connect method
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;
}
}