Flutter通过WebSocket对接Node.js Socket.IO服务器通信失败求助
问题根源:协议不兼容
你遇到的核心问题很明确:Flutter端用的是标准WebSocket协议,但Node.js端用的是Socket.IO框架——Socket.IO并不是纯粹的WebSocket实现,它在标准协议之上封装了自定义的握手、心跳、事件机制,原生WebSocket客户端根本没法和它直接通信,这就是为什么你发消息收不到反馈的原因。
下面给你两种可行的解决方案,按需选择:
方案1:Node.js改用标准WebSocket库
如果你想继续用Flutter的原生WebSocket,那Node.js端需要换成标准WebSocket实现,比如ws库:
- 先安装依赖:
npm install ws
- 修改Node.js服务器代码:
const express = require('express'); const http = require('http'); const WebSocket = require('ws'); const app = express(); const server = http.createServer(app); const wss = new WebSocket.Server({ server }); app.get('/', (req, res) => { res.send('hey people'); }); // 处理WebSocket连接与消息 wss.on('connection', (ws) => { console.log('a user connected'); // 接收客户端消息并主动回复 ws.on('message', (message) => { console.log(`received: ${message}`); ws.send(`Server echo: ${message}`); }); // 监听断开连接 ws.on('close', () => { console.log('user disconnected'); }); }); const PORT = process.env.PORT || 3000; server.listen(PORT, () => console.log(`app started on port ${PORT}`));
你的Flutter客户端代码完全不需要修改,直接运行就能实现双向通信——客户端发消息后,服务器会立即回复,Flutter的StreamBuilder也能实时接收到回复内容。
方案2:Flutter使用Socket.IO客户端库
如果想保留Node.js的Socket.IO服务器,那Flutter端需要用对应的Socket.IO客户端库,而不是原生WebSocket:
- 在Flutter项目的
pubspec.yaml中添加依赖:
dependencies: flutter: sdk: flutter socket_io_client: ^2.0.3 # 可替换为最新兼容版本
- 修改Flutter客户端代码:
import 'package:flutter/material.dart'; import 'package:socket_io_client/socket_io_client.dart' as IO; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { final title = 'Socket.IO Demo'; // 初始化Socket.IO连接,指定用WebSocket传输 final socket = IO.io('http://localhost:3000', <String, dynamic>{ 'transports': ['websocket'], 'autoConnect': true, }); return MaterialApp( title: title, home: MyHomePage(title: title, socket: socket), ); } } class MyHomePage extends StatefulWidget { final String title; final IO.Socket socket; const MyHomePage({Key? key, required this.title, required this.socket}) : super(key: key); @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { final TextEditingController _controller = TextEditingController(); String _receivedMessage = ''; @override void initState() { super.initState(); // 监听服务器发来的消息 widget.socket.on('message', (data) { setState(() { _receivedMessage = data.toString(); }); }); // 监听连接状态 widget.socket.onConnect((_) => print('connected to server')); widget.socket.onDisconnect((_) => print('disconnected from server')); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(widget.title)), body: Padding( padding: const EdgeInsets.all(20.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( controller: _controller, decoration: const InputDecoration(labelText: 'Send a message'), ), Padding( padding: const EdgeInsets.symmetric(vertical: 24.0), child: Text(_receivedMessage.isNotEmpty ? _receivedMessage : ''), ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _sendMessage, child: const Icon(Icons.send), ), ); } void _sendMessage() { if (_controller.text.isNotEmpty) { widget.socket.emit('message', _controller.text); _controller.clear(); } } @override void dispose() { widget.socket.disconnect(); _controller.dispose(); super.dispose(); } }
- 同时完善Node.js的Socket.IO服务器,添加消息处理逻辑:
const express= require('express'); const app= express(); const http=require('http'); const socketio= require('socket.io'); const server= http.createServer(app); const io=socketio(server); app.get('/',(req,res)=>{ res.send('hey people') }) const PORT= process.env.PORT||3000; io.on('connection', (socket) => { console.log('a user connected'); // 监听客户端的'message'事件并回复 socket.on('message', (msg) => { console.log(`received: ${msg}`); socket.emit('message', `Server received: ${msg}`); }); socket.on('disconnect', () => { console.log('user disconnected'); }); }); server.listen(PORT,()=> console.log(`app started on port ${PORT}`));
这样两端就用统一的Socket.IO协议通信,能正常收发消息了。
额外注意事项
- 真机测试时,不要用
localhost,换成你的电脑局域网IP(比如192.168.x.x),确保手机和电脑在同一网络下。 - 注意Socket.IO客户端和服务器的版本兼容性,比如服务器用v4的话,客户端也要对应使用支持v4的
socket_io_client版本。
内容的提问来源于stack exchange,提问作者Himanshu Ranjan
相关产品推荐
相关产品推荐

