open static method
Future<SocketIoChannel>
open(
- FreedomeEndpoint endpoint,
- RealtimeHello hello, {
- Duration timeout = const Duration(seconds: 10),
- FreedomeLogger? logger,
Connects to <endpoint>/v1 (path /socket.io/) and waits for the namespace connect.
Implementation
static Future<SocketIoChannel> open(
FreedomeEndpoint endpoint,
RealtimeHello hello, {
Duration timeout = const Duration(seconds: 10),
FreedomeLogger? logger,
}) async {
final s = IO.io(
'${endpoint.baseUri}/v1',
IO.OptionBuilder()
.setTransports(['websocket'])
.setPath('/socket.io/')
.setAuth({
'app': hello.app,
'appVersion': ?hello.appVersion,
'sdk': ?hello.sdk,
'token': ?hello.token,
})
.disableAutoConnect()
.enableForceNew()
.disableReconnection()
.build(),
);
final ch = SocketIoChannel._(s, timeout);
final ready = Completer<void>();
s
..onConnect((_) {
if (!ready.isCompleted) ready.complete();
})
..onConnectError((Object? e) {
if (!ready.isCompleted) {
final msg = e is Map ? e['message'] : e;
ready.completeError(
'$msg'.contains('unauthenticated')
? UnauthorizedException('socket.io: $msg')
: NetworkException('socket.io connect failed: $msg'),
);
}
})
..onDisconnect((Object? reason) {
if (!ch._closed.isCompleted) {
ch._closed.complete(
RealtimeClosed(null, '$reason', byServer: !ch._closing),
);
}
unawaited(ch._events.close());
unawaited(ch._resyncs.close());
})
..on('event', (Object? data) {
if (data is Map) {
try {
ch._events.add(
FreedomeEvent.fromJson(data.cast<String, Object?>()),
);
} on FormatException catch (e) {
logger?.call(
FreedomeLogRecord(
FreedomeLogLevel.warning,
'socket.io: malformed event (${e.message})',
),
);
}
}
})
..on('resync', (Object? data) {
if (data is Map) {
try {
ch._resyncs.add(WsResync.fromJson(data.cast<String, Object?>()));
} on FormatException {
// Ignore malformed notices.
}
}
})
..connect();
try {
await ready.future.timeout(timeout);
} on TimeoutException {
s.dispose();
throw NetworkException('socket.io: no connect within $timeout');
} on FreedomeException {
s.dispose();
rethrow;
}
return ch;
}