11import { WORKSPACE_EVENT } from '@wabinar/constants/socket-message' ;
22import { Socket } from 'socket.io-client' ;
33
4- type SocketId = string ;
5-
64type onMediaConnectedCb = ( socketId : string , remoteStream : MediaStream ) => void ;
75type onMediaDisconnectedCb = ( socketId : string ) => void ;
86
@@ -30,25 +28,6 @@ class RTC {
3028 this . onMediaDisconnectedCallback = ( ) => { } ; // eslint-disable-line @typescript-eslint/no-empty-function
3129 }
3230
33- connect ( ) {
34- this . socket . on (
35- WORKSPACE_EVENT . RECEIVE_HELLO ,
36- this . setDescriptionAndEmitOffer . bind ( this ) ,
37- ) ;
38- this . socket . on (
39- WORKSPACE_EVENT . RECEIVE_OFFER ,
40- this . setDescriptionAndEmitAnswer . bind ( this ) ,
41- ) ;
42- this . socket . on (
43- WORKSPACE_EVENT . RECEIVE_ANSWER ,
44- this . setDescriptionForAnswer . bind ( this ) ,
45- ) ;
46- this . socket . on ( WORKSPACE_EVENT . RECEIVE_ICE , this . addIce . bind ( this ) ) ;
47- this . socket . on ( WORKSPACE_EVENT . RECEIVE_BYE , this . disconnectPeer . bind ( this ) ) ;
48-
49- this . socket . emit ( WORKSPACE_EVENT . SEND_HELLO ) ;
50- }
51-
5231 onMediaConnected ( callback : onMediaConnectedCb ) {
5332 this . onMediaConnectedCallback = callback ;
5433 }
@@ -57,108 +36,112 @@ class RTC {
5736 this . onMediaDisconnectedCallback = callback ;
5837 }
5938
60- private async setDescriptionAndEmitOffer ( remoteSocketId : SocketId ) {
61- const pc = this . createPeerConnection ( remoteSocketId ) ;
62- this . connections . set ( remoteSocketId , pc ) ;
39+ #createPeerConnection( remoteSocketId : string ) {
40+ // initialize
41+ const pcOptions = {
42+ iceServers : [ { urls : this . iceServerUrls } ] ,
43+ } ;
44+ const pc = new RTCPeerConnection ( pcOptions ) ;
6345
64- const offer = await pc . createOffer ( ) ;
65- await pc . setLocalDescription ( offer ) ;
46+ // add event listeners
47+ pc . addEventListener ( 'icecandidate' , ( iceEvent ) => {
48+ this . socket . emit (
49+ WORKSPACE_EVENT . 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 ) ) ;
6669
67- this . socket . emit ( WORKSPACE_EVENT . SEND_OFFER , offer , remoteSocketId ) ;
70+ return pc ;
6871 }
6972
70- private async setDescriptionAndEmitAnswer (
71- offer : RTCSessionDescriptionInit ,
72- remoteSocketId : SocketId ,
73- ) {
74- const pc = this . createPeerConnection ( remoteSocketId ) ;
75- await pc . setRemoteDescription ( offer ) ;
76- this . connections . set ( remoteSocketId , pc ) ;
77-
78- const answer = await pc . createAnswer ( ) ;
79- await pc . setLocalDescription ( answer ) ;
73+ async #setVideoBitrate( pc : RTCPeerConnection , bitrate : number ) {
74+ // fetch video sender
75+ const [ videoSender ] = pc
76+ . getSenders ( )
77+ . filter ( ( sender ) => sender ! . track ! . kind === 'video' ) ;
8078
81- this . socket . emit ( WORKSPACE_EVENT . SEND_ANSWER , answer , remoteSocketId ) ;
79+ // set bitrate
80+ const params = videoSender . getParameters ( ) ;
81+ params . encodings [ 0 ] . maxBitrate = bitrate ;
82+ await videoSender . setParameters ( params ) ;
8283 }
8384
84- private async setDescriptionForAnswer (
85- answer : RTCSessionDescriptionInit ,
86- remoteSocketId : SocketId ,
87- ) {
88- const pc = this . connections . get ( remoteSocketId ) ;
89- if ( ! pc ) {
90- throw new Error ( 'No RTCPeerConnection on answer received.' ) ;
91- }
92-
93- await pc . setRemoteDescription ( answer ) ;
94- }
85+ connect ( ) {
86+ this . socket . on ( WORKSPACE_EVENT . RECEIVE_HELLO , async ( remoteSocketId ) => {
87+ const pc = this . #createPeerConnection( remoteSocketId ) ;
88+ this . connections . set ( remoteSocketId , pc ) ;
9589
96- private async addIce ( ice : RTCIceCandidate , remoteSocketId : SocketId ) {
97- const pc = this . connections . get ( remoteSocketId ) ;
98- if ( ! pc ) {
99- throw new Error ( 'No RTCPeerConnection on ice candindate received.' ) ;
100- }
90+ const offer = await pc . createOffer ( ) ;
91+ await pc . setLocalDescription ( offer ) ;
10192
102- await pc . addIceCandidate ( ice ) ;
103- }
93+ this . socket . emit (
94+ WORKSPACE_EVENT . SEND_OFFER ,
95+ pc . localDescription ,
96+ remoteSocketId ,
97+ ) ;
98+ } ) ;
10499
105- private async disconnectPeer ( remoteSocketId : SocketId ) {
106- this . connections . delete ( remoteSocketId ) ;
107- this . streams . delete ( remoteSocketId ) ;
100+ this . socket . on (
101+ WORKSPACE_EVENT . RECEIVE_OFFER ,
102+ async ( offer , remoteSocketId ) => {
103+ const pc = this . #createPeerConnection( remoteSocketId ) ;
104+ this . connections . set ( remoteSocketId , pc ) ;
108105
109- this . onMediaDisconnectedCallback ( remoteSocketId ) ;
110- }
106+ await pc . setRemoteDescription ( offer ) ;
111107
112- private createPeerConnection ( remoteSocketId : string ) {
113- // initialize
114- const pcOptions = {
115- iceServers : [ { urls : this . iceServerUrls } ] ,
116- } ;
117- const pc = new RTCPeerConnection ( pcOptions ) ;
108+ const answer = await pc . createAnswer ( ) ;
109+ await pc . setLocalDescription ( answer ) ;
118110
119- pc . addEventListener ( 'icecandidate' , ( event ) =>
120- this . emitIce ( event , remoteSocketId ) ,
121- ) ;
122- pc . addEventListener ( 'track' , ( event ) =>
123- this . addRemoteStream ( event , remoteSocketId ) ,
111+ this . socket . emit ( WORKSPACE_EVENT . SEND_ANSWER , answer , remoteSocketId ) ;
112+ } ,
124113 ) ;
125- this . addTracksToLocalConnection ( pc ) ;
126114
127- return pc ;
128- }
129-
130- private emitIce ( event : RTCPeerConnectionIceEvent , remoteSocketId : string ) {
131- this . socket . emit ( WORKSPACE_EVENT . SEND_ICE , event . candidate , remoteSocketId ) ;
132- }
115+ this . socket . on (
116+ WORKSPACE_EVENT . RECEIVE_ANSWER ,
117+ async ( answer , remoteSocketId ) => {
118+ const pc = this . connections . get ( remoteSocketId ) ;
119+ if ( ! pc ) {
120+ throw new Error ( 'No RTCPeerConnection on answer received.' ) ;
121+ }
122+
123+ await pc . setRemoteDescription ( answer ) ;
124+ } ,
125+ ) ;
133126
134- private addRemoteStream ( event : RTCTrackEvent , remoteSocketId : string ) {
135- if ( this . streams . has ( remoteSocketId ) ) {
136- return ;
137- }
127+ this . socket . on ( WORKSPACE_EVENT . RECEIVE_ICE , ( ice , remoteSocketId ) => {
128+ const pc = this . connections . get ( remoteSocketId ) ;
138129
139- const [ remoteStream ] = event . streams ;
130+ if ( ! pc ) {
131+ throw new Error ( 'No RTCPeerConnection on ice candindate received.' ) ;
132+ }
140133
141- this . streams . set ( remoteSocketId , remoteStream ) ;
142- this . onMediaConnectedCallback ( remoteSocketId , remoteStream ) ;
143- }
134+ pc . addIceCandidate ( ice ) ;
135+ } ) ;
144136
145- private addTracksToLocalConnection ( pc : RTCPeerConnection ) {
146- this . userMediaStream
147- . getTracks ( )
148- . forEach ( ( track ) => pc . addTrack ( track , this . userMediaStream ) ) ;
149- }
137+ this . socket . on ( WORKSPACE_EVENT . RECEIVE_BYE , ( remoteSocketId ) => {
138+ this . connections . delete ( remoteSocketId ) ;
139+ this . streams . delete ( remoteSocketId ) ;
150140
151- // unused; may be used in the future
152- private async setVideoBitrate ( pc : RTCPeerConnection , bitrate : number ) {
153- // fetch video sender
154- const [ videoSender ] = pc
155- . getSenders ( )
156- . filter ( ( sender ) => sender ! . track ! . kind === 'video' ) ;
141+ this . onMediaDisconnectedCallback ( remoteSocketId ) ;
142+ } ) ;
157143
158- // set bitrate
159- const params = videoSender . getParameters ( ) ;
160- params . encodings [ 0 ] . maxBitrate = bitrate ;
161- await videoSender . setParameters ( params ) ;
144+ this . socket . emit ( WORKSPACE_EVENT . SEND_HELLO ) ;
162145 }
163146}
164147
0 commit comments