Socket.io - 在 node.js 的单独文件中监听事件
Posted
技术标签:
【中文标题】Socket.io - 在 node.js 的单独文件中监听事件【英文标题】:Socket.io - listen events in separate files in node.js 【发布时间】:2014-07-02 10:44:15 【问题描述】:例如我的想法是:
文件1.js
io.sockets.on('connection', function (socket)
socket.on('file1Event', function ()
//logic
);
);
文件2.js
io.sockets.on('connection', function (socket)
socket.on('file2Event', function ()
//logic
);
);
这段代码是用于节点服务器的,这段代码我会遇到问题吗?
【问题讨论】:
【参考方案1】:不,只需使用相同的“io”对象。
文件1.js
exports = module.exports = function(io)
io.sockets.on('connection', function (socket)
socket.on('file1Event', function ()
console.log('file1Event triggered');
);
);
文件2.js
exports = module.exports = function(io)
io.sockets.on('connection', function (socket)
socket.on('file2Event', function ()
console.log('file2Event triggered');
);
);
app.js
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
, file1 = require('./File1')(io)
, file2 = require('./File2')(io)
app.listen(3000);
function handler (req, res)
fs.readFile(__dirname + '/index.html',
function (err, data)
if (err)
res.writeHead(500);
return res.end('Error loading index.html');
res.writeHead(200);
res.end(data);
);
index.html
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.emit('file1Event'); // 'file1Event triggered' will be shown
socket.emit('file2Event'); // 'file2Event triggered' will be shown
</script>
【讨论】:
【参考方案2】:注意不要为每个文件生成新的连接事件。您应该使用相同的 on('connection') 事件,否则在导入 10 个文件后,您将从节点收到此错误:MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 connection listeners added. Use emitter.setMaxListeners() to increase limit
。
更好的方法是在你的主文件中这样做:
io.on('connection', function (socket)
require('pathToSocketRoutesFile1')(socket);
require('pathToSocketRoutesFile2')(socket);
require('pathToSocketRoutesFileN')(socket);
return io;
;
在每个单独的文件中:
module.exports = function(socket)
socket.on('eventName1', function()
//...
);
socket.on('eventName2', function()
//...
);
;
【讨论】:
如果您还需要在函数中使用io
,请不要忘记将它与socket
一起传递,如下所示:require('pathToSocketRoutesFileN')(socket, io)
。另外你不需要在连接函数中返回io
太棒了!有没有办法使用特定于文件的中间件?就像一个只能在文件 pathToSocketRoutesFile1
上运行的中间件?【参考方案3】:
另一种选择是创建一个 rootSocket,它处理初始连接,然后将套接字传递给其他处理程序。
const rootSocket = (io) =>
io.sockets.on('connection', (socket) =>
authorization(socket);
chat(socket);
);
;
exports.default = rootSocket;
【讨论】:
【参考方案4】:您可以在任何路由中使用 IO 模块,只需创建全局中间件。
socketiomw.js
module.exports = (io)=>
return (req,res,next)=>
req.io = io;
next();
middlewares.js
module.exports.global =
socketIo:require('./socketiomw'),
// add other global middleware
;
index.js
const express = require('express');
const app = express();
const port = 3000;
const http = require('http');
const server = http.createServer(app);
const Server = require("socket.io");
const io = new Server(server);
//global middleware initialization
app.use(require('./middlewares').global.socketIo(io));
app.get('/notify',(req,res)=>
req.io.emit("hello");
req.io.to("someRoom").emit("some event");
req.io.to("room1").to("room2").to("room3").emit("some event");
req.io.of("/").adapter.on("create-room", (room) =>
console.log(`room $room was created`);
);
req.io.of("/").adapter.on("join-room", (room, id) =>
console.log(`socket $id has joined room $room`);
);
req.json( success:true )
);
server.listen(port, () =>
console.log(`Example app listening at http://localhost:$port`)
)
我在全局中间件中使用了这个,所以我可以在任何路由中使用这个io module
【讨论】:
我现在如何使用 Io 模块?我应该在我想使用它的文件中放入什么? 我更新了答案。 ` app.get('/notify',(req,res)=> req.io.emit("hello"); req.json( success:true ) ); `【参考方案5】:rootSocket.js:
const rootSocket = (io) =>
io.on('connection', (socket) =>
console.log('New connection');
// possibility to outsource events
socket.on('myEvent', () =>
console.log('myEvent triggered');
);
);
module.exports = rootSocket;
index.js:
const express = require('express');
const app = express();
//app.use(express.json());
//const cors = require('cors');
//app.use(cors());
const http = require('http');
const server = http.createServer(app);
const socketIo = require('socket.io');
const io = socketIo(server);
const rootSocket = require('./rootSocket')(io);
const port = 8000;
// process.env.PORT for production
server.listen(port, () => console.log('server started on ' + port));
【讨论】:
以上是关于Socket.io - 在 node.js 的单独文件中监听事件的主要内容,如果未能解决你的问题,请参考以下文章
找不到Node.js /socket.io/socket.io.js express 4.0