3

私は自分のsocket.ioセットアップでこの承認機能を使用しています:

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);
    });
});

次に、セッション変数を次のように操作します。

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 () {
            });
        }
    });
};

これはうまく機能し、私が望むことを行いますが、時にはいくつかの悪い競合状態が発生します。

では、競合状態が発生しないようにこれを書き直すにはどうすればよいですか? 接続ミドルウェアを調べて、セッション オブジェクト全体ではなく、キーと値のペアを 1 つだけ操作できるかどうかを確認しました。しかし、セッションは文字列である必要があるため、これは不可能のようです:

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

何か案は?

4

1 に答える 1

3

わかりましたので、問題を解決するのに実際には役に立たなかったredisミドルウェアを使い始めました。とにかく、私は基本的にsocket.ioを介してセッションを編集するだけです(そしてクライアントが最初に接続したときに1回)ので、次のようなすべてのアクティブなセッションを含むセッション配列を作成するのが「最善」であると考えました:

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 メソッドのみ)。良いことは、同じクライアントが複数のソケットに接続している場合でも、このように機能することです。

于 2012-06-23T18:15:41.110 に答える