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

Flutter与Frappe间Socket API连接问题求助

排查与解决步骤

1. 确认Frappe Socket服务状态与配置

Frappe默认基于Socket.IO提供实时服务,先从后端层面排除问题:

  • 检查Socket.IO进程:执行bench ps,确认存在node socketio.js相关进程;若没有,执行bench start socketio单独启动服务。
  • 验证站点配置:打开站点的site_config.json,确保包含"socketio_port": 9000(默认端口),且"host"设置为0.0.0.0或你的本地IP(如192.168.x.x),不要用localhost——模拟器/真机可能无法解析该地址。
  • 测试服务可用性:用浏览器访问http://<你的本地IP>:9000/socket.io/?EIO=4&transport=polling,若返回类似0{"sid":"xxx","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":5000}的内容,说明Socket服务正常。

2. 网络与权限排查(本地测试核心)

  • 设备网络映射:
    • Android模拟器:将localhost替换为10.0.2.2(模拟器本地回环映射地址);
    • iOS模拟器:可直接用localhost或127.0.0.1;
    • 真机:必须使用电脑的本地IP(如192.168.1.100)。
  • 应用权限配置:
    • Android:在AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET"/>;
    • iOS:在Info.plist中添加HTTP访问允许配置:
      <key>NSAppTransportSecurity</key>
      <dict>
          <key>NSAllowsArbitraryLoads</key>
          <true/>
      </dict>
      
  • 防火墙与代理:关闭电脑防火墙(或放行9000端口),确保Flutter应用未通过代理访问本地服务(若开启代理,需配置允许访问本地IP)。

3. 代码层面正确实现

推荐使用socket_io_client(适配Frappe Socket.IO协议)

Frappe的Socket.IO需要指定命名空间,若需认证需携带会话令牌:

import 'package:socket_io_client/socket_io_client.dart' as IO;

void connectFrappeSocket() {
  // 替换为你的本地IP与端口
  final socket = IO.io('http://192.168.1.100:9000', <String, dynamic>{
    'transports': ['websocket'], // 强制使用WebSocket,避免轮询问题
    'autoConnect': false,
  });

  // 携带Frappe会话认证(从浏览器开发者工具的Cookie中复制sid)
  socket.io.options['extraHeaders'] = {
    'Cookie': 'sid=<你的Frappe会话ID>',
  };

  socket.onConnect((_) {
    print('Socket连接成功');
    // 订阅文档更新事件(替换为你的DocType)
    socket.emit('subscribe', {'event': 'doc_update', 'doctype': 'Your DocType'});
  });

  socket.on('doc_update', (data) {
    print('收到文档更新:$data');
  });

  socket.onConnectError((err) => print('连接错误:$err'));
  socket.onDisconnect((_) => print('Socket断开连接'));

  socket.connect();
}

web_socket_channel使用注意事项

需手动适配Socket.IO协议,连接URL要包含完整路径:

import 'package:web_socket_channel/web_socket_channel.dart';

void connectWithWebSocket() {
  final url = Uri.parse('ws://192.168.1.100:9000/socket.io/?EIO=4&transport=websocket');
  final channel = WebSocketChannel.connect(url);

  channel.stream.listen(
    (message) {
      print('收到消息:$message');
      // 手动发送Socket.IO ping帧维持连接
      channel.sink.add('2');
    },
    onError: (error) => print('WebSocket错误:$error'),
    onDone: () => print('WebSocket连接关闭'),
  );
}

4. 日志与调试技巧

  • 开启Frappe Socket.IO调试日志:执行bench set-config -g socketio_log_level debug,再重启服务bench restart socketio,此时bench日志会输出详细的连接记录。
  • 用wscat测试连接:全局安装npm install -g wscat,执行wscat -c ws://<本地IP>:9000/socket.io/?EIO=4&transport=websocket,若能连接并在发送2后收到3(pong响应),则排除Flutter代码问题,确认后端服务正常。

5. 常见坑点

  • 会话认证缺失:未携带有效Frappe会话Cookie时,服务会静默拒绝连接,需从登录后的浏览器Cookie中复制sid添加到Socket请求头。
  • 端口冲突:用lsof -i :9000(Mac/Linux)或netstat -ano | findstr :9000(Windows)检查9000端口是否被占用,若冲突可修改Frappe的socketio_port配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 04:20:18