connect method

Future<void> connect(
  1. ButtplugClientConnector connector
)

Implementation

Future<void> connect(ButtplugClientConnector connector) async {
  if (_connecting || _disconnecting || _isConnected || _communicator?.connected() == true) {
    throw ButtplugClientException("Client is already connected");
  }
  _connecting = true;
  _connectionCancelled = false;
  final communicator = ButtplugClientCommunicator(connector);
  _communicator = communicator;
  try {
    await _messageSubscription?.cancel();
    if (_connectionCancelled) throw ButtplugClientException('Connection cancelled');
    _messageSubscription = connector.messageStream.listen(
      (message) => _handleMessage(communicator, message),
      onDone: () => _handleDisconnect(communicator),
      onError: (_, _) => _handleDisconnect(communicator),
    );
    await communicator.connect();
    if (_connectionCancelled || !identical(_communicator, communicator)) {
      throw ButtplugClientException('Connection cancelled');
    }
    final requestServerInfo = RequestServerInfo()..clientName = name;
    final serverInfo = await communicator.sendMessageExpectReply(requestServerInfo);
    if (serverInfo.serverInfo == null) {
      throw ButtplugClientException(
        "Did not receive ServerInfo message back from server on handshake: ${jsonEncode(serverInfo.toJson())}.",
      );
    }
    _serverName = serverInfo.serverInfo!.serverName;

    final deviceListWrapper = await communicator.sendMessageExpectReply(RequestDeviceList());
    if (deviceListWrapper.deviceList == null) {
      throw ButtplugClientException("Did not receive DeviceList message back from server on handshake.");
    }
    if (_connectionCancelled || !identical(_communicator, communicator) || !communicator.connected()) {
      throw ButtplugClientException('Connection closed during handshake');
    }
    _replaceDevices(deviceListWrapper.deviceList!, communicator);
    _isConnected = true;
    communicator.eventStreamController.add(DeviceListReceivedEvent());
  } catch (_) {
    try {
      await _cleanupConnection(communicator);
    } catch (_) {
      // Preserve the connection failure if transport cleanup also fails.
    }
    rethrow;
  } finally {
    _connecting = false;
  }
}