Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

events not triggering am using socket_io_client: ^1.0.2 in app and socket_io v2.* on the server #409

Open
Jules369-ZM opened this issue Jan 30, 2025 · 0 comments

Comments

@Jules369-ZM
Copy link

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 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant