聞いたことがあるかもしれませんが、ソケットをセッションに保存するのではなく、ソケット認証プロセス中にサーバーに渡されるセッション cookie によってソケットを参照します。認証時にサーバーに渡されるオブジェクトのタイプの例を次に示します。
{
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
、接続ソケットのセッション Cookie を見つけることができるプロパティです。次に、認証中に Cookie を解析します。
// 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 を持つ 2 つのソケットが作成されます。
socket.on()
との使用に関する質問についてsocket.emit()
は、ソケット自体が存在しないため、接続が確立される前にそれを使用することはできません。接続されているすべてのクライアントにメッセージを送信する場合は、グローバルio.sockets
オブジェクトを使用する必要があります。それはもっと似ているでしょうio.sockets.emit()
。