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

Socket.io报错TypeError: socket is not a function,如何解决?

解决TypeError: socket is not a function错误及WebSocket按键检测实现

问题原因

你的代码错误地将socket.io的实例当作函数调用了。当执行const socket = require("socket.io")(server)时,已经完成了socket.io与HTTP服务器的绑定,返回的是一个IO实例对象而非构造函数。后续再用socket(server.listen(...))调用这个实例,自然会触发TypeError: socket is not a function。

另外代码还有两处小问题:

  • io.socket.emit是错误调用,io实例没有socket属性,广播事件应该用io.emit
  • 服务器启动逻辑嵌套在io实例化里,代码结构混乱

修正后的服务端代码(app.js)

// 模块导入
const express = require("express"),
  bd = require("body-parser"),
  cors = require("cors"),
  http = require("http");

const app = express();
const server = http.createServer(app);
// 直接创建socket.io实例并绑定到HTTP服务器
const io = require("socket.io")(server, {
  cors: {
    origin: "*",
    credentials: true
  }
});

// 中间件配置
app.use(bd.json());
app.use(bd.urlencoded({ extended: true }));
app.use(cors());

// 路由配置
app.get("/", (req, res) => {
  res.sendFile(__dirname + "/index.html");
});

// WebSocket连接监听
io.on("connection", (socket) => {
  console.log("客户端已连接,ID:", socket.id);
  
  // 监听客户端发送的按键事件
  socket.on("key_press", (keyData) => {
    console.log("收到按键:", keyData);
    // 广播按键事件给所有客户端(包括发送者)
    io.emit("key_press", keyData);
  });

  socket.on("disconnect", () => {
    console.log("客户端已断开连接,ID:", socket.id);
  });
});

// 启动服务器
server.listen(5050, (err) => {
  if (err) throw err;
  console.log("服务器成功运行在 http://localhost:5050");
});

客户端HTML代码(index.html)

需要引入socket.io客户端脚本,并监听键盘事件发送到服务端:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>WebSocket按键检测</title>
</head>
<body>
  <h1>按下任意键查看控制台输出</h1>

  <!-- 引入socket.io客户端脚本,路径由服务端自动提供 -->
  <script src="/socket.io/socket.io.js"></script>
  <script>
    // 连接到服务端
    const socket = io("http://localhost:5050");

    // 监听键盘按下事件
    document.addEventListener("keydown", (e) => {
      const keyData = {
        key: e.key,
        keyCode: e.keyCode,
        timestamp: Date.now()
      };
      // 发送按键数据到服务端
      socket.emit("key_press", keyData);
    });

    // 监听服务端广播的按键事件(可选,用于同步显示)
    socket.on("key_press", (keyData) => {
      console.log("服务端广播的按键:", keyData);
    });
  </script>
</body>
</html>

关键改动说明

  1. socket.io实例化:直接用require("socket.io")(server)创建IO实例,无需后续二次调用。同时将CORS配置直接传入socket.io的选项中,更符合socket.io的配置规范。
  2. 服务器启动:单独调用server.listen,避免逻辑嵌套,代码结构更清晰。
  3. 事件广播修正:将错误的io.socket.emit改为io.emit,实现全局广播。
  4. 客户端补充:添加了完整的客户端代码,实现键盘事件监听与数据发送,确保端到端通信正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 22:59:52