因爲我的能力,所寫內容較爲懶散,請多見諒。javascript
若排版亂掉,請參閱https://www.zybuluo.com/bornkiller/note/6163前端
若有錯誤,聯繫QQ:491229492,收到反饋後會儘快修正。java
// 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經常使用的數據傳輸方式,node
io.sockets.on('connection', function (socket) { });
回調函數的socket參數爲一個client
與服務器的鏈接標示,不一樣的client
會有不一樣的鏈接標示。web
socket.emitsocket.emit
信息傳輸對象爲當前socket
對應的client
,各個client socket
相互不影響。redis
socket.broadcast.emitsocket.broadcast.emit
信息傳輸對象爲全部client
,排除當前socket
對應的client
。chrome
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,客戶端操做websocket
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
鏈接須要添加權限驗證,讓已登陸的用戶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推送消息。
因爲我將Express框架和socket.io庫兩個進程,並且沒有使用redis共享數據,因此暫時不能作到session
讀取,大概5天后補上。