connect method
Connect to the socket server using the token
@param data - {String token }
Implementation
Future<Socket> connect(String token) async {
if (this.token == null) {
setToken(token);
}
if (connectionState == ConnectionState.connected) {
logger.e('🔴 Socket Already Connected');
return Socket._instance;
}
if (connectionState == ConnectionState.connecting) {
logger.e('🔴 Socket Connecting');
return this;
}
if (_ws != null) {
logger.e('🔴 Socket Already Initialized');
return Socket._instance;
}
logger.i('🔌 Connecting to the socket server');
if (_region == null) {
String? region = await _getRegion();
_region = region;
}
final url = await _getConfigUrl(token, region);
logger.i('Region -> $region | URL -> $url');
connectionState = ConnectionState.connecting;
emit('connecting');
_ws = IOWebSocketChannel.connect(url);
StreamController socketStreamController = StreamController.broadcast();
Stream? socketStream = _ws?.stream;
if (socketStream != null) {
socketStreamController.addStream(socketStream);
}
Future<void> webSocketListener() async {
Completer<void> eventCompleter = Completer<void>();
socketStreamController.stream.listen(
(message) {
_handleSocketOpen();
_handleIncomingMessage(message);
// Resolving future function -> Completion
// Will only work if the event is received from backend -> Eg: "() => 'hello"
eventCompleter.complete();
eventCompleter = Completer<void>();
},
onDone: () {
_handleSocketClose(_ws);
logger.i('Socket connection closed');
if (_retryCount < 5) {
if (_ws?.closeCode == ESocketCloseCode.abnormalClosure.value) {
final delay = Duration(milliseconds: 2 << _retryCount);
Timer(delay, () async {
await connect(token);
emit('reconnected');
_retryCount = 0;
eventCompleter.complete();
});
_retryCount++;
}
}
},
onError: (error) {
_handleSocketError(error);
logger.e(
'🔴 Socket connection closed abnormally, reconnecting failed',
);
close(ESocketCloseCode.connectionExpired);
eventCompleter.completeError(error);
},
);
await eventCompleter.future;
}
await webSocketListener();
return Socket._instance;
}