You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter Socket.IO客户端无法连接Node.js Socket.IO服务器问题求助

解决Flutter Socket.IO客户端无法连接Node.js Socket.IO服务器的问题

结合你描述的情况(版本匹配、Postman可连接但Flutter客户端超时),我帮你梳理几个关键排查点和修复方案:

1. 服务端CORS配置错误(Socket.IO v2.x的配置方式问题)

你使用的是Socket.IO v2.4.1,这个版本的CORS配置不是用cors对象,而是用origins参数。当前的cors: { origin: '*' }配置在v2.x中不会生效,可能导致Flutter客户端的跨域连接被拦截(Postman不受浏览器CORS限制所以能正常连接)。

修改服务端的初始化代码:

io = require("socket.io")(server, {
    origins: '*' // 替换原来的cors配置
});

如果需要更严格的控制,可以指定具体的源,比如origins: 'http://localhost:8080,http://192.168.1.14:5000'

2. Flutter客户端缺少必要的连接配置

你的客户端初始化代码没有指定传输方式和Socket.IO版本,这会导致客户端和服务端协商失败。Socket.IO v2.x默认使用polling+websocket的传输顺序,Flutter客户端需要明确配置这些参数:

修改Flutter客户端代码:

// 初始化时添加配置参数
io.Socket socket = io.io(
  "http://192.168.1.14:5000",
  OptionBuilder()
      .setTransports(['polling', 'websocket']) // 指定传输方式,和v2.x服务端匹配
      .disableAutoConnect() // 手动控制连接时机
      .build(),
);

// 监听连接事件
socket.onConnect((_) {
  log("Socket connected successfully!");
});
socket.onConnectError((data) {
  log("Connect error: $data");
});
socket.onError((data) {
  log("Error: $data");
});

// 手动触发连接
socket.connect();

这里的关键是:

  • 指定transports为服务端支持的类型
  • 手动调用connect()(默认情况下客户端可能不会自动发起连接,尤其是在初始化后)
  • 禁用自动连接可以让你更灵活地控制连接时机

3. 检查中间件的认证逻辑

你的服务端添加了socketGuard中间件用于认证,如果这个中间件返回isValid: false,会直接拒绝连接。可以先临时注释掉中间件,测试是否能正常连接:

// 暂时注释中间件,测试基础连接
// io.use(async (socket, next) => {
//     let result = await socketGuard(socket);
//     if (result.isValid) {
//         next();
//     } else {
//         next(new Error("Not authorized"));
//     }
// });

如果注释后能连接,说明问题出在socketGuard的认证逻辑里(比如token传递错误、解析失败等),需要排查中间件的实现。

4. 确认设备网络可达性

确保Flutter运行的设备(模拟器/真机)和Node.js服务器在同一个局域网内,并且能访问192.168.1.14:5000。可以在设备浏览器中访问http://192.168.1.14:5000/socket.io/,如果返回类似{"code":0,"message":"Transport unknown"}的内容,说明服务器的Socket.IO端点是正常可达的。


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

火山引擎 最新活动