Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
@@ -8,23 +8,55 @@ export type SignalMessage =
|
|||||||
| { type: 'answer'; viewerId: string; sdp: RTCSessionDescriptionInit }
|
| { type: 'answer'; viewerId: string; sdp: RTCSessionDescriptionInit }
|
||||||
| { type: 'ice'; viewerId: string; from: 'broadcaster' | 'viewer'; candidate: RTCIceCandidateInit };
|
| { type: 'ice'; viewerId: string; from: 'broadcaster' | 'viewer'; candidate: RTCIceCandidateInit };
|
||||||
|
|
||||||
|
const readyChannels = new WeakMap<RealtimeChannel, Promise<void>>();
|
||||||
|
|
||||||
export function joinSignalingChannel(
|
export function joinSignalingChannel(
|
||||||
code: string,
|
code: string,
|
||||||
onMessage: (msg: SignalMessage) => void,
|
onMessage: (msg: SignalMessage) => void,
|
||||||
): RealtimeChannel {
|
): RealtimeChannel {
|
||||||
|
let resolveReady!: () => void;
|
||||||
|
let rejectReady!: (error: Error) => void;
|
||||||
|
const ready = new Promise<void>((resolve, reject) => {
|
||||||
|
resolveReady = resolve;
|
||||||
|
rejectReady = reject;
|
||||||
|
});
|
||||||
|
|
||||||
const channel = supabase.channel(`share:${code}`, {
|
const channel = supabase.channel(`share:${code}`, {
|
||||||
config: { broadcast: { self: false, ack: false } },
|
config: { broadcast: { self: false, ack: false } },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
readyChannels.set(channel, ready);
|
||||||
|
|
||||||
channel
|
channel
|
||||||
.on('broadcast', { event: 'signal' }, ({ payload }) => onMessage(payload as SignalMessage))
|
.on('broadcast', { event: 'signal' }, ({ payload }) => onMessage(payload as SignalMessage))
|
||||||
.subscribe();
|
.subscribe((status, err) => {
|
||||||
|
if (status === 'SUBSCRIBED') resolveReady();
|
||||||
|
if (status === 'CHANNEL_ERROR' || status === 'TIMED_OUT' || status === 'CLOSED') {
|
||||||
|
rejectReady(err instanceof Error ? err : new Error(`Canal de sinalização: ${status}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sendSignal(channel: RealtimeChannel, msg: SignalMessage) {
|
export async function waitForSignalingReady(channel: RealtimeChannel, timeoutMs = 5000) {
|
||||||
return channel.send({ type: 'broadcast', event: 'signal', payload: msg });
|
const ready = readyChannels.get(channel);
|
||||||
|
if (!ready) return;
|
||||||
|
await Promise.race([
|
||||||
|
ready,
|
||||||
|
new Promise<void>((_, reject) => {
|
||||||
|
window.setTimeout(() => reject(new Error('Tempo esgotado ao conectar sinalização')), timeoutMs);
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function sendSignal(channel: RealtimeChannel, msg: SignalMessage) {
|
||||||
|
await waitForSignalingReady(channel);
|
||||||
|
const response = await channel.send({ type: 'broadcast', event: 'signal', payload: msg });
|
||||||
|
if (response !== 'ok') {
|
||||||
|
const restResponse = await channel.httpSend('signal', msg);
|
||||||
|
if (!restResponse.success) throw new Error(restResponse.error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateRoomCode(): string {
|
export function generateRoomCode(): string {
|
||||||
|
|||||||
Reference in New Issue
Block a user