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

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个点:

  1. 调整端口定义顺序,先定义端口再启动服务
  2. 增加自定义事件监听,从事件回调中接收客户端传来的data参数
  3. 增加跨域配置,避免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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 18:27:01