[英]socket.io and session?
我正在使用快速框架。 我想從 socket.io 訪問會話數據。 我嘗試使用 client.listener.server.dynamicViewHelpers 數據表達 dynamicHelpers,但我無法獲取會話數據。 有沒有一種簡單的方法可以做到這一點? 請看代碼
app.listen(3000);
var io = require('socket.io');
var io = io.listen(app);
io.on('connection', function(client){
// I want to use session data here
client.on('message', function(message){
// or here
});
client.on('disconnect', function(){
// or here
});
});
這不適用於通過 flashsocket 傳輸的套接字(它不會向服務器發送所需的 cookie),但它可靠地適用於其他一切。 我只是在我的代碼中禁用了 flashsocket 傳輸。
為了使其工作,在快速/連接端,我明確定義了會話存儲,以便我可以在套接字內使用它:
MemoryStore = require('connect/middleware/session/memory'),
var session_store = new MemoryStore();
app.configure(function () {
app.use(express.session({ store: session_store }));
});
然后在我的套接字代碼中,我包含了連接框架,以便我可以使用它的 cookie 解析從 cookie 中檢索 connect.sid。 然后我在會話存儲中查找具有 connect.sid 的會話,如下所示:
var connect = require('connect');
io.on('connection', function(socket_client) {
var cookie_string = socket_client.request.headers.cookie;
var parsed_cookies = connect.utils.parseCookie(cookie_string);
var connect_sid = parsed_cookies['connect.sid'];
if (connect_sid) {
session_store.get(connect_sid, function (error, session) {
//HOORAY NOW YOU'VE GOT THE SESSION OBJECT!!!!
});
}
});
然后,您可以根據需要使用會話。
我建議不要完全重新發明輪子。 你需要的工具已經是一個 npm 包了。我想這就是你需要的: session.socket.io我最近在用它,我猜它會很有幫助!! 將 express-session 鏈接到 socket.io 層會有很多好處!
編輯:在嘗試了一些不起作用的模塊后,我實際上已經編寫了自己的庫來做到這一點。 無恥的插件:去https://github.com/aviddiviner/Socket.IO-sessions看看吧。 出於歷史目的,我將在下面留下我的舊帖子:
我非常巧妙地完成了這項工作,而無需按照pr0zac上面的解決方案繞過flashsocket傳輸。 我也在 Socket.IO 中使用 express。 這是如何。
首先,將會話 ID 傳遞給視圖:
app.get('/', function(req,res){
res.render('index.ejs', {
locals: {
connect_sid: req.sessionID
// ...
}
});
});
然后在您的視圖中,將其與 Socket.IO 客戶端鏈接:
<script>
var sid = '<%= connect_sid %>';
var socket = new io.Socket();
socket.connect();
</script>
<input type="button" value="Ping" onclick="socket.send({sid:sid, msg:'ping'});"/>
然后在您的服務器端 Socket.IO 偵聽器中,拿起它並讀取/寫入會話數據:
var socket = io.listen(app);
socket.on('connection', function(client){
client.on('message', function(message){
session_store.get(message.sid, function(error, session){
session.pings = session.pings + 1 || 1;
client.send("You have made " + session.pings + " pings.");
session_store.set(message.sid, session); // Save the session
});
});
});
就我而言,我的session_store
是 Redis,使用redis-connect
庫。
var RedisStore = require('connect-redis');
var session_store = new RedisStore;
// ...
app.use(express.session({ store: session_store }));
希望這可以幫助那些在搜索谷歌時找到這篇文章的人(就像我一樣;)
請參閱: Socket.IO 身份驗證
我建議不要通過client.request...
或client.listener...
獲取任何內容,因為它沒有直接附加到client
對象,並且始終指向最后登錄的用戶!
您可以使用express-socket.io-session 。
與 socket.io 共享一個基於 cookie 的 express-session 中間件。 適用於 express > 4.0.0 和 socket.io > 1.0.0,並且不會向后兼容。
為我工作!!
查看Socket.IO-connect
圍繞 Socket.IO-node 連接 WebSocket 中間件包裝器https://github.com/bnoguchi/Socket.IO-connect
這將允許您在使用 Socket.IO 事件處理程序處理它之前將 Socket.IO 請求向下推送到 Express/Connect 中間件堆棧,從而使您可以訪問會話、cookie 等。 雖然,我不確定它是否適用於所有 Socket.IO 的傳輸。
你可以看看這個: https : //github.com/bmeck/session-web-sockets
或者,您可以使用:
io.on('connection', function(client) {
var session = client.listener.server.viewHelpers;
// use session here
});
希望這會有所幫助。
我不確定我做對了。 https://github.com/LearnBoost/socket.io/wiki/Authorizing
通過握手數據,您可以訪問 cookie。 在 cookie 中,您可以獲取 connect.sid,它是每個客戶端的會話 ID。 然后使用 connect.sid 從數據庫中獲取會話數據(我假設您正在使用 RedisStore)
對於未來的讀者 - 有一種優雅而簡單的方法可以使用 express-session 訪問 socket.io 中的會話。 來自 socket.io 文檔:
大多數現有的 Express 中間件模塊應該與 Socket.IO 兼容,您只需要一個小包裝函數來使方法簽名匹配:
const wrap = middleware => (socket, next) => middleware(socket.request, {}, next);
但是,結束請求-響應周期且不調用 next() 的中間件函數將無法工作。
快速會話示例:
const session = require("express-session");
io.use(wrap(session({ secret: "cats" })));
io.on("connection", (socket) => {
const session = socket.request.session; // here you get access to the session :)
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.