socket.io-client-dart
socket.io-client-dart copied to clipboard
events not triggering am using socket_io_client: ^1.0.2 in app and socket_io v2.* on the server
import 'dart:async'; import 'dart:developer'; import 'package:auth_repo/auth_repo.dart'; import 'package:internet_connection_checker/internet_connection_checker.dart'; import 'package:local_data/local_data.dart'; import 'package:socket_io_client/socket_io_client.dart' as io_client;
/// {@template socket_source} /// Package to handle Socket.IO calls /// {@endtemplate} class SocketSource { /// {@macro socket_source} SocketSource._( this._token, this._prefs, this._appBuildConfig, this._storeId, );
final String _token; final String _storeId; // ignore: unused_field final SharedPrefs _prefs; final AppBuildConfig _appBuildConfig;
/// Public factory to initialize the SocketSource static Future<SocketSource> init( String socketUrl, { required SharedPrefs prefs, required AppBuildConfig appBuildConfig, required String storeId, bool alwaysConnected = false, String? token, }) async { final socketApi = SocketSource._( token ?? '', prefs, appBuildConfig, storeId, ); await socketApi._init( socketUrl: socketUrl, alwaysConnected: alwaysConnected, ); return socketApi; }
late io_client.Socket _socket;
// Stream controllers to manage connection status and incoming messages
final _socketState = StreamController
/// Initialize the Socket.IO connection
Future
InternetConnectionChecker().onStatusChange.listen((event) {
switch (event) {
case InternetConnectionStatus.connected:
log('Internet connected');
log('Socket URL: $socketUrl');
try {
_socket = io_client.io(
socketUrl,
io_client.OptionBuilder()
.setTimeout(10000)
.setReconnectionDelay(5000)
.setReconnectionDelayMax(10000)
.enableAutoConnect()
.enableForceNewConnection()
.enableReconnection()
.setTransports(['websocket']).build(),
);
// Initialize socket event handlers
_setupSocketEventHandlers();
} catch (e, stackTrace) {
log('Socket initialization error: $e');
log('Stack trace: $stackTrace');
}
if (!_socket.connected) {
_connectToSocket();
} else {
log('Socket already connected');
_socketState.add(true);
}
case InternetConnectionStatus.disconnected:
log('Internet disconnected');
_socketState.add(false);
_socket.disconnect();
}
});
final hasConnection = await InternetConnectionChecker().hasConnection;
if (hasConnection && alwaysConnected) {
_connectToSocket();
}
}
void _setupSocketEventHandlers() { socket ..onConnect(() { log('Socket connected successfully'); _handleConnection(); debugSocketState(); socketState.add(true); }) ..onDisconnect(() { log('Socket disconnected'); socketState.add(false); }) ..onConnectError((error) { log('Socket connection error: $error'); }) ..onError((error) { log('Socket error: $error'); }) ..onReconnect(() { log('Socket reconnected'); _handleConnection(); debugSocketState(); socketState.add(true); }) ..onReconnectError((error) { log('Socket reconnection error: $error'); }) ..onReconnectFailed(() { log('Socket reconnection failed'); }); }
/// Connect to the Socket.IO server void _connectToSocket() { try { log('Attempting to connect to socket...'); _socket.connect(); } catch (e) { log('Error connecting to socket: $e'); } }
void _handleConnection() { try { // First emit the merchant data final merchantData = { 'token': _token, 'appId': _appBuildConfig.appId, 'sender': 'Jules', 'storeId': _storeId, };
log('Emitting addMerchant event with data: $merchantData');
emit('addMerchant', merchantData);
// Then set up all event listeners
_socket
..on('orderAddTime', (data) {
log('Received orderAddTime: $data');
_emitToController('orderAddTime', data);
})
..on('pendingOrderCount', (data) {
log('Received pendingOrderCount: $data');
_emitToController('pendingOrderCount', data);
})
..on('storeOrder', (data) {
log('Received storeOrder: $data');
_emitToController('storeOrder', data);
})
..on('orderLimitAlert', (data) {
log('Received orderLimitAlert: $data');
_emitToController('orderLimitAlert', data);
})
..on('addMerchant', (data) {
log('Received addMerchant: $data');
_emitToController('addMerchant', data);
})
..on('acceptOrder', (data) {
log('Received acceptOrder: $data');
_emitToController('acceptOrder', data);
})
..on('statusChange', (data) {
log('Received statusChange: $data');
_emitToController('statusChange', data);
})
..on('updateStore', (data) {
log('Received updateStore: $data');
_emitToController('updateStore', data);
});
} catch (e, stackTrace) {
log('Error in _handleConnection: $e');
log('Stack trace: $stackTrace');
}
}
void _emitToController(String event, dynamic data) { final response = <String, dynamic>{ 'event': event, 'data': data, }; _socketController.add(response); }
/// Socket connection status stream
Stream
/// Stream to listen for messages from the socket Stream<Map<dynamic, dynamic>?> get channelStream async* { yield* _socketController.stream; }
/// Emit data to a Socket.IO event
Future
if (_socket.connected) {
log('Emitting event: $event');
log('Event data: $data');
_socket.emit(event, data);
} else {
log('Socket not connected - attempting to reconnect');
_connectToSocket();
}
} catch (e) {
log('Error emitting event: $e');
}
}
/// Disconnect from the Socket.IO server void disconnect() { try { _socket.disconnect(); _socketState.add(false); log('Socket disconnected successfully'); } catch (e) { log('Error disconnecting socket: $e'); } }
/// Dispose method to clean up resources void dispose() { try { disconnect(); _socketController.close(); _socketState.close(); log('Socket resources disposed successfully'); } catch (e) { log('Error disposing socket resources: $e'); } }
/// void debugSocketState() { try { log('=== Socket Debug Information ==='); log('Socket Connected: ${_socket.connected}'); log('Socket ID: ${_socket.id}'); log('Active Transport: ${_socket.io.engine.transport?.name}'); log('Attempted Events:'); _socket.emit('debug_events', { 'token': _token, 'appId': _appBuildConfig.appId, 'storeId': _storeId, });
// Test emit for each event to verify server handling
final testEvents = [
'orderAddTime',
'pendingOrderCount',
'storeOrder',
'orderLimitAlert',
// 'acceptOrder',
'statusChange',
'updateStore',
];
for (final event in testEvents) {
_socket.emit(event, {
'test': true,
'event': event,
'token': _token,
'appId': _appBuildConfig.appId,
'storeId': _storeId,
});
log('Emitted test for event: $event');
}
} catch (e) {
log('Error in debugSocketState: $e');
}
} }
the first event addMerchant which I emit after successful connection is responding correctly but these others are not triggered i.e storeOrder