我正在尝试将Socket.io与Node.js一起使用并发送到路由逻辑中的套接字。
我有一个相当标准的Express 3设置,其中包含一个位于路由中的server.js文件,然后我有一个index.js,它位于路径文件夹中,用于导出站点的所有页面/可公开访问的功能。所以他们看起来像:
exports.index = function (req, res) {
res.render('index', {
title: "Awesome page"
});
};
使用server.js中定义的路由,如:
app.get('/',routes.index);
我假设我必须在server.js中创建socket.io对象,因为它需要服务器对象,但是如何访问该对象并从index.js导出函数向它发出?
答案 0 :(得分:66)
现在有一种更好的方法可以使用Express 4.0。
您可以使用app.set()存储对io
对象的引用。
基本配置:
var app = require('express')();
var server = app.listen(process.env.PORT || 3000);
var io = require('socket.io')(server);
// next line is the money
app.set('socketio', io);
内部路线或中间件:
exports.foo = function(req,res){
// now use socket.io in your routes file
var io = req.app.get('socketio');
io.emit('hi!');
}
有关app.set()
和app.get()
的信息如下:
app.set(名称,值)
将设置名称指定给值。您可以存储任何您想要的值, 但某些名称可用于配置服务器的行为。 这些特殊名称列在app settings table。
中调用
app.set('foo', true)
获取布尔属性与 致电app.enable('foo')
。同样,呼叫app.set('foo', false)
对于布尔属性,与调用app.disable('foo')
相同。使用
app.get()
检索设置的值。
答案 1 :(得分:14)
您可以将路径文件设置为函数,并在需要文件时传递Socket.IO对象。
module.exports = function(io) {
var routes = {};
routes.index = function (req, res) {
io.sockets.emit('payload');
res.render('index', {
title: "Awesome page"
});
};
return routes;
};
然后需要这样的路线:
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var routes = require('./routes')(io);
答案 2 :(得分:8)
aarosil的答案很棒,但我遇到了与Victor一样的问题,使用这种方法管理客户端连接。对于客户端上的每次重新加载,您将在服务器上获得尽可能多的重复消息(第二次重新加载= 2次重复,第三次= 3次重复等)。
扩展了aarosil的答案,我使用这种方法在我的路由文件中使用套接字对象,并管理连接/控制重复消息:
内部服务器文件
// same as aarosil (LIFESAVER)
const app = require('express')();
const server = app.listen(process.env.PORT || 3000);
const io = require('socket.io')(server);
// next line is the money
app.set('socketio', io);
内部路线文件
exports.foo = (req,res) => {
let socket_id = [];
const io = req.app.get('socketio');
io.on('connection', socket => {
socket_id.push(socket.id);
if (socket_id[0] === socket.id) {
// remove the connection listener for any subsequent
// connections with the same ID
io.removeAllListeners('connection');
}
socket.on('hello message', msg => {
console.log('just got: ', msg);
socket.emit('chat message', 'hi from server');
})
});
}
答案 3 :(得分:3)
使用
有什么不对global.io = require('socket.io').listen(server);
答案 4 :(得分:1)
这里超级晚了,但是我想访问我的路由中的套接字,特别想在保存到数据库后广播消息。我使用@aarosil提供的答案来设置/获取io对象,向每个客户端发送其连接时的套接字ID,然后在路由中使用套接字ID以便能够使用socket.broadcast.emit()
而不是{{1} }。
在服务器中:
io.emit()
我随每个请求发送套接字ID,然后可以在路由中执行以下操作:
const io = require('socket.io')(server)
app.set('socketio', io)
io.on('connect', socket => {
socket.emit('id', socket.id) // send each client their socket id
})
答案 5 :(得分:0)
module.parent.exports.server
也会有效。