Redis, Node.js und Socket.io: Serverübergreifende Authentifizierung und das Verständnis von node.js

Ich habe eine einseitige Anwendung auf Rails und Backbone.js ausgeführt. Ich verwende Node.js über Redis, um Daten an Clients zu senden und zu synchronisieren. Ich versuche die Sockets-Kommunikation zu verstehen, zu sichern und zu optimieren.

Beim Schreiben mit console.log werden einige Protokollzeilen angezeigt (console.log('Redis connection on ..')) werden dupliziert (siehe unten).

Kann mir jemand erklären warum? Gibt es bestimmte Verhaltensweisen von Node.js, die ich aufgrund meiner Code-Implementierung nicht verstehe?

Hier ist mein Node.js Code:

var io = require('socket.io').listen(3003);
var redis = require('redis');
var cookie = require("cookie");
var redis_subs = redis.createClient(6379, "localhost");
var redis_auth = redis.createClient(6379, "localhost");
var authenticated = false;

var authentication_status = function (status) {
  if (status === true) {
    console.log('Authentication status is true.');
  }
  else {
    console.log('Authentication status is false.');
  }
  authenticated = status;
};

redis_subs.subscribe('application_channel');

io.configure(function () {
  io.set('authorization', function (data, callback) {
    console.log('Cross authentication...');
    if (data.headers.cookie) {
      data.cookie = cookie.parse(data.headers.cookie);
      data.sessionID = data.cookie['_validation_token_key'];
      redis_auth.hget(["sessionStore", data.sessionID], function (err, session) {
        if (err || !session) {
          console.log('Socket.io authorization say false');
          return callback(authentication_status(false), false);
        }
        else {
          data.session = JSON.parse(session);
          console.log('Socket.io authorization say true');
          return callback(authentication_status(true), true);
        }
      });
    }
    else {
      console.log('Socket.io authorization say false');
      return callback(authentication_status(false), false);
    }
  });
});

io.on('connection', function(socket){
    if (socket.handshake.session) {
      var user_socket_channel = socket.handshake.session['user_socket_channel']
      redis_subs.on('message', function(redis_channel, rawdata) {
        console.log('Redis connection on '+redis_channel);
        console.log('Handshaked Session, authenticated user. All channels allowed.');
        var data = JSON.parse(rawdata);
        if (data.channel) { var socket_channel = data.channel; }
        else { var socket_channel = user_socket_channel; }
        var rails_data = data.data;
        console.log('Socket.io emiting on ['+socket_channel+']')
        socket.emit(socket_channel, rails_data);
      });
    }
    else {
      redis_subs.on('message', function(redis_channel, rawdata) {
        console.log('Redis connection on '+redis_channel);
        console.log('No handshaked Session, unauthenticated user. Public channels allowed.');
        var data = JSON.parse(rawdata);
        var rails_data = data.data;
        console.log('Socket.io emiting on [public]')
        socket.emit('public', rails_data);
      });
    }
});

Hier ist die Art und Weise, wie ich es teste, und der spezielle Anwendungsfall, in dem das Protokoll doppelt vorhanden ist:

Laden der Seite, während Sie angemeldet sind, mit dem Webbrowser1 (z. B. Firefox); Ausgabe:

   info  - socket.io started
Cross authentication...
Socket.io authorization say true
Authentication status is true.
   debug - authorized
   info  - handshake authorized bJxm_IcWl2mKZT4Ed-kV
   debug - setting request GET /socket.io/1/websocket/bJxm_IcWl2mKZT4Ed-kV
   debug - set heartbeat interval for client bJxm_IcWl2mKZT4Ed-kV
   debug - client authorized for 
   debug - websocket writing 1::

Laden derselben Seite, die mit browser2 abgemeldet wurde (z. B. Chrome)

Cross authentication...
Socket.io authorization say false
Authentication status is false.
   debug - authorized
   info  - handshake unauthorized

Senden von Daten über page / browser1 (Firefox) -> Rails -> Redis, Ausgabe:

Redis connection on application_channel
Handshaked Session, authenticated user. All channels allowed.
Socket.io emiting on [hLTYXuvP+13aQlIT9CZiYc1i9eg=]
   debug - websocket writing 5:::{"name":"hLTYXuvP+13aQlIT9CZiYc1i9eg=","args":[null]}

Erneutes Laden der Seite in Browser2 (Chrome, abgemeldet), wird weiterhin ausgegeben

Cross authentication...
Socket.io authorization say false
Authentication status is false.
   debug - authorized
   info  - handshake unauthorized

Das Neuladen der Seite in Browser1 / Firefox und das Weiterleiten weiterer Daten an Redis über die Seite und Rails, Ausgabe:

Redis connection on application_channel
Handshaked Session, authenticated user. All channels allowed.
Socket.io emiting on [hLTYXuvP+13aQlIT9CZiYc1i9eg=]
Redis connection on application_channel
Handshaked Session, authenticated user. All channels allowed.
Socket.io emiting on [hLTYXuvP+13aQlIT9CZiYc1i9eg=]
   debug - websocket writing 5:::{"name":"hLTYXuvP+13aQlIT9CZiYc1i9eg=","args":[null]}

Wie Sie sehen, wurde das Ereignis dupliziert, und der Redis-Listener erkennt jetzt zwei Verbindungen. Jedes Mal, wenn ich page1 / Firefox neu lade, wird es noch einmal dupliziert (3,4,5 ...).

Ich verstehe dieses Verhalten nicht. Was vermisse ich? Übrigens, wie Sie sehen, verstehe ich auch das Ziel von Socket.io nicht wirklichconfigure, set authorization undcallbackRückgabe von true oder false, wenn Node erreichtio.on('connection') und Redis Zuhörer trotzdem.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage