-
Notifications
You must be signed in to change notification settings - Fork 3
/
Negotiation.ts
115 lines (109 loc) · 2.85 KB
/
Negotiation.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
export const onIceCandidateHandler = (
connectionId: string,
socket: WebSocket,
channel: RTCDataChannel
) => ({ candidate }: RTCPeerConnectionIceEvent) => {
const message = {
action: "negotiate",
connectionId: connectionId,
candidate,
};
sendMessage(socket, channel, message);
};
export const onNegotiationNeededHandler = (
connectionMeta: ConnectionMeta,
peerConnectionId: string,
socket: WebSocket
) => async () => {
try {
if (connectionMeta.type === ConnectionType.MASTER) {
connectionMeta.makingOffer = true;
await connectionMeta.connection.setLocalDescription(
await connectionMeta.connection.createOffer()
);
sendOffer(
peerConnectionId,
connectionMeta.connection.localDescription,
socket,
connectionMeta.channels.negotiationChannel
);
}
} catch (err) {
console.error(err);
} finally {
connectionMeta.makingOffer = false;
}
};
export const onMessageHandlerNegotiation = (
connectionMeta: ConnectionMeta,
peerConnectionId: string,
socket: WebSocket
) => {
return async (e: MessageEvent) => {
try {
const { description, candidate } = JSON.parse(e.data) as Message;
if (description) {
if (description.type === "offer") {
await connectionMeta.connection.setRemoteDescription(description);
await connectionMeta.connection.setLocalDescription(
await connectionMeta.connection.createAnswer()
);
sendOffer(
peerConnectionId,
connectionMeta.connection.localDescription,
socket,
connectionMeta.channels.negotiationChannel
);
} else {
await connectionMeta.connection.setRemoteDescription(description);
}
} else if (candidate) {
addIceCandidate(connectionMeta.connection, candidate);
}
} catch (err) {
if (!connectionMeta.ignoreOffer) {
console.error(err);
}
}
};
};
const addIceCandidate = async (
connection: RTCPeerConnection,
candidate: RTCIceCandidateInit
) => {
try {
if (connection.remoteDescription) {
await connection.addIceCandidate(candidate);
} else {
setTimeout(() => {
addIceCandidate(connection, candidate);
}, 1000);
}
} catch (e) {
console.error(e, candidate);
}
};
const sendMessage = (
socket: WebSocket,
channel: RTCDataChannel,
message: Object
): void => {
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify(message));
} else {
channel.send(JSON.stringify(message));
}
};
const sendOffer = (
peerConnectionId: string,
description: RTCSessionDescription,
socket: WebSocket,
channel: RTCDataChannel
) => {
const message = {
action: "negotiate",
connectionId: peerConnectionId,
description,
};
sendMessage(socket, channel, message);
};