优化目录结构

This commit is contained in:
2026-05-25 20:37:36 +08:00
parent bbe7e71274
commit 40fd7f7e08
101 changed files with 108 additions and 110 deletions

View File

@@ -0,0 +1,321 @@
import * as Logger from "../utils/logger.js";
export class Signaling extends EventTarget {
constructor(interval = 1000) {
super();
this.running = false;
this.interval = interval;
this.sleep = msec => new Promise(resolve => setTimeout(resolve, msec));
}
headers() {
if (this.sessionId !== undefined) {
return { 'Content-Type': 'application/json', 'Session-Id': this.sessionId };
}
else {
return { 'Content-Type': 'application/json' };
}
}
url(method, parameter = '') {
let ret = location.origin + '/signaling';
if (method)
ret += '/' + method;
if (parameter)
ret += '?' + parameter;
return ret;
}
async start() {
if (this.running) {
return;
}
this.running = true;
while (!this.sessionId) {
const createResponse = await fetch(this.url(''), { method: 'PUT', headers: this.headers() });
const session = await createResponse.json();
this.sessionId = session.sessionId;
if (!this.sessionId) {
await this.sleep(this.interval);
}
}
this.loopGetAll();
}
async loopGetAll() {
let lastTimeRequest = Date.now() - 30000;
while (this.running) {
const res = await this.getAll(lastTimeRequest);
const data = await res.json();
lastTimeRequest = data.datetime ? data.datetime : Date.now();
const messages = data.messages;
for (const msg of messages) {
switch (msg.type) {
case "connect":
break;
case "disconnect":
this.dispatchEvent(new CustomEvent('disconnect', { detail: msg }));
break;
case "offer":
this.dispatchEvent(new CustomEvent('offer', { detail: msg }));
break;
case "answer":
this.dispatchEvent(new CustomEvent('answer', { detail: msg }));
break;
case "candidate":
this.dispatchEvent(new CustomEvent('candidate', { detail: msg }));
break;
case "on-message":
{
let parsed = msg.data;
if (typeof msg.data === 'string') {
try { parsed = JSON.parse(msg.data); } catch(e) {
Logger.error(`Signaling: on-message, error: ${e}`);
}
}
this.dispatchEvent(new CustomEvent('on-message', { detail: parsed }));
}
break;
default:
break;
}
}
await this.sleep(this.interval);
}
}
async stop() {
this.running = false;
await fetch(this.url(''), { method: 'DELETE', headers: this.headers() });
this.sessionId = null;
}
async createConnection(connectionId) {
const data = { 'connectionId': connectionId };
const res = await fetch(this.url('connection'), { method: 'PUT', headers: this.headers(), body: JSON.stringify(data) });
const json = await res.json();
Logger.log(`Signaling: HTTP create connection, connectionId: ${json.connectionId}, polite:${json.polite}`);
this.dispatchEvent(new CustomEvent('connect', { detail: json }));
return json;
}
async deleteConnection(connectionId) {
const data = { 'connectionId': connectionId };
const res = await fetch(this.url('connection'), { method: 'DELETE', headers: this.headers(), body: JSON.stringify(data) });
const json = await res.json();
this.dispatchEvent(new CustomEvent('disconnect', { detail: json }));
return json;
}
async sendOffer(connectionId, sdp) {
const data = { 'sdp': sdp, 'connectionId': connectionId };
Logger.log('sendOffer:' + data);
await fetch(this.url('offer'), { method: 'POST', headers: this.headers(), body: JSON.stringify(data) });
}
async sendAnswer(connectionId, sdp) {
const data = { 'sdp': sdp, 'connectionId': connectionId };
Logger.log('sendAnswer:' + data);
await fetch(this.url('answer'), { method: 'POST', headers: this.headers(), body: JSON.stringify(data) });
}
async sendCandidate(connectionId, candidate, sdpMid, sdpMLineIndex) {
const data = {
'candidate': candidate,
'sdpMLineIndex': sdpMLineIndex,
'sdpMid': sdpMid,
'connectionId': connectionId
};
Logger.log('sendCandidate:' + data);
await fetch(this.url('candidate'), { method: 'POST', headers: this.headers(), body: JSON.stringify(data) });
}
// 在 Signaling 类中添加
async sendMessage(connectionId, message) {
const data = {
'message': message,
'connectionId': connectionId
};
await fetch(this.url('on-message'), { method: 'POST', headers: this.headers(), body: JSON.stringify(data) });
}
async getAll(fromTime = 0) {
return await fetch(this.url(``, `fromtime=${fromTime}`), { method: 'GET', headers: this.headers() });
}
}
export class WebSocketSignaling extends EventTarget {
constructor(interval = 1000) {
super();
this.interval = interval;
this.sleep = msec => new Promise(resolve => setTimeout(resolve, msec));
let websocketUrl;
if (location.protocol === "https:") {
websocketUrl = "wss://" + location.host;
} else {
websocketUrl = "ws://" + location.host;
}
this.websocket = new WebSocket(websocketUrl);
this.connectionId = null;
this.websocket.onopen = () => {
this.isWsOpen = true;
};
this.websocket.onclose = () => {
this.isWsOpen = false;
};
this.websocket.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (!msg || !this) {
return;
}
Logger.log(msg);
switch (msg.type) {
case "connect":
this.dispatchEvent(new CustomEvent('connect', { detail: msg }));
break;
case "disconnect":
this.dispatchEvent(new CustomEvent('disconnect', { detail: msg }));
break;
case "offer":
this.dispatchEvent(new CustomEvent('offer', { detail: { connectionId: msg.from, sdp: msg.data.sdp, polite: msg.data.polite, participantId: msg.participantId } }));
break;
case "answer":
this.dispatchEvent(new CustomEvent('answer', { detail: { connectionId: msg.from, sdp: msg.data.sdp, participantId: msg.participantId } }));
break;
case "candidate":
this.dispatchEvent(new CustomEvent('candidate', { detail: { connectionId: msg.from, candidate: msg.data.candidate, sdpMLineIndex: msg.data.sdpMLineIndex, sdpMid: msg.data.sdpMid, participantId: msg.participantId } }));
break;
case "on-message":
{
let parsed = msg.data;
if (typeof msg.data === 'string') {
try { parsed = JSON.parse(msg.data); } catch(e) {
Logger.error(`Signaling: on-message, error: ${e}`);
}
}
if (msg.participantId) {
parsed.participantId = msg.participantId;
}
this.dispatchEvent(new CustomEvent('on-message', { detail: parsed }));
}
break;
case "participant-left":
this.dispatchEvent(new CustomEvent('participant-left', { detail: msg }));
break;
case "participant-joined":
this.dispatchEvent(new CustomEvent('participant-joined', { detail: msg }));
break;
case "broadcast":
this.dispatchEvent(new CustomEvent('on-message', { detail: msg.message }));
break;
case "invite-call":
this.dispatchEvent(new CustomEvent('invite-call', { detail: msg.data }));
break;
case "invite-accepted":
this.dispatchEvent(new CustomEvent('invite-accepted', { detail: msg.data }));
break;
case "invite-rejected":
this.dispatchEvent(new CustomEvent('invite-rejected', { detail: msg.data }));
break;
case "invite-failed":
this.dispatchEvent(new CustomEvent('invite-failed', { detail: msg.data }));
break;
default:
break;
}
};
}
async start() {
while (!this.isWsOpen) {
await this.sleep(100);
}
}
async stop() {
this.websocket.close();
while (this.isWsOpen) {
await this.sleep(100);
}
}
createConnection(connectionId) {
const sendJson = JSON.stringify({ type: "connect", connectionId: connectionId });
Logger.log(sendJson);
this.websocket.send(sendJson);
}
deleteConnection(connectionId) {
const sendJson = JSON.stringify({ type: "disconnect", connectionId: connectionId });
Logger.log(sendJson);
this.websocket.send(sendJson);
}
sendOffer(connectionId, sdp, participantId) {
const data = { 'sdp': sdp, 'connectionId': connectionId };
const sendJson = JSON.stringify({ type: "offer", from: connectionId, data: data, participantId: participantId || '' });
Logger.log(sendJson);
this.websocket.send(sendJson);
}
sendAnswer(connectionId, sdp, participantId) {
const data = { 'sdp': sdp, 'connectionId': connectionId };
const sendJson = JSON.stringify({ type: "answer", from: connectionId, data: data, participantId: participantId || '' });
Logger.log(sendJson);
this.websocket.send(sendJson);
}
sendCandidate(connectionId, candidate, sdpMLineIndex, sdpMid, participantId) {
const data = {
'candidate': candidate,
'sdpMLineIndex': sdpMLineIndex,
'sdpMid': sdpMid,
'connectionId': connectionId
};
const sendJson = JSON.stringify({ type: "candidate", from: connectionId, data: data, participantId: participantId || '' });
Logger.log(sendJson);
this.websocket.send(sendJson);
}
// 在 WebSocketSignaling 类中添加
sendMessage(connectionId, message) {
const data = {
'message': message,
'senderId': message.senderId,
'connectionId': connectionId
};
const sendJson = JSON.stringify({ type: "on-message", data: data });
Logger.log(sendJson);
this.websocket.send(sendJson);
}
sendInviteCall(payload) {
const sendJson = JSON.stringify({ type: 'invite-call', data: payload });
Logger.log(sendJson);
this.websocket.send(sendJson);
}
sendInviteAccepted(payload) {
const sendJson = JSON.stringify({ type: 'invite-accepted', data: payload });
Logger.log(sendJson);
this.websocket.send(sendJson);
}
sendInviteRejected(payload) {
const sendJson = JSON.stringify({ type: 'invite-rejected', data: payload });
Logger.log(sendJson);
this.websocket.send(sendJson);
}
}