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>
关键改动说明
- socket.io实例化:直接用
require("socket.io")(server)创建IO实例,无需后续二次调用。同时将CORS配置直接传入socket.io的选项中,更符合socket.io的配置规范。 - 服务器启动:单独调用
server.listen,避免逻辑嵌套,代码结构更清晰。 - 事件广播修正:将错误的
io.socket.emit改为io.emit,实现全局广播。 - 客户端补充:添加了完整的客户端代码,实现键盘事件监听与数据发送,确保端到端通信正常。
内容的提问来源于stack exchange,提问作者user26503803
相关产品推荐
相关产品推荐

