@@ -20,6 +20,7 @@ import 'package:sendbird_chat_sdk/src/public/core/user/user.dart';
2020import 'package:sendbird_chat_sdk/src/public/main/define/exceptions.dart' ;
2121import 'package:sendbird_chat_sdk/src/public/main/define/sendbird_error.dart' ;
2222import 'package:universal_io/io.dart' ;
23+ import 'package:uuid/uuid.dart' ;
2324
2425class ConnectionManager {
2526 Timer ? reconnectTimer;
@@ -344,72 +345,101 @@ class ConnectionManager {
344345 }
345346
346347 changeState (ReconnectingState (chat: chat));
347-
348- if (reset) {
349- chat.chatContext.resetReconnectTask ();
350- } else {
351- chat.chatContext.reconnectTask? .increaseRetryCount ();
352- }
348+ chat.chatContext.reconnectTask? .increaseRetryCount (reset: reset); // Check
353349
354350 sbLog.i (
355351 StackTrace .current,
356352 '[Timer()] ${chat .chatContext .reconnectTask ?.backOffPeriod }sec, ${chat .chatContext .reconnectTask ?.retryCount }/${chat .chatContext .reconnectTask ?.config .maximumRetryCount }' ,
357353 );
358354
359355 reconnectTimer? .cancel ();
360- reconnectTimer =
361- Timer (Duration (seconds: chat.chatContext.reconnectTask! .backOffPeriod),
362- () async {
363- sbLog.i (
364- StackTrace .current,
365- '[Timer() => RUN] ${chat .chatContext .reconnectTask ?.backOffPeriod }sec, ${chat .chatContext .reconnectTask ?.retryCount }/${chat .chatContext .reconnectTask ?.config .maximumRetryCount }' ,
366- );
356+ reconnectTimer = Timer (
357+ Duration (seconds: chat.chatContext.reconnectTask! .backOffPeriod),
358+ () async => await _reconnect (doNotCallReconnectStartedEvent),
359+ );
360+ return true ;
361+ }
367362
368- if (chat.chatContext.reconnectTask? .retryCount == 1 ) {
369- if (! doNotCallReconnectStartedEvent) {
370- await chat.eventDispatcher.onReconnecting ();
371- chat.eventManager.notifyReconnectStarted ();
372- }
363+ Future <void > _reconnect (bool doNotCallReconnectStartedEvent) async {
364+ sbLog.i (
365+ StackTrace .current,
366+ '[Timer() => RUN] ${chat .chatContext .reconnectTask ?.backOffPeriod }sec, ${chat .chatContext .reconnectTask ?.retryCount }/${chat .chatContext .reconnectTask ?.config .maximumRetryCount }' ,
367+ );
368+
369+ if (chat.chatContext.reconnectTask? .retryCount == 1 ) {
370+ if (! doNotCallReconnectStartedEvent) {
371+ await chat.eventDispatcher.onReconnecting ();
372+ chat.eventManager.notifyReconnectStarted ();
373373 }
374+ }
374375
375- // ===== Reconnect =====
376- final sessionKey = await chat.sessionManager.getSessionKey ();
377- final params = {
378- if (sessionKey == null ) 'user_id' : chat.chatContext.currentUserId,
379- 'SB-User-Agent' : _sbUserAgentHeader,
380- 'SB-SDK-USER-AGENT' : _sbSdkUserAgentHeader,
381- 'expiring_session' :
382- chat.eventManager.getSessionHandler () != null ? '1' : '0' ,
383- 'include_extra_data' : chat.extraData.join (',' ),
384- 'include_poll_details' : '1' ,
385- };
386- params.addAll (await _getWebSocketParams (
387- userId: chat.chatContext.currentUser? .userId ?? '' ));
388-
389- final url =
390- '${chat .chatContext .wsHost }/?${Uri (queryParameters : params ).query }' ;
391-
392- runZonedGuarded (() {
393- sbLog.d (StackTrace .current, 'webSocketClient?.connect()' );
394- webSocketClient.connect (
395- url: url,
396- accessToken: chat.chatContext.accessToken,
397- sessionKey: sessionKey,
398- );
376+ // ===== Reconnect =====
377+ final sessionKey = await chat.sessionManager.getSessionKey ();
378+ final params = {
379+ if (sessionKey == null ) 'user_id' : chat.chatContext.currentUserId,
380+ 'SB-User-Agent' : _sbUserAgentHeader,
381+ 'SB-SDK-USER-AGENT' : _sbSdkUserAgentHeader,
382+ 'expiring_session' :
383+ chat.eventManager.getSessionHandler () != null ? '1' : '0' ,
384+ 'include_extra_data' : chat.extraData.join (',' ),
385+ 'include_poll_details' : '1' ,
386+ };
387+ params.addAll (await _getWebSocketParams (
388+ userId: chat.chatContext.currentUser? .userId ?? '' ));
399389
400- reconnectTimer? .cancel ();
401- reconnectTimer = null ;
402- }, (e, s) {
403- sbLog.e (StackTrace .current, 'e: $e ' );
404- });
390+ final url =
391+ '${chat .chatContext .wsHost }/?${Uri (queryParameters : params ).query }' ;
392+
393+ runZonedGuarded (() {
394+ sbLog.d (StackTrace .current, 'webSocketClient?.connect()' );
395+
396+ chat.statManager.startWsConnectStat (hostUrl: url);
397+ if (chat.chatContext.reconnectTask != null ) {
398+ chat.chatContext.reconnectTask? .url = url;
399+ }
400+
401+ webSocketClient.connect (
402+ url: url,
403+ accessToken: chat.chatContext.accessToken,
404+ sessionKey: sessionKey,
405+ reconnect: true ,
406+ );
407+
408+ reconnectTimer? .cancel ();
409+ reconnectTimer = null ;
410+ }, (e, s) {
411+ sbLog.e (StackTrace .current, 'e: $e ' );
412+
413+ if (e is SendbirdException ) {
414+ chat.statManager.endWsConnectStat (
415+ hostUrl: url,
416+ success: false ,
417+ errorCode: e.code,
418+ errorDescription: e.message,
419+ accumTrial: chat.chatContext.reconnectTask? .retryCount ?? 1 ,
420+ connectionId: chat.chatContext.reconnectTask? .id ?? const Uuid ().v1 (),
421+ );
422+ } else {
423+ final exception = WebSocketFailedException (message: e.toString ());
424+
425+ chat.statManager.endWsConnectStat (
426+ hostUrl: url,
427+ success: false ,
428+ errorCode: exception.code,
429+ errorDescription: exception.message,
430+ accumTrial: chat.chatContext.reconnectTask? .retryCount ?? 1 ,
431+ connectionId: chat.chatContext.reconnectTask? .id ?? const Uuid ().v1 (),
432+ );
433+ }
405434 });
406- return true ;
407435 }
408436
409437//------------------------------//
410438// WebSocket Event Listener
411439//------------------------------//
412- void _onWebSocketConnected () {}
440+ void _onWebSocketConnected () {
441+ // Nothing to do here.
442+ }
413443
414444 void _onWebSocketClosed () {
415445 chat.commandManager.clearCompleterMap ();
@@ -459,6 +489,8 @@ class ConnectionManager {
459489 Future <void > _onWebSocketError (Object e) async {
460490 if (chat.chatContext.currentUser != null ) {
461491 if (isReconnecting ()) {
492+ await Future .delayed (const Duration (
493+ milliseconds: 1 )); // [Timing issue] Because of endWsConnectStat()
462494 await reconnect (reset: false );
463495 } else {
464496 await disconnect (logout: false );
0 commit comments