关于录屏相关的消息格式需要封一层,放在on-message下,利用on-message传递
This commit is contained in:
@@ -85,6 +85,8 @@ type RecordingBroadcastPayload = {
|
||||
mediaMode?: string;
|
||||
};
|
||||
|
||||
type RecordingClientMessageType = 'recording-offer' | 'recording-candidate' | 'recording-status';
|
||||
|
||||
interface StoredRoom {
|
||||
roomId: string;
|
||||
connectionId: string;
|
||||
@@ -347,6 +349,63 @@ function sendToEntireGroup(connectionId: string, message: any): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
function toTypedDataMessage(message: any): any {
|
||||
if (!message || typeof message !== 'object' || typeof message.type !== 'string') {
|
||||
return message;
|
||||
}
|
||||
|
||||
const data: any = {};
|
||||
Object.keys(message).forEach((key) => {
|
||||
if (key !== 'type') {
|
||||
data[key] = message[key];
|
||||
}
|
||||
});
|
||||
return {
|
||||
type: message.type,
|
||||
data
|
||||
};
|
||||
}
|
||||
|
||||
function toOnMessageEnvelope(connectionId: string, message: any, participantId?: string): any {
|
||||
const envelope: any = {
|
||||
from: connectionId,
|
||||
to: "",
|
||||
type: "on-message",
|
||||
data: JSON.stringify(toTypedDataMessage(message))
|
||||
};
|
||||
if (participantId) {
|
||||
envelope.participantId = participantId;
|
||||
}
|
||||
return envelope;
|
||||
}
|
||||
|
||||
function safeSendOnMessage(ws: WebSocket, connectionId: string, message: any, participantId?: string): boolean {
|
||||
return safeSend(ws, toOnMessageEnvelope(connectionId, message, participantId));
|
||||
}
|
||||
|
||||
function sendOnMessageToEntireGroup(connectionId: string, message: any): boolean {
|
||||
return sendToEntireGroup(connectionId, toOnMessageEnvelope(connectionId, message));
|
||||
}
|
||||
|
||||
function isRecordingClientMessage(message: any): boolean {
|
||||
return message
|
||||
&& typeof message === 'object'
|
||||
&& (message.type === 'recording-offer'
|
||||
|| message.type === 'recording-candidate'
|
||||
|| message.type === 'recording-status');
|
||||
}
|
||||
|
||||
function unwrapRecordingClientPayload(message: any): any {
|
||||
const payload = message.data && typeof message.data === 'object' ? message.data : message;
|
||||
if (!payload.connectionId && message.connectionId) {
|
||||
payload.connectionId = message.connectionId;
|
||||
}
|
||||
if (!payload.participantId && message.participantId) {
|
||||
payload.participantId = message.participantId;
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
|
||||
function getActiveRecordingSessions(connectionId: string): RecordingSession[] {
|
||||
return listRecordingSessions(connectionId).filter((session) => session.status === 'recording');
|
||||
}
|
||||
@@ -802,7 +861,7 @@ function toRecordingBroadcastPayload(type: RecordingBroadcastPayload['type'], se
|
||||
}
|
||||
|
||||
function broadcastRecordingStarted(session: RecordingSession): boolean {
|
||||
return sendToEntireGroup(
|
||||
return sendOnMessageToEntireGroup(
|
||||
session.connectionId,
|
||||
toRecordingBroadcastPayload('recording-started', session)
|
||||
);
|
||||
@@ -811,11 +870,11 @@ function broadcastRecordingStarted(session: RecordingSession): boolean {
|
||||
function broadcastRecordingPeerRequest(session: RecordingSession): boolean {
|
||||
const payload = toRecordingBroadcastPayload('recording-peer-request', session);
|
||||
payload.mediaMode = 'webrtc-sendonly';
|
||||
return sendToEntireGroup(session.connectionId, payload);
|
||||
return sendOnMessageToEntireGroup(session.connectionId, payload);
|
||||
}
|
||||
|
||||
function broadcastRecordingStopped(session: RecordingSession): boolean {
|
||||
return sendToEntireGroup(
|
||||
return sendOnMessageToEntireGroup(
|
||||
session.connectionId,
|
||||
toRecordingBroadcastPayload('recording-stopped', session)
|
||||
);
|
||||
@@ -824,8 +883,8 @@ function broadcastRecordingStopped(session: RecordingSession): boolean {
|
||||
function sendActiveRecordingRequests(ws: WebSocket, connectionId: string): void {
|
||||
const activeSessions = getActiveRecordingSessions(connectionId);
|
||||
activeSessions.forEach((session) => {
|
||||
safeSend(ws, toRecordingBroadcastPayload('recording-started', session));
|
||||
safeSend(ws, {
|
||||
safeSendOnMessage(ws, connectionId, toRecordingBroadcastPayload('recording-started', session));
|
||||
safeSendOnMessage(ws, connectionId, {
|
||||
...toRecordingBroadcastPayload('recording-peer-request', session),
|
||||
mediaMode: 'webrtc-sendonly'
|
||||
});
|
||||
@@ -837,7 +896,7 @@ async function onRecordingOffer(ws: WebSocket, message: any): Promise<void> {
|
||||
const connectionId = typeof message.connectionId === 'string' ? message.connectionId : '';
|
||||
const sdp = typeof message.sdp === 'string' ? message.sdp : '';
|
||||
if (!recordingId || !connectionId || !sdp) {
|
||||
safeSend(ws, { type: 'recording-status', recordingId, connectionId, status: 'invalid-offer' });
|
||||
safeSendOnMessage(ws, connectionId, { type: 'recording-status', recordingId, connectionId, status: 'invalid-offer' });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -849,7 +908,7 @@ async function onRecordingOffer(ws: WebSocket, message: any): Promise<void> {
|
||||
});
|
||||
|
||||
if (!offer) {
|
||||
safeSend(ws, {
|
||||
safeSendOnMessage(ws, connectionId, {
|
||||
type: 'recording-status',
|
||||
recordingId,
|
||||
connectionId,
|
||||
@@ -870,7 +929,7 @@ async function onRecordingOffer(ws: WebSocket, message: any): Promise<void> {
|
||||
role,
|
||||
onLocalCandidate: (candidate) => {
|
||||
const json = typeof candidate.toJSON === 'function' ? candidate.toJSON() : candidate;
|
||||
safeSend(ws, {
|
||||
safeSendOnMessage(ws, connectionId, {
|
||||
type: 'recording-candidate',
|
||||
recordingId,
|
||||
connectionId,
|
||||
@@ -882,7 +941,7 @@ async function onRecordingOffer(ws: WebSocket, message: any): Promise<void> {
|
||||
}
|
||||
});
|
||||
|
||||
safeSend(ws, {
|
||||
safeSendOnMessage(ws, connectionId, {
|
||||
type: 'recording-answer',
|
||||
recordingId,
|
||||
connectionId,
|
||||
@@ -891,7 +950,7 @@ async function onRecordingOffer(ws: WebSocket, message: any): Promise<void> {
|
||||
});
|
||||
} catch (error) {
|
||||
log(LogLevel.error, 'Failed to accept recording offer:', error);
|
||||
safeSend(ws, {
|
||||
safeSendOnMessage(ws, connectionId, {
|
||||
type: 'recording-status',
|
||||
recordingId,
|
||||
connectionId,
|
||||
@@ -901,7 +960,7 @@ async function onRecordingOffer(ws: WebSocket, message: any): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
safeSend(ws, {
|
||||
safeSendOnMessage(ws, connectionId, {
|
||||
type: 'recording-status',
|
||||
recordingId,
|
||||
connectionId,
|
||||
@@ -928,7 +987,7 @@ async function onRecordingCandidate(ws: WebSocket, message: any): Promise<void>
|
||||
});
|
||||
|
||||
if (!candidate) {
|
||||
safeSend(ws, { type: 'recording-status', recordingId, connectionId, status: 'candidate-rejected' });
|
||||
safeSendOnMessage(ws, connectionId, { type: 'recording-status', recordingId, connectionId, status: 'candidate-rejected' });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -942,7 +1001,7 @@ async function onRecordingCandidate(ws: WebSocket, message: any): Promise<void>
|
||||
});
|
||||
} catch (error) {
|
||||
log(LogLevel.warn, 'Failed to add recording ICE candidate:', error);
|
||||
safeSend(ws, { type: 'recording-status', recordingId, connectionId, status: 'candidate-rejected' });
|
||||
safeSendOnMessage(ws, connectionId, { type: 'recording-status', recordingId, connectionId, status: 'candidate-rejected' });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1077,6 +1136,23 @@ function onMessage(ws: WebSocket, message: any): void {
|
||||
}
|
||||
chatMessage.participantId = senderParticipantId;
|
||||
chatMessage.connectionId = connectionId;
|
||||
if (isRecordingClientMessage(chatMessage)) {
|
||||
const recordingPayload = unwrapRecordingClientPayload(chatMessage);
|
||||
switch (chatMessage.type as RecordingClientMessageType) {
|
||||
case 'recording-offer':
|
||||
onRecordingOffer(ws, recordingPayload);
|
||||
break;
|
||||
case 'recording-candidate':
|
||||
onRecordingCandidate(ws, recordingPayload);
|
||||
break;
|
||||
case 'recording-status':
|
||||
log(LogLevel.log, 'Received recording status:', recordingPayload);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (connectionGroup.has(connectionId)) {
|
||||
const group = connectionGroup.get(connectionId);
|
||||
if (group.host === ws) {
|
||||
|
||||
@@ -17,9 +17,6 @@ const VALID_MESSAGE_TYPES = new Set([
|
||||
"host-userInfo",
|
||||
"invite-call",
|
||||
"on-message",
|
||||
"recording-offer",
|
||||
"recording-candidate",
|
||||
"recording-status",
|
||||
]);
|
||||
|
||||
function sendJson(ws: WebSocket, payload: unknown): void {
|
||||
@@ -207,16 +204,6 @@ export default class WSSignaling {
|
||||
if (msg.from) msg.data.connectionId = msg.from;
|
||||
handler.onMessage(ws, msg.data);
|
||||
break;
|
||||
case 'recording-offer':
|
||||
if (!hasData(msg)) return;
|
||||
handler.onRecordingOffer(ws, msg.data);
|
||||
break;
|
||||
case 'recording-candidate':
|
||||
if (!hasData(msg)) return;
|
||||
handler.onRecordingCandidate(ws, msg.data);
|
||||
break;
|
||||
case 'recording-status':
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user