我如何避免node.js中的竞争条件,当我通过socket.io操纵会话?

我在我的socket.io安装程序中使用这个授权function:

io.set('authorization', function (data, accept) { if (!data.headers.cookie) { return accept('Session cookie required.', false); } data.cookie = require("cookie").parse(data.headers.cookie); data.cookie = require("connect").utils.parseSignedCookies(data.cookie,"yeah whatever"); data.sessionID = data.cookie['connect.sid']; sessionStore.get(data.sessionID, function(err, session){ if (err) { return accept('Error in session store.', false); } else if (!session) { return accept('Session not found.', false); } // success! we're authenticated with a known session.info. return accept(null, true); }); }); 

然后我操作这样的会话variables:

 var addAchievementToUser = function(achievement, sessionID) { sessionStore.get(sessionID, function(err, session) { //stuff happens here such as session.info.username = "whatever"; sessionStore.set(sessionID, session, function () { }); } }); }; 

这工作正常,做我想要的,但有时它会产生一些恶劣的竞争条件。

所以,我怎么能重写这个,以便它不创造竞争条件? 我查看了连接中间件,看看是否有可能只操作一个键/值对而不是整个会话对象。 但似乎这是不可能的,因为会话需要是一个string:

 MemoryStore.prototype.set = function(sid, sess, fn){ var self = this; process.nextTick(function(){ self.sessions[sid] = JSON.stringify(sess); fn && fn(); }); }; 

有任何想法吗?

好的,所以我开始使用redis中间件,这并没有真正帮助我解决这个问题。 无论如何,我基本上只通过socket.io编辑会议(和客户端第一次连接时),所以我觉得这将是最好的创build一个包含所有这样的活动会话的会话数组:

 io.set('authorization', function (data, accept) { if (!data.headers.cookie) { return accept('Session cookie required.', false); } data.cookie = require("cookie").parse(data.headers.cookie); data.cookie = require("connect").utils.parseSignedCookies(data.cookie, "rawr"); data.sessionID = data.cookie['connect.sid']; sessionStore.get(data.sessionID, function(err, session){ if (err) { return accept('Error in session store.', false); } else if (!session) { return accept('Session not found.', false); } // success! we're authenticated with a known session.info. if (!sessions[data.sessionID]) { sessions[data.sessionID] = session; } return accept(null, true); }); }); 

所以我从来不需要使用get session方法来编辑我的会话数据(只有set方法)。 好事是这样,即使同一个客户端连接多个套接字,它也能工作。