Ответ 1
Мне нужно указать, что вы неправильно добавляете в приложение промежуточное ПО. Вызов app.use
не должен выполняться в обработчике запроса app.get
, но за его пределами. Просто позвоните им непосредственно после createServer
или посмотрите другие примеры в документах.
Секрет, который вы передаете в express.session
, должен быть строковой константой или, возможно, чем-то взятым из файла конфигурации. Не кормите его тем, что может знать клиент, что на самом деле опасно. Это секрет, о котором должен знать только сервер.
Если вы хотите сохранить адрес электронной почты в сеансе, просто выполните что-то по строкам:
req.session.email = req.param('email');
С этим в сторону...
Если я правильно понимаю, то, что вы пытаетесь сделать, это обработать один или несколько HTTP-запросов и отслеживать сеанс, а затем открыть соединение Socket.IO, из которого вам нужны данные сеанса.
Какая сложность в этой проблеме заключается в том, что средство Socket.IO для создания волшебной работы над любым http.Server
заключается в захвате события request
. Таким образом, Express '(или, скорее, Connect), промежуточное ПО сеанса никогда не вызывается в соединении Socket.IO.
Я считаю, что вы можете сделать эту работу, хотя, с некоторыми обманами.
Вы можете получить данные сеанса Connect; вам просто нужно получить ссылку на хранилище сеансов. Самый простой способ сделать это - создать магазин перед вызовом express.session
:
// A MemoryStore is the default, but you probably want something
// more robust for production use.
var store = new express.session.MemoryStore;
app.use(express.session({ secret: 'whatever', store: store }));
Каждое хранилище сеансов имеет метод get(sid, callback)
. Параметр sid
или идентификатор сеанса хранится в файле cookie на клиенте. По умолчанию для этого файла cookie указано connect.sid
. (Но вы можете дать ему любое имя, указав опцию key
в своем вызове express.session
.)
Затем вам нужно получить доступ к этому файлу cookie в соединении Socket.IO. К сожалению, Socket.IO, похоже, не дает вам доступ к http.ServerRequest
. Простая работа заключалась бы в том, чтобы получить cookie в браузере и отправить его через соединение Socket.IO.
Код на сервере будет выглядеть примерно так:
var io = require('socket.io'),
express = require('express');
var app = express.createServer(),
socket = io.listen(app),
store = new express.session.MemoryStore;
app.use(express.cookieParser());
app.use(express.session({ secret: 'something', store: store }));
app.get('/', function(req, res) {
var old = req.session.email;
req.session.email = req.param('email');
res.header('Content-Type', 'text/plain');
res.send("Email was '" + old + "', now is '" + req.session.email + "'.");
});
socket.on('connection', function(client) {
// We declare that the first message contains the SID.
// This is where we handle the first message.
client.once('message', function(sid) {
store.get(sid, function(err, session) {
if (err || !session) {
// Do some error handling, bail.
return;
}
// Any messages following are your chat messages.
client.on('message', function(message) {
if (message.email === session.email) {
socket.broadcast(message.text);
}
});
});
});
});
app.listen(4000);
Предполагается, что вы хотите читать только существующий сеанс. Вы не можете создавать или удалять сеансы, потому что соединения Socket.IO могут не иметь ответа HTTP для отправки заголовка Set-Cookie
(думаю, WebSockets).
Если вы хотите редактировать сеансы, это может работать с некоторыми хранилищами сеансов. Например, CookieStore не работает, потому что ему также необходимо отправить заголовок Set-Cookie
, который он не может. Но для других магазинов вы можете попробовать вызвать метод set(sid, data, callback)
и посмотреть, что произойдет.