Nodejs,保持套接字io连接在MongoStore中保持活动

在nodejs-express应用程序中,在server.js文件中,我设置了socket-io连接。 它可以很好的做这样的事情

var server = require('http').createServer(app) var io = require('socket.io').listen(server); io.sockets.on('connection', function (socket) { // how can I save globally this 'socket'? }); 

我想将这个'socket'全局保存在server.js文件中,这样就可以在项目中的任何地方使用它。 喜欢这个:

 app.get('/on', function(req, res){ socket.on('test', function (data) { console.log(data); }); }); app.get('/emit', function(req, res){ socket.emit('test', "ciao"); }); 

我红色有一种方法来保存会话中的“套接字”连接。 我的会话设置:

 app.configure(function(){ // .... app.use(express.cookieParser(SITE_SECRET)); app.use(express.session({ secret : ,store : new MongoStore({ mongoose_connection : mongoose.connection ,db: mongoose.connections[0].db }) ,cookie: { maxAge: new Date(Date.now() + (1000*60*60*24*30*12)) } })); ... }); 

什么是一个好办法呢?

而且,在做了这个保存之后,如果连接还没打开,如何使用socket.on()和socket.emit()加载第一页?

你可能听说过的不是将一个套接字保存到一个会话中,而是通过它们的会话cookie来引用套接字,在套接字授权过程中将这个套接字传递给服务器。 在授权过程中,这是传递给服务器的对象types的示例:

 { headers: req.headers, // <Object> the headers of the request time: (new Date) +'', // <String> date time of the connection address: socket.address(), // <Object> remoteAddress and remotePort object xdomain: !!headers.origin, // <Boolean> was it a cross domain request? secure: socket.secure, // <Boolean> https connection issued: +date, // <Number> EPOCH of when the handshake was created url: request.url, // <String> the entrance path of the request query: data.query // <Object> the result of url.parse().query or a empty object } 

我们感兴趣的是headers属性,我们可以在其中find连接套接字的会话cookie。 然后,我们在授权过程中parsingcookie:

 // pass same objects from Express to Socket.IO so they match var parseCookie = express.cookieParser(SITE_SECRET); var store = new MongoStore({ mongoose_connection: mongoose.connection, db: mongoose.connections[0].db }); io.configure(function() { io.set('authorization', function(handshake, callback) { if (handshake.headers.cookie) { parseCookie(handshake, null, function(err) { // we used the signedCookies property since we have a secret // save the session ID to the socket object, we can access it later handshake.sessionID = handshake.signedCookies['connect.sid']; store.get(handshake.sessionID, function(err, session) { // we have the same Express session, reference it socket.session = session; callback(null, true); }); }); } else { // they client has no session yet, don't let them connect callback('No session.', false); } }); }); app.use(parseCookie); app.use(express.session({ secret: SITE_SECRET, store: store, cookie: {maxAge: new Date(Date.now() + (1000*60*60*24*30*12))} })); 

然后,一旦我们保存了会话ID,就可以使用典型的连接事件:

 var server = require('http').createServer(app) var io = require('socket.io').listen(server); var clients = {}; io.sockets.on('connection', function (socket) { // save to a global object var session = socket.handshake.sessionID; clients[session] = socket; socket.on('disconnect', function() { delete clients[session]; }); }); 

然后我们通过cookie签名来进行全局引用。 然后我们可以像这样访问套接字:

 app.get('/path', function(req, res) { var socket = clients[req.sessionID]; socket.emit('Socket client accessed route.'); }); 

请记住,您可能需要在具有多个选项卡的客户端的全局逻辑中添加一些逻辑,这会导致两个具有相同授权cookie的套接字。

至于你使用socket.on()socket.emit() ,你不能在连接build立之前使用它,因为套接字本身不存在。 如果你想发送消息给所有连接的客户端,那么你应该使用全局的io.sockets对象。 它会更像io.sockets.emit()