connectWithRetry method
Future<void>
connectWithRetry(
- ClientTransport transport, {
- int maxRetries = 3,
- Duration delay = const Duration(seconds: 2),
Connect with retry mechanism
Implementation
Future<void> connectWithRetry(
ClientTransport transport, {
int maxRetries = 3,
Duration delay = const Duration(seconds: 2),
}) async {
if (_transport != null) {
throw McpError('Client is already connected to a transport');
}
if (_connecting) {
throw McpError('Client is already connecting to a transport');
}
_connecting = true;
int attempts = 0;
while (attempts < maxRetries) {
try {
_transport = transport;
_transport!.onMessage.listen(_handleMessage);
_transport!.onClose
.then((_) {
// Only send disconnect event if we're still connected
if (_transport != null) {
_disconnectStreamController.add(
DisconnectReason.transportClosed,
);
_onDisconnect();
}
})
.catchError((error) {
// Only handle error if we're still connected
if (_transport != null) {
_errorStreamController.add(McpError('Transport error: $error'));
_disconnectStreamController.add(
DisconnectReason.transportError,
);
_onDisconnect();
}
});
// Message handling setup
_messageController.stream.listen((message) async {
try {
await _processMessage(message);
} catch (e) {
_logger.debug('Error processing message: $e');
_errorStreamController.add(
McpError('Error processing message: $e'),
);
}
});
// Initialize connection
await initialize();
_connecting = false;
// Emit connection event after successful initialization
if (_initialized &&
_serverInfo != null &&
_serverCapabilities != null) {
_connectStreamController.add(
ServerInfo(
name: _serverInfo!['name'] as String? ?? 'Unknown',
version: _serverInfo!['version'] as String? ?? 'Unknown',
capabilities: _serverCapabilities!.toJson(),
protocolVersion: protocolVersion,
),
);
}
return; // Successfully connected
} catch (e) {
// Clean up resources on failure
if (_transport != null) {
try {
_transport!.close();
} catch (_) {}
_transport = null;
}
attempts++;
if (attempts >= maxRetries) {
_connecting = false;
_errorStreamController.add(
McpError('Failed to connect after $maxRetries attempts: $e'),
);
throw McpError('Failed to connect after $maxRetries attempts: $e');
}
_logger.debug(
'Connection attempt $attempts failed: $e. Retrying in ${delay.inSeconds} seconds...',
);
await Future.delayed(delay);
}
}
}