open static method

Future<SocketIoChannel> open(
  1. FreedomeEndpoint endpoint,
  2. RealtimeHello hello, {
  3. Duration timeout = const Duration(seconds: 10),
  4. 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;
}