Node.js与Socket.io模块导入问题:counter函数无法在连接回调内运行
解决方案
你的问题根源在于counter.js中未定义io变量——Socket.io的实例是在app.js里创建的,counter.js无法直接访问到它,所以调用io.sockets.emit时会抛出错误导致服务器停止。
下面是两种可行的修复方式:
方式一:将io实例作为参数传递给counter函数
修改app.js的调用逻辑
在connection回调中调用counter时,把io实例传进去:
const express = require('express'); const app = express(); const http = require('http'); const server = http.createServer(app); const counter = require('./counter'); var io = require('socket.io')(server,{}); server.listen(3000, () => { console.log('listening on *:3000'); }); io.on('connection', function(socket) { // 传入io实例 counter(io); });
修改counter.js的函数定义
让counter函数接受io作为参数,并在内部使用这个参数:
const counter = (io) => { let time = 20; let countdown = setInterval(update, 1000); function update() { let sec = time % 60; // 使用传入的io实例发送消息 io.sockets.emit('countdown', sec); time--; if (sec === 0) { io.sockets.emit('countdown', 'Time is over'); clearInterval(countdown); } } } module.exports = counter
注意:我把emit的事件名改成了
countdown,直接发送数字作为事件名不是规范用法,客户端可以通过监听countdown事件来接收倒计时数据和结束提示。
方式二:在counter.js中直接获取io实例(不推荐)
如果你不想传递参数,可以把io的创建逻辑抽离到单独模块,然后在counter.js中导入:
- 创建
io.js:
const http = require('http'); const express = require('express'); const app = express(); const server = http.createServer(app); const io = require('socket.io')(server, {}); module.exports = { io, server, app };
- 修改
app.js:
const { io, server, app } = require('./io'); const counter = require('./counter'); server.listen(3000, () => { console.log('listening on *:3000'); }); io.on('connection', function(socket) { counter(); });
- 修改
counter.js:
const { io } = require('./io'); const counter = () => { let time = 20; let countdown = setInterval(update, 1000); function update() { let sec = time % 60; io.sockets.emit('countdown', sec); time--; if (sec === 0) { io.sockets.emit('countdown', 'Time is over'); clearInterval(countdown); } } } module.exports = counter
这种方式虽然能解决问题,但会增加模块间的耦合度,不如方式一灵活,所以更推荐方式一。
内容的提问来源于stack exchange,提问作者Vanila
相关产品推荐
相关产品推荐

