Flutter socket.io客户端通过HTTPS无法连接Node.js socket.io服务端求助
问题排查与解决方案
问题原因
- 版本不兼容:Node.js服务端使用socket.io v2.4.1,Flutter端使用的socket_io_client v1.0.1仅适配socket.io v3.x/v4.x服务端,版本不匹配会导致连接握手失败
- 代码拼写错误:Flutter端配置传输协议的参数错误写为
transpose,正确参数名为transports,导致传输方式配置未生效 - 事件监听错误:Flutter端连接成功的监听事件应为
connect,你当前用的connection是服务端侧的连接事件,客户端不会触发 - 自签名证书不信任:你用的是本地生成的pem/crt自签名证书,浏览器手动信任后可正常访问,但移动端默认不信任自签名证书,会直接阻断HTTPS握手
- 地址配置错误:如果移动端用的是模拟器/真机,
https://<localhost>:3000的地址指向的是移动设备本身,而非运行服务端的电脑,需要替换为电脑的局域网IP,且证书的通用名(Common Name)要和访问的IP/域名一致
解决方案
1. 优先处理版本兼容
二选一即可:
- 方案1:降级Flutter端依赖,将pubspec.yaml中的
socket_io_client版本改为^0.9.12,该版本适配socket.io v2.x服务端 - 方案2:升级Node.js服务端socket.io版本到
^4.0.0,升级后需要额外配置CORS规则,示例如下:
// Node端升级后的io初始化代码 var io = require('socket.io')(server, { cors: { origin: "*", // 开发环境可临时设为*,生产环境填写实际客户端域名 methods: ["GET", "POST"] } });
2. 修正Flutter端代码
修正配置错误、事件监听错误,开发环境下临时关闭SSL证书校验,替换访问地址:
import 'package:flutter/material.dart'; import 'package:socket_io_client/socket_io_client.dart'; class TestSocket extends StatefulWidget { const TestSocket({Key? key}) : super(key: key); @override _TestSocketState createState() => _TestSocketState(); } class _TestSocketState extends State<TestSocket> { late Socket socket; @override void initState() { super.initState(); socketServer(); } // Socket Connection void socketServer() { try { // Configure socket transports // 替换<你的电脑局域网IP>为实际运行服务端的电脑IP,比如192.168.1.10 socket = io('https://<你的电脑局域网IP>:3000', <String, dynamic>{ 'transports': ['websocket'], // 修正拼写错误 'autoConnect': false, 'sslVerify': false, // 开发环境临时关闭SSL校验,生产环境必须删除该配置 }); // Connect to websocket socket.connect(); // Handle socket events socket.on('connect', (_) => print("Connected with ${socket.id}")); // 修正事件名 socket.on('connect_error', (err) => print("连接错误: $err")); // 增加错误监听方便排查 socket.on('message', (data) => print("收到服务端消息: $data")); } catch (e) { print('The error is ${e.toString()}'); } } @override Widget build(BuildContext context) { return Container(); } }
3. 生产环境注意事项
- 不要使用自签名证书,替换为正规CA机构颁发的可信SSL证书
- 移除
sslVerify: false配置,避免安全风险 - 确保证书的通用名与服务端访问域名完全一致
内容的提问来源于stack exchange,提问作者Shreyas Ramachandran
相关产品推荐
相关产品推荐

