2026-05-24 01:46:57 +08:00
|
|
|
import { Signaling, WebSocketSignaling } from "../../module/signaling.js";
|
2026-05-24 14:16:28 +08:00
|
|
|
import { createLogger } from './logger.js';
|
|
|
|
|
|
|
|
|
|
const logger = createLogger('signaling');
|
2026-05-24 01:46:57 +08:00
|
|
|
|
|
|
|
|
const INVITE_EVENT_NAMES = Object.freeze([
|
|
|
|
|
'invite-call',
|
|
|
|
|
'invite-accepted',
|
|
|
|
|
'invite-rejected',
|
|
|
|
|
'invite-failed'
|
|
|
|
|
]);
|
|
|
|
|
|
2026-05-24 01:54:47 +08:00
|
|
|
const DEFAULT_SOCKET_USER_NAME = '?';
|
2026-05-24 01:46:57 +08:00
|
|
|
const DEFAULT_SOCKET_USER_AVATAR = '/images/p1.png';
|
|
|
|
|
|
|
|
|
|
export function createSignalingInstance(useWebSocket) {
|
|
|
|
|
return useWebSocket ? new WebSocketSignaling() : new Signaling();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function ensureSignalingStarted(existingSignaling, useWebSocket) {
|
|
|
|
|
if (existingSignaling) {
|
|
|
|
|
return {
|
|
|
|
|
signaling: existingSignaling,
|
|
|
|
|
reused: true
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const signaling = createSignalingInstance(useWebSocket);
|
|
|
|
|
await signaling.start();
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
signaling,
|
|
|
|
|
reused: false
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function bindInviteSocketEvents(signaling, eventHandlers, boundSignaling = null) {
|
|
|
|
|
if (!signaling || signaling === boundSignaling || typeof signaling.addEventListener !== 'function') {
|
|
|
|
|
return boundSignaling;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
INVITE_EVENT_NAMES.forEach((eventName) => {
|
|
|
|
|
signaling.addEventListener(eventName, (event) => {
|
|
|
|
|
const handler = eventHandlers[eventName];
|
|
|
|
|
if (typeof handler === 'function') {
|
|
|
|
|
handler(event.detail);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return signaling;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getActiveSignalingInstance(preconnectedSignaling, renderstreaming) {
|
|
|
|
|
if (preconnectedSignaling) {
|
|
|
|
|
return preconnectedSignaling;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (renderstreaming && renderstreaming._signaling) {
|
|
|
|
|
return renderstreaming._signaling;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function sendInviteSignal(signaling, methodName, payload) {
|
|
|
|
|
if (!signaling || typeof signaling[methodName] !== 'function') {
|
|
|
|
|
throw new Error('Invite signaling is not ready');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
signaling[methodName](payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function readStoredSocketUserInfo() {
|
|
|
|
|
try {
|
|
|
|
|
return JSON.parse(localStorage.getItem('userSettings') || '{}');
|
|
|
|
|
} catch (error) {
|
2026-05-24 14:16:28 +08:00
|
|
|
logger.error('Error parsing user settings:', error);
|
2026-05-24 01:46:57 +08:00
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function buildSocketUserInfoPayload(userInfo, localUser) {
|
|
|
|
|
const settings = userInfo || readStoredSocketUserInfo();
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
id: settings.id || settings.userId || localUser.id || '',
|
|
|
|
|
name: settings.name || localUser.name || DEFAULT_SOCKET_USER_NAME,
|
|
|
|
|
avatar: settings.avatar || localUser.avatar || DEFAULT_SOCKET_USER_AVATAR
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function sendSocketUserInfo(signaling, payload) {
|
|
|
|
|
if (!signaling || typeof signaling.sendMessage !== 'function') {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
signaling.sendMessage('', {
|
|
|
|
|
type: 'user-info',
|
|
|
|
|
data: payload
|
|
|
|
|
});
|
|
|
|
|
}
|