getSid method

Future<String> getSid()

server assigned unique room id. returns once a sid has been issued by the server.

Implementation

Future<String> getSid() async {
  if (engine.connectionState == ConnectionState.disconnected) {
    return '';
  }

  if (_roomInfo != null && _roomInfo!.sid.isNotEmpty) {
    return _roomInfo!.sid;
  }

  final completer = Completer<String>();

  // SignalRoomUpdateEvent is emitted on the signal client's emitter (and
  // consumed by _setUpSignalListeners) — it never appears on the Room's
  // [events], so listen where it actually fires or the future returned
  // here never completes. Created via createListener() so it is cancelled
  // with its owner.
  final roomUpdateListener = engine.signalClient.createListener();
  roomUpdateListener.on<SignalRoomUpdateEvent>((event) {
    if (event.room.sid.isNotEmpty && !completer.isCompleted) {
      completer.complete(event.room.sid);
    }
  });

  // A caller waiting while the connection is still being established: the
  // sid may arrive inside the JoinResponse, which is applied via
  // EngineJoinResponseEvent without a SignalRoomUpdateEvent.
  final joinListener = engine.createListener();
  joinListener.on<EngineJoinResponseEvent>((event) {
    if (event.response.room.sid.isNotEmpty && !completer.isCompleted) {
      completer.complete(event.response.room.sid);
    }
  });

  final cancelDisconnectListen = events.once<RoomDisconnectedEvent>((event) {
    if (!completer.isCompleted) {
      completer.complete('');
    }
  });

  // Disposal without a disconnect event (Room.dispose during teardown)
  // cancels the listeners above — the constructor's dispose routine
  // completes every tracked waiter with '' instead of leaving the returned
  // future pending forever.
  _pendingSidCompleters.add(completer);

  // The update may have been applied between the check above and the
  // listener registration.
  if (_roomInfo != null && _roomInfo!.sid.isNotEmpty && !completer.isCompleted) {
    completer.complete(_roomInfo!.sid);
  }

  return completer.future.whenComplete(() async {
    _pendingSidCompleters.remove(completer);
    await roomUpdateListener.dispose();
    await joinListener.dispose();
    await cancelDisconnectListen?.call();
  });
}