@@ -18,8 +18,9 @@ import '../types.dart';
1818import '../utils.dart' ;
1919
2020class SignalClient extends Disposable with EventsEmittable <SignalEvent > {
21- //
22- bool _connected = false ;
21+ // Connection state of the socket conection.
22+ ConnectionState _connectionState = ConnectionState .disconnected;
23+
2324 LiveKitWebSocket ? _ws;
2425
2526 SignalClient () {
@@ -33,8 +34,6 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
3334 });
3435 }
3536
36- bool get connected => _connected;
37-
3837 Future <void > connect (
3938 String uriString,
4039 String token, {
@@ -51,7 +50,7 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
5150 rtcUri,
5251 WebSocketEventHandlers (
5352 onData: _onSocketData,
54- onDispose: _onSocketDone ,
53+ onDispose: _onSocketDispose ,
5554 onError: _handleError,
5655 ),
5756 );
@@ -86,7 +85,8 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
8685 String token, {
8786 ConnectOptions ? connectOptions,
8887 }) async {
89- _connected = false ;
88+ logger.fine ('SignalClient reconnecting...' );
89+ _connectionState = ConnectionState .reconnecting;
9090 await _ws? .dispose ();
9191 _ws = null ;
9292
@@ -101,19 +101,106 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
101101 rtcUri,
102102 WebSocketEventHandlers (
103103 onData: _onSocketData,
104- onDispose: _onSocketDone ,
104+ onDispose: _onSocketDispose ,
105105 onError: _handleError,
106106 ),
107107 );
108108
109- _connected = true ;
109+ logger.fine ('SignalClient socket reconnected' );
110+ _connectionState = ConnectionState .connected;
110111 }
111112
112113 Future <void > close () async {
113- _connected = false ;
114+ logger. fine ( 'SignalClient close' ) ;
114115 await _ws? .dispose ();
116+ _ws = null ;
117+ }
118+
119+ void _sendRequest (lk_rtc.SignalRequest req) {
120+ if (_ws == null || isDisposed) {
121+ logger.warning (
122+ '[$objectId ] Could not send message, not connected or already disposed' );
123+ return ;
124+ }
125+
126+ final buf = req.writeToBuffer ();
127+ _ws? .send (buf);
128+ }
129+
130+ Future <void > _onSocketData (dynamic message) async {
131+ if (message is ! List <int >) return ;
132+ final msg = lk_rtc.SignalResponse .fromBuffer (message);
133+
134+ switch (msg.whichMessage ()) {
135+ case lk_rtc.SignalResponse_Message .join:
136+ events.emit (SignalConnectedEvent (response: msg.join));
137+ break ;
138+ case lk_rtc.SignalResponse_Message .answer:
139+ events.emit (SignalAnswerEvent (sd: msg.answer.toSDKType ()));
140+ break ;
141+ case lk_rtc.SignalResponse_Message .offer:
142+ events.emit (SignalOfferEvent (sd: msg.offer.toSDKType ()));
143+ break ;
144+ case lk_rtc.SignalResponse_Message .trickle:
145+ events.emit (SignalTrickleEvent (
146+ candidate: RTCIceCandidateExt .fromJson (msg.trickle.candidateInit),
147+ target: msg.trickle.target,
148+ ));
149+ break ;
150+ case lk_rtc.SignalResponse_Message .update:
151+ events.emit (SignalParticipantUpdateEvent (
152+ participants: msg.update.participants));
153+ break ;
154+ case lk_rtc.SignalResponse_Message .trackPublished:
155+ events.emit (SignalLocalTrackPublishedEvent (
156+ cid: msg.trackPublished.cid,
157+ track: msg.trackPublished.track,
158+ ));
159+ break ;
160+ case lk_rtc.SignalResponse_Message .speakersChanged:
161+ events.emit (
162+ SignalSpeakersChangedEvent (speakers: msg.speakersChanged.speakers));
163+ break ;
164+ case lk_rtc.SignalResponse_Message .connectionQuality:
165+ events.emit (SignalConnectionQualityUpdateEvent (
166+ updates: msg.connectionQuality.updates,
167+ ));
168+ break ;
169+ case lk_rtc.SignalResponse_Message .leave:
170+ events.emit (SignalLeaveEvent (canReconnect: msg.leave.canReconnect));
171+ break ;
172+ case lk_rtc.SignalResponse_Message .mute:
173+ events.emit (SignalMuteTrackEvent (
174+ sid: msg.mute.sid,
175+ muted: msg.mute.muted,
176+ ));
177+ break ;
178+ case lk_rtc.SignalResponse_Message .streamStateUpdate:
179+ events.emit (SignalStreamStateUpdatedEvent (
180+ updates: msg.streamStateUpdate.streamStates,
181+ ));
182+ break ;
183+ default :
184+ logger.warning ('skipping unsupported signal message' );
185+ }
115186 }
116187
188+ void _handleError (dynamic error) {
189+ logger.warning ('received websocket error $error ' );
190+ }
191+
192+ void _onSocketDispose () {
193+ logger.fine ('SignalClient onSocketDispose $_connectionState ' );
194+ // don't emit event's when reconnecting state
195+ if (_connectionState != ConnectionState .reconnecting) {
196+ logger.fine ('SignalClient did disconnect ${_connectionState }' );
197+ _connectionState = ConnectionState .disconnected;
198+ events.emit (const SignalCloseEvent ());
199+ }
200+ }
201+ }
202+
203+ extension SignalClientRequests on SignalClient {
117204 void sendOffer (rtc.RTCSessionDescription offer) =>
118205 _sendRequest (lk_rtc.SignalRequest (
119206 offer: offer.toSDKType (),
@@ -206,87 +293,4 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
206293 void sendLeave () => _sendRequest (lk_rtc.SignalRequest (
207294 leave: lk_rtc.LeaveRequest (),
208295 ));
209-
210- void _sendRequest (lk_rtc.SignalRequest req) {
211- if (_ws == null || isDisposed) {
212- logger.warning (
213- '[$objectId ] Could not send message, not connected or already disposed' );
214- return ;
215- }
216-
217- final buf = req.writeToBuffer ();
218- _ws? .send (buf);
219- }
220-
221- Future <void > _onSocketData (dynamic message) async {
222- if (message is ! List <int >) return ;
223- final msg = lk_rtc.SignalResponse .fromBuffer (message);
224-
225- switch (msg.whichMessage ()) {
226- case lk_rtc.SignalResponse_Message .join:
227- if (! _connected) {
228- _connected = true ;
229- events.emit (SignalConnectedEvent (response: msg.join));
230- }
231- break ;
232- case lk_rtc.SignalResponse_Message .answer:
233- events.emit (SignalAnswerEvent (sd: msg.answer.toSDKType ()));
234- break ;
235- case lk_rtc.SignalResponse_Message .offer:
236- events.emit (SignalOfferEvent (sd: msg.offer.toSDKType ()));
237- break ;
238- case lk_rtc.SignalResponse_Message .trickle:
239- events.emit (SignalTrickleEvent (
240- candidate: RTCIceCandidateExt .fromJson (msg.trickle.candidateInit),
241- target: msg.trickle.target,
242- ));
243- break ;
244- case lk_rtc.SignalResponse_Message .update:
245- events.emit (SignalParticipantUpdateEvent (
246- participants: msg.update.participants));
247- break ;
248- case lk_rtc.SignalResponse_Message .trackPublished:
249- events.emit (SignalLocalTrackPublishedEvent (
250- cid: msg.trackPublished.cid,
251- track: msg.trackPublished.track,
252- ));
253- break ;
254- case lk_rtc.SignalResponse_Message .speakersChanged:
255- events.emit (
256- SignalSpeakersChangedEvent (speakers: msg.speakersChanged.speakers));
257- break ;
258- case lk_rtc.SignalResponse_Message .connectionQuality:
259- events.emit (SignalConnectionQualityUpdateEvent (
260- updates: msg.connectionQuality.updates,
261- ));
262- break ;
263- case lk_rtc.SignalResponse_Message .leave:
264- events.emit (SignalLeaveEvent (canReconnect: msg.leave.canReconnect));
265- break ;
266- case lk_rtc.SignalResponse_Message .mute:
267- events.emit (SignalMuteTrackEvent (
268- sid: msg.mute.sid,
269- muted: msg.mute.muted,
270- ));
271- break ;
272- case lk_rtc.SignalResponse_Message .streamStateUpdate:
273- events.emit (SignalStreamStateUpdatedEvent (
274- updates: msg.streamStateUpdate.streamStates,
275- ));
276- break ;
277- default :
278- logger.warning ('skipping unsupported signal message' );
279- }
280- }
281-
282- void _handleError (dynamic error) {
283- logger.warning ('received websocket error $error ' );
284- }
285-
286- void _onSocketDone () {
287- if (! _connected) return ;
288- _ws = null ;
289- _connected = false ;
290- events.emit (const SignalCloseEvent ());
291- }
292296}
0 commit comments