Skip to content

Commit d4d1481

Browse files
authored
Merge pull request #279 from boostcampwm-2022/Refactor/#275-C
Refactor/#275-C: RTC ๋ชจ๋“ˆ ๋ฉ”์†Œ๋“œ ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ
2 parents ce6b7d6 + 0dbd630 commit d4d1481

File tree

1 file changed

+85
-97
lines changed

1 file changed

+85
-97
lines changed
Lines changed: 85 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import { parseClassName } from 'react-toastify/dist/utils';
12
import { Socket } from 'socket.io-client';
23
import SOCKET_MESSAGE from 'src/constants/socket-message';
4+
const MSG = SOCKET_MESSAGE.WORKSPACE;
5+
6+
type SocketId = string;
37

48
type onMediaConnectedCb = (socketId: string, remoteStream: MediaStream) => void;
59
type onMediaDisconnectedCb = (socketId: string) => void;
@@ -28,6 +32,16 @@ class RTC {
2832
this.onMediaDisconnectedCallback = () => {}; // eslint-disable-line @typescript-eslint/no-empty-function
2933
}
3034

35+
connect() {
36+
this.socket.on(MSG.RECEIVE_HELLO, this.setDescriptionAndEmitOffer.bind(this));
37+
this.socket.on(MSG.RECEIVE_OFFER, this.setDescriptionAndEmitAnswer.bind(this));
38+
this.socket.on(MSG.RECEIVE_ANSWER, this.setDescriptionForAnswer.bind(this));
39+
this.socket.on(MSG.RECEIVE_ICE, this.addIce.bind(this));
40+
this.socket.on(MSG.RECEIVE_BYE, this.disconnectPeer.bind(this));
41+
42+
this.socket.emit(MSG.SEND_HELLO);
43+
}
44+
3145
onMediaConnected(callback: onMediaConnectedCb) {
3246
this.onMediaConnectedCallback = callback;
3347
}
@@ -36,41 +50,87 @@ class RTC {
3650
this.onMediaDisconnectedCallback = callback;
3751
}
3852

39-
#createPeerConnection(remoteSocketId: string) {
53+
private async setDescriptionAndEmitOffer(remoteSocketId: SocketId) {
54+
const pc = this.createPeerConnection(remoteSocketId);
55+
this.connections.set(remoteSocketId, pc);
56+
57+
const offer = await pc.createOffer();
58+
await pc.setLocalDescription(offer);
59+
60+
this.socket.emit(MSG.SEND_OFFER, offer, remoteSocketId);
61+
}
62+
63+
private async setDescriptionAndEmitAnswer(offer: RTCSessionDescriptionInit, remoteSocketId: SocketId) {
64+
const pc = this.createPeerConnection(remoteSocketId);
65+
await pc.setRemoteDescription(offer);
66+
this.connections.set(remoteSocketId, pc);
67+
68+
const answer = await pc.createAnswer();
69+
await pc.setLocalDescription(answer);
70+
71+
this.socket.emit(MSG.SEND_ANSWER, answer, remoteSocketId);
72+
}
73+
74+
private async setDescriptionForAnswer(answer: RTCSessionDescriptionInit, remoteSocketId: SocketId) {
75+
const pc = this.connections.get(remoteSocketId);
76+
if (!pc) {
77+
throw new Error('No RTCPeerConnection on answer received.');
78+
}
79+
80+
await pc.setRemoteDescription(answer);
81+
}
82+
83+
private async addIce(ice: RTCIceCandidate, remoteSocketId: SocketId) {
84+
const pc = this.connections.get(remoteSocketId);
85+
if (!pc) {
86+
throw new Error('No RTCPeerConnection on ice candindate received.');
87+
}
88+
89+
await pc.addIceCandidate(ice);
90+
}
91+
92+
private async disconnectPeer(remoteSocketId: SocketId) {
93+
this.connections.delete(remoteSocketId);
94+
this.streams.delete(remoteSocketId);
95+
96+
this.onMediaDisconnectedCallback(remoteSocketId);
97+
}
98+
99+
private createPeerConnection(remoteSocketId: string) {
40100
// initialize
41101
const pcOptions = {
42102
iceServers: [{ urls: this.iceServerUrls }],
43103
};
44104
const pc = new RTCPeerConnection(pcOptions);
45105

46-
// add event listeners
47-
pc.addEventListener('icecandidate', (iceEvent) => {
48-
this.socket.emit(
49-
SOCKET_MESSAGE.WORKSPACE.SEND_ICE,
50-
iceEvent.candidate,
51-
remoteSocketId,
52-
);
53-
});
54-
pc.addEventListener('track', async (event) => {
55-
if (this.streams.has(remoteSocketId)) {
56-
return;
57-
}
58-
59-
const [remoteStream] = event.streams;
60-
61-
this.streams.set(remoteSocketId, remoteStream);
62-
this.onMediaConnectedCallback(remoteSocketId, remoteStream);
63-
});
64-
65-
// add tracks
66-
this.userMediaStream
67-
.getTracks()
68-
.forEach((track) => pc.addTrack(track, this.userMediaStream));
106+
pc.addEventListener('icecandidate', event => this.emitIce(event, remoteSocketId));
107+
pc.addEventListener('track', event => this.addRemoteStream(event, remoteSocketId));
108+
this.addTracksToLocalConnection(pc);
69109

70110
return pc;
71111
}
72112

73-
async #setVideoBitrate(pc: RTCPeerConnection, bitrate: number) {
113+
private emitIce(event: RTCPeerConnectionIceEvent, remoteSocketId: string) {
114+
this.socket.emit(MSG.SEND_ICE, event.candidate, remoteSocketId);
115+
}
116+
117+
private addRemoteStream(event: RTCTrackEvent, remoteSocketId: string) {
118+
if (this.streams.has(remoteSocketId)) {
119+
return;
120+
}
121+
122+
const [remoteStream] = event.streams;
123+
124+
this.streams.set(remoteSocketId, remoteStream);
125+
this.onMediaConnectedCallback(remoteSocketId, remoteStream);
126+
}
127+
128+
private addTracksToLocalConnection(pc: RTCPeerConnection) {
129+
this.userMediaStream.getTracks().forEach(track => pc.addTrack(track, this.userMediaStream));
130+
}
131+
132+
// unused; may be used in the future
133+
private async setVideoBitrate(pc: RTCPeerConnection, bitrate: number) {
74134
// fetch video sender
75135
const [videoSender] = pc
76136
.getSenders()
@@ -81,78 +141,6 @@ class RTC {
81141
params.encodings[0].maxBitrate = bitrate;
82142
await videoSender.setParameters(params);
83143
}
84-
85-
connect() {
86-
this.socket.on(
87-
SOCKET_MESSAGE.WORKSPACE.RECEIVE_HELLO,
88-
async (remoteSocketId) => {
89-
const pc = this.#createPeerConnection(remoteSocketId);
90-
this.connections.set(remoteSocketId, pc);
91-
92-
const offer = await pc.createOffer();
93-
await pc.setLocalDescription(offer);
94-
95-
this.socket.emit(
96-
SOCKET_MESSAGE.WORKSPACE.SEND_OFFER,
97-
pc.localDescription,
98-
remoteSocketId,
99-
);
100-
},
101-
);
102-
103-
this.socket.on(
104-
SOCKET_MESSAGE.WORKSPACE.RECEIVE_OFFER,
105-
async (offer, remoteSocketId) => {
106-
const pc = this.#createPeerConnection(remoteSocketId);
107-
this.connections.set(remoteSocketId, pc);
108-
109-
await pc.setRemoteDescription(offer);
110-
111-
const answer = await pc.createAnswer();
112-
await pc.setLocalDescription(answer);
113-
114-
this.socket.emit(
115-
SOCKET_MESSAGE.WORKSPACE.SEND_ANSWER,
116-
answer,
117-
remoteSocketId,
118-
);
119-
},
120-
);
121-
122-
this.socket.on(
123-
SOCKET_MESSAGE.WORKSPACE.RECEIVE_ANSWER,
124-
async (answer, remoteSocketId) => {
125-
const pc = this.connections.get(remoteSocketId);
126-
if (!pc) {
127-
throw new Error('No RTCPeerConnection on answer received.');
128-
}
129-
130-
await pc.setRemoteDescription(answer);
131-
},
132-
);
133-
134-
this.socket.on(
135-
SOCKET_MESSAGE.WORKSPACE.RECEIVE_ICE,
136-
(ice, remoteSocketId) => {
137-
const pc = this.connections.get(remoteSocketId);
138-
139-
if (!pc) {
140-
throw new Error('No RTCPeerConnection on ice candindate received.');
141-
}
142-
143-
pc.addIceCandidate(ice);
144-
},
145-
);
146-
147-
this.socket.on(SOCKET_MESSAGE.WORKSPACE.RECEIVE_BYE, (remoteSocketId) => {
148-
this.connections.delete(remoteSocketId);
149-
this.streams.delete(remoteSocketId);
150-
151-
this.onMediaDisconnectedCallback(remoteSocketId);
152-
});
153-
154-
this.socket.emit(SOCKET_MESSAGE.WORKSPACE.SEND_HELLO);
155-
}
156144
}
157145

158146
export default RTC;

0 commit comments

Comments
ย (0)