socket.io-client-dart icon indicating copy to clipboard operation
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

Open Jules369-ZM opened this issue 8 months ago • 0 comments

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(); final _socketController = StreamController<Map<dynamic, dynamic>?>.broadcast();

/// Initialize the Socket.IO connection Future _init({ required String socketUrl, bool alwaysConnected = false, }) async { log('Initializing socket with URL: $socketUrl');

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 get hasSocketConnection async* { yield false; // Initial state yield* _socketState.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 emit(String event, dynamic data) async { try { final hasConnection = await InternetConnectionChecker().hasConnection; if (!hasConnection) { log('Cannot emit - No internet connection'); return; }

  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

Jules369-ZM avatar Jan 30 '25 08:01 Jules369-ZM