Nodejs+Socket.io服务报Cannot read property 'writeHead' of undefined错误如何解决
错误原因
- 核心问题是代码中直接使用了未定义的
data变量:socket连接的回调函数只会返回socket实例本身,你没有监听客户端发送的自定义事件,也没有从任何参数中接收客户端传值,就直接调用data.meetingid、data.current_user_name,data属于未声明的变量,触发的未捕获异常顺着Socket.io的内部调用栈传递,最终导致底层依赖的engine.io在处理错误响应时找不到对应的response对象,抛出Cannot read property 'writeHead' of undefined错误。 - 额外的不规范问题:端口定义顺序错误,你先启动服务监听3000端口,之后才定义PORT常量,虽然不是本次报错的直接原因,但不符合代码逻辑规范。
修复方案
服务端代码修改
主要调整3个点:
- 调整端口定义顺序,先定义端口再启动服务
- 增加自定义事件监听,从事件回调中接收客户端传来的
data参数 - 增加跨域配置,避免Flutter客户端和服务端不同源时连接失败
修复后的完整服务端代码如下:
const socketio = require('socket.io'); const express = require('express'); const app = express(); // 先定义端口常量,支持从环境变量读取端口 const PORT = process.env.PORT || 3000; // 启动服务 const server = app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); // 初始化Socket.io服务,增加跨域配置 const io = require("socket.io")(server, { cors: { origin: "*", methods: ["GET", "POST"] } }); // 存储用户连接信息的数组 var userConnection = []; io.on('connection', (socket)=> { console.log(`客户端连接成功,socket id:${socket.id}`); // 监听客户端发送的加入会议事件,接收客户端传的参数 socket.on('join-meeting', (data) => { try { // 筛选同会议的其他用户 const other_users = userConnection.filter(p => p.meeting_id === data.meetingid); // 存储当前用户的连接信息 userConnection.push({ connectionId: socket.id, user_id: data.current_user_name, meeting_id: data.meetingid, }); // 可向当前客户端返回加入成功通知 socket.emit('join-success', { other_users }); } catch(e) { console.log('处理加入会议逻辑出错:', e); } }); // 监听客户端断开连接事件,清理无效的连接信息 socket.on('disconnect', () => { userConnection = userConnection.filter(p => p.connectionId !== socket.id); console.log(`客户端断开连接,socket id:${socket.id}`); }); });
Flutter客户端适配
你需要在Flutter端连接服务端成功后,主动发送join-meeting事件并携带对应参数,示例代码如下:
import 'package:socket_io_client/socket_io_client.dart' as IO; // 初始化socket实例 IO.Socket socket = IO.io('你的服务端访问地址', <String, dynamic>{ 'transports': ['websocket'], 'autoConnect': false, }); // 连接服务端 socket.connect(); socket.onConnect((_) { print('连接服务端成功'); // 发送加入会议事件,携带参数 socket.emit('join-meeting', { 'meetingid': '实际的会议ID', 'current_user_name': '当前登录的用户名' }); });
内容的提问来源于stack exchange,提问作者Mahi
相关产品推荐
相关产品推荐

