服務器信息傳輸
// send to current request socket client
socket.emit('message', "this is a test");
// sending to all clients except sender
socket.broadcast.emit('message', "this is a test");
// sending to all clients in 'game' room(channel) except sender
socket.broadcast.to('game').emit('message', 'nice game');
// sending to all clients, include sender
io.sockets.emit('message', "this is a test");
// sending to all clients in 'game' room(channel), include sender
io.sockets.in('game').emit('message', 'cool game');
// sending to individual socketid
io.sockets.socket(socketid).emit('message', 'for your eyes only');
上述集中方式爲socket.io常用的數據傳輸方式,
io.sockets.on('connection', function (socket) {
});
回調函數的socket參數爲一個 client
與服務器的連接標示,不同的 client
會有不同的連接標示。
不分組,數據傳輸
-
socket.emit
socket.emit
信息傳輸對象爲當前socket
對應的client
,各個client socket
相互不影響。 -
socket.broadcast.emit
socket.broadcast.emit
信息傳輸對象爲所有client
,排除當前socket
對應的client
。 -
io.sockets.emit
信息傳輸對象爲所有client
。
分組數據傳輸
類似於之前提過的 of
方法生成命名空間來管理用戶, socket.io
可以使用分組方法, socket.join()
,以及與之對應的 socket.leave()
。
io.sockets.on('connection', function (socket) {
socket.on('firefox', function (data) {
socket.join('firefox');
});
socket.on('chrome',function(data){
socket.join('chrome');
});
});
假設有兩個聊天室,一個名爲firefox,另一個爲chrome,客戶端操作
socket.emit('firefox')
,就可以加入 firefox
聊天室; socket.emit('chrome')
,就可以加入 chrome
聊天室;
向一個分組傳輸消息,有兩種方式:
socket.broadcast.to('chrome').emit('event_name', data);
//emit to 'room' except this socket client
io.sockets.in('chrome').emit('event_name', data)
//emit to all socket client in the room
broadcast
方法允許當前 socket
client
不在該分組內。
可能有一個疑問,一個 socket
是否可以同時存在於幾個分組,等效於一個用戶會同時在幾個聊天室活躍,答案是”可以“, socket.join()
添加進去就可以了。官方提供了訂閱模式的示例:
socket.on('subscribe', function(data) {
socket.join(data.room);
})
socket.on('unsubscribe', function(data) {
socket.leave(data.room);
})
後臺處理訂閱/退訂事件
socket = io.connect('http://127.0.0.1:1338/');
socket.emit('subscribe',{"room" : "chrome"};
socket.emit('unsubscribe',{"room" : "chrome"};
前端觸發訂閱/退訂事件,就可以加入對應的聊天室。 通過 of
方法也可以通過劃分命名空間的方式,實現聊天室功能,但不如分組管理來的方便。
Socket.io難點大放送(暫時沒有搞定)
- 授權驗證
socket
連接需要添加權限驗證,讓已登錄的用戶socket
連接到服務器,未登錄的用戶無條件拒絕。全局授權管理如下:
io.sockets.authorization(function (handshakeData, callback) {
callback(null, true);
}).
callback
函數有兩個參數,第一個爲 error
,第二個參數爲是否授權bool值,通過授權回調函數應爲 callback(null,true)
,其它情況下都爲拒絕建立連接。
按照web的開發方式,檢測是否登錄首選 cookie-session
來實現,問題也是出在這裏。 websocket
握手階段屬於 HTTP
協議,簡單來說是可以讀到cookie,就可以實現session。
+ 精準單用戶推送
理論上來說
// sending to individual socketid
io.sockets.socket(socketid).emit('message', 'for your eyes only');
就可以向一個特定用戶推送消息,但是如何獲得這個 socketId
,就是生成一個哈希數組,key爲username,值爲socket.id,這樣就可以通過用戶名獲取對應的id,進而可以向特定client推送消息。