You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bloc初始化时userInformation未就绪,OnConnectSocket事件及配置是否生效?

问题解答

1. 触发OnConnectSocket事件能否正常工作?

如果这个事件是在userInformation就绪之后发送的,事件本身可以正常触发执行。需要注意:

  • 构造函数中初始化Socket时,因为userInformation未就绪,userInformation.token是无效的,但由于设置了disableAutoConnect: true,Socket不会自动尝试连接,所以不会立刻出现认证失败的问题。
  • 后续发送OnConnectSocket事件时,只要事件携带的event.userInformation是有效就绪的,事件处理逻辑会正常执行。

2. 修改_socket.io.options['auth']的逻辑是否有效?

大概率无效。原因在于socket_io_client的底层实现机制:

  • Socket实例初始化时,传入的options会被封装为固定的连接配置,后续直接修改_socket.io.options中的属性,底层连接逻辑不会重新读取这些修改后的参数。也就是说,调用_socket.connect()时,依然会使用构造函数初始化时的无效token,导致连接认证失败。
  • 代码中print('Connect Status ${_socket.connected}')打印false是正常现象,因为connect()是异步操作,调用后不会立即建立连接,需要等待onConnect回调触发才代表连接成功。

可行的解决方案

方案一:延迟初始化Socket实例

不在Bloc构造函数中创建Socket,而是在OnConnectSocket事件处理中,等userInformation就绪时再创建并连接:

class SocketBloc extends Bloc<SocketEvent, SocketState> {
  Socket? _socket;
  final UserInformation userInformation;

  SocketBloc({required this.userInformation}) 
      : super(SocketState(userInformation: userInformation)) {
    on<OnConnectSocket>((event, emit) async {
      try {
        // 当user就绪时才创建Socket实例
        _socket = io.io(
          Constant.endpointSocket,
          <String, dynamic>{
            'transports': ['websocket', 'polling'],
            'secure': true,
            'auth': {
              'token': event.userInformation.token // 使用有效token
            },
            'timeout': 5000,
            'reconnectionDelay': 5000,
            'disableAutoConnect': false, // 创建后自动连接
            'forceNewConnection': true
          });

        _socket?.onConnect((data) {
          add(OnSocketMessasges(
            Socket: Socket.onConnect,
            data: data,
          ));
          print('Connect Status ${_socket?.connected}'); // 此时会返回true
        });

      } catch (e) {
        racerLogger.e('Connect Error ${e.toString()}');
      }
    });
  }
}

方案二:使用Socket实例的auth更新API(版本兼容情况下)

部分新版本的socket_io_client支持直接修改socket.auth属性后重新连接,示例如下:

on<OnConnectSocket>((event, emit) async {
  try {
    // 直接更新auth,而非修改options
    _socket?.auth = {'token': event.userInformation.token};
    _socket?.connect();

    // 监听连接成功事件
    _socket?.onConnect((data) {
      add(OnSocketMessasges(
        Socket: Socket.onConnect,
        data: data,
      ));
      print('Connect Status: Connected');
    });

  } catch (e) {
    racerLogger.e('Connect Error ${e.toString()}');
  }
});

注意:这种方式需要确认你使用的socket_io_client版本是否支持动态修改auth属性,建议核对对应版本的官方说明。

内容的提问来源于stack exchange,提问作者aintno12u

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 02:44:54