connect method
Connect to Lavalink WebSocket
Implementation
Future<void> connect() async {
if (_isConnecting || _socket != null) {
LavalinkLogger.warning('Already connected or connecting', tag: 'WebSocket');
return;
}
_isConnecting = true;
_intentionallyClosed = false;
int retries = 0;
const maxRetries = 5;
Duration delay = Duration(seconds: 1);
while (retries < maxRetries) {
try {
final uri = '${useSSL ? 'wss' : 'ws'}://$host:$port/v4/websocket';
LavalinkLogger.info(
'Connecting to Lavalink WebSocket: $uri (attempt ${retries + 1}/$maxRetries)',
tag: 'WebSocket',
);
_socket = await WebSocket.connect(
uri,
headers: {
'Authorization': password,
'User-Id': userId,
'Client-Name': 'Milter/1.0',
},
).timeout(
Duration(seconds: 15),
onTimeout: () {
throw TimeoutException('WebSocket connection timeout after 15 seconds');
},
);
LavalinkLogger.info('✅ WebSocket connected successfully!', tag: 'WebSocket');
_reconnectAttempts = 0;
_startHeartbeat();
_socket!.listen(
_handleMessage,
onError: _handleError,
onDone: _handleClose,
cancelOnError: false,
);
_isConnecting = false;
return; // Success!
} on SocketException catch (e) {
retries++;
LavalinkLogger.error(
'SocketException (attempt $retries/$maxRetries): ${e.message}',
tag: 'WebSocket',
error: e,
);
if (retries >= maxRetries) {
_isConnecting = false;
throw LavalinkConnectionException(
'Failed to connect to Lavalink WebSocket after $maxRetries attempts.\n'
'URL: ws://$host:$port/v4/websocket\n'
'Error: ${e.message}\n\n'
'Troubleshooting:\n'
'1. Make sure Lavalink is running (check with: netstat -an | findstr :2333)\n'
'2. Verify host and port in your config\n'
'3. Check Lavalink logs for errors\n'
'4. Ensure no firewall is blocking port $port',
cause: e,
);
}
LavalinkLogger.info('Retrying in ${delay.inSeconds} seconds...', tag: 'WebSocket');
await Future.delayed(delay);
delay *= 2; // Exponential backoff
} on TimeoutException catch (e) {
retries++;
LavalinkLogger.error(
'Connection timeout (attempt $retries/$maxRetries)',
tag: 'WebSocket',
error: e,
);
if (retries >= maxRetries) {
_isConnecting = false;
throw LavalinkConnectionException(
'WebSocket connection timeout after $maxRetries attempts.\n'
'URL: ws://$host:$port/v4/websocket\n\n'
'Lavalink may be slow to respond or not running properly.\n'
'Check Lavalink logs and server status.',
cause: e,
);
}
await Future.delayed(delay);
delay *= 2;
} catch (e) {
_isConnecting = false;
LavalinkLogger.error(
'Unexpected error while connecting to WebSocket',
tag: 'WebSocket',
error: e,
);
throw LavalinkException(
'WebSocket connection error: $e\n'
'Host: $host:$port\n'
'SSL: $useSSL\n\n'
'Make sure Lavalink is running and accessible.',
cause: e,
);
}
}
_isConnecting = false;
}