socket.io學習筆記
1。伺服器資訊傳輸;
2。不分組,資料傳輸;
3。分組資料傳輸;
4。Socket.io難點大放送(暫時沒有搞定);
伺服器資訊傳輸
1. // send to current request socket client
2. socket.emit('message', "this is a test");
3. // sending to all clients except sender
4. socket.broadcast.emit('message', "this is a test");
5. // sending to all clients in 'game' room(channel) except sender
6. socket.broadcast.to('game').emit('message', 'nice game');
7. // sending to all clients, include sender
8. io.sockets.emit('message', "this is a test");
9. // sending to all clients in 'game' room(channel), include sender
10. io.sockets.in('game').emit('message', 'cool game');
11. // sending to individual socketid
12. io.sockets.socket(socketid).emit('message', 'for your eyes only');
複製程式碼
上述集中方式為socket.io常用的資料傳輸方式,
1. io.sockets.on('connection', function (socket) {
2. });
複製程式碼
回撥函式的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()。
1. io.sockets.on('connection', function (socket) {
2. socket.on('firefox', function (data) {
3. socket.join('firefox');
4. });
5. socket.on('chrome',function(data){
6. socket.join('chrome');
7. });
8. });
複製程式碼
假設有兩個聊天室,一個名為firefox,另一個為chrome,客戶端操作
socket.emit('firefox')
,就可以加入firefox聊天室;
socket.emit('chrome')
,就可以加入chrome聊天室;
向一個分組傳輸訊息,有兩種方式:
1. socket.broadcast.to('chrome').emit('event_name', data);
2. //emit to 'room' except this socket client
3. io.sockets.in('chrome').emit('event_name', data)
4. //emit to all socket client in the room
複製程式碼
broadcast方法允許當前socket client不在該分組內。 可能有一個疑問,一個socket是否可以同時存在於幾個分組,等效於一個使用者會同時在幾個聊天室活躍,答案是”可以“,socket.join()新增進去就可以了。官方提供了訂閱模式的示例:
1. socket.on('subscribe', function(data) {
2. socket.join(data.room);
3. })
4. socket.on('unsubscribe', function(data) {
5. socket.leave(data.room);
6. })
複製程式碼
後臺處理訂閱/退訂事件
1. socket = io.connect('http://127.0.0.1:1338/');
2. socket.emit('subscribe',{"room" : "chrome"};
3. socket.emit('unsubscribe',{"room" : "chrome"};
複製程式碼
前端觸發訂閱/退訂事件,就可以加入對應的聊天室。 通過of方法也可以通過劃分名稱空間的方式,實現聊天室功能,但不如分組管理來的方便。
Socket.io難點
● 授權驗證 socket連線需要新增許可權驗證,讓已登入的使用者socket連線到伺服器,未登入的使用者無條件拒絕。全域性授權管理如下:
1. io.sockets.authorization(function (handshakeData, callback) {
2. callback(null, true);
3. }).
複製程式碼
callback函式有兩個引數,第一個為error,第二個引數為是否授權bool值,通過授權回撥函式應為callback(null,true),其它情況下都為拒絕建立連線。
按照web的開發方式,檢測是否登入首選cookie-session來實現,問題也是出在這裡。websocket握手階段屬於HTTP協議,簡單來說是可以讀到cookie,就可以實現session。
精準單使用者推送
理論上來說
1. // sending to individual socketid
2. io.sockets.socket(socketid).emit('message', 'for your eyes only');
複製程式碼
就可以向一個特定使用者推送訊息,但是如何獲得這個socketId,就是生成一個雜湊陣列,key為username,值為socket.id,這樣就可以通過使用者名稱獲取對應的id,進而可以向特定client推送訊息。
由於我將Express框架和socket.io庫兩個程式,而且沒有使用redis共享資料,所以暫時不能做到session讀取,後續補上。