Я пробовал очень много вещей, чтобы иметь возможность захватывать переменные сеанса экспресса внутри соединения socket.io в Node.JS, но продолжаю терпеть неудачу. Я заметил, что всякий раз, когда я использую промежуточное программное обеспечение сеанса, правильный сеанс не используется, вместо этого он создает 3 других бесполезных сеанса (если только saveUninitialized: true, если false, то не сохраняет его, но, конечно, использует неправильный сеанс, разумеется ).
Я пытался:
- Использование cookie-парсера.
- Сохранение сессии в файле.
- экспресс-Socket.io-сессию.
- Redis
- и несколько других вещей, которые я больше не могу вспомнить.
Но все сводится к одному: сокет не использует тот же сеанс, что и экспресс-запрос (req.session), вместо этого он создает 3 других сеанса, а также продолжает создавать новые при работе с сокетом.
Настройка клиента socket.io внутри компонента приложения:
componentWillMount() {
let socket = io("http://localhost:5000");
this.setState({socket});
socket.emit("test"); // This actually returns the correct session.
}
Пример способа отправки AJAX в ReactJS:
fetch('http://localhost:5000/home/userinfo', {
method: 'GET',
credentials: 'include',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
}).then(function(response) {
return response.json();
}).then(function(data) {
if (data.login) {
self.setState({username: data.login});
}
else {
self.props.history.push("/login");
}
});
экспресс-сессия:
var sessionMiddleware = session({
store: new sessionFileStore({ path: './sessions' }),
secret: 'nothingspecial',
maxAge: new Date(Date.now() + 3600000),
resave: true,
saveUninitialized: false
});
app.use(sessionMiddleware);
соединение socket.io:
const server = app.listen(port, () => console.log(`Listening on port ${port}`));
const io = require('socket.io').listen(server);
io.use(function(socket, next) {
sessionMiddleware(socket.handshake, {}, next);
});
io.on('connection', function(socket) {
console.log('a user connected');
socket.on('disconnect', function() {
console.log('user disconnected');
});
socket.on('test', function() {
console.log(socket.handshake.session);
// Returns different session than when using app.get and then req.session for example
});
});
Также некоторые другие app.use, которые стоит опубликовать здесь:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
С удовольствием оценил бы помощь, поскольку я уже потратил столько времени, пытаясь это выяснить.
Редактировать: я заметил, что при обновлении страницы, когда я запускаю socket.emit прямо из того места, где начинается соединение (компонент приложения), он фактически захватывает нужный сеанс.
Я пытался создать некоторые функции внутри компонента App, но все же, когда я передаю функцию в другой компонент и запускаю функцию props, она создает новый сеанс.
Как мне передать сокет:
<Route path="/home" render={(props) => <Home {...props} socket={this.state.socket} />} />