網上查閱了 socket.io 官方文檔,彷佛沒有發現最新的中文文檔,有舊的,好比這個 (socket.io 中文文檔) 是 2017 年的。redis
官網的實例和網上絕大多數入門例子,幾乎都同樣,就一個羣聊窗口,過於簡單。這讓不少有志於socket.io 學習的人不那麼方便,這裏翻譯一篇官網的 socket.io 關於 namespace 和rooms 的文檔,但願對你們有點幫助。如須要查閱的人多,再考慮翻譯其它節。服務器
原文地址:Rooms and Namespaces異步
如下爲譯文socket
socket.io 容許你將socket 制定不一樣的命名空間,本質上,就是指定不一樣的 終點(endpoint) 或 路徑(path)tcp
這是個有用的特性,它能減小所需資源數目(tcp 鏈接數),同時,它經過隔離通訊信道(通道 channel)達到隔離應用的多個部分函數
咱們使用默認命名空間 / ,它既是socket.io 客戶端默認鏈接也是服務端默認監聽的的命名空間。
ns 經過 io.sockets 或 簡以 io 調用加以區分:工具
// the following two will emit to all the sockets connected to `/` io.sockets.emit('hi', 'everyone'); io.emit('hi', 'everyone'); // short form
每一個ns 都會觸發一 connection 事件,並以 socket 做爲參數傳遞到事件響應中學習
io.on('connection', function(socket){ socket.on('disconnect', function(){ }); });
若是要設置一個自定義ns,你可再服務端調用 of 函數:ui
const nsp = io.of('/my-namespace'); nsp.on('connection', function(socket){ console.log('someone connected'); }); nsp.emit('hi', 'everyone!');
在客戶端,你能夠告知 socket.io 客戶端鏈接到對應的nsconst socket = io('/my-namespace');
socket.io
重要提示:ns 僅是 socket.io 協議的實現細節,它和實際 URL 所表示的底層傳輸並沒有關係,如: /socket.io/...
在每一個ns 內,你能夠定義專屬通道供, 這些sockets 能夠 join 和 leave
你能夠經過調用 join 函數 讓 socket 訂閱一個指定通道
io.on('connection', function(socket){ socket.join('some room'); });
而後,在廣播或者分發時能夠簡單的使用 to 或者 in (二者等同)io.to('some room').emit('some event');
若是要離開通道,你能夠像調用 join同樣而調用 leave。 這兩個方法都是異步的,接受 callback 做用參數
在socket.io中,每一個socket都會以一個 隨機的、不可測的惟一標識 socket#id 區分。 爲了方便,每一個socket又會自動的經過這個標識id加入到一個房間。
這樣讓廣播一個消息到其它sockets 很方便:
io.on('connection', function(socket){ socket.on('say to someone', function(id, msg){ socket.broadcast.to(id).emit('my message', msg); }); });
對應鏈接斷開,socket 或自動的 leave 全部通道,並不須要你作其它處理
有時,你可能須要在socket.io 進程上下文以外向你的 socket.io ns / rooms 中的sockets 分發事件
有一些方式能夠處理這種問題,好比實現本身的通道從而向進程發送消息
爲了簡化此種狀況,咱們建立了兩個模塊
經過實踐redis 適配器:
const io = require('socket.io')(3000); const redis = require('socket.io-redis'); io.adapter(redis({ host: 'localhost', port: 6379 }));
而後你就能從其餘進程 emit 消息到任意通道
const io = require('socket.io-emitter')({ host: '127.0.0.1', port: 6379 }); setInterval(function(){ io.emit('time', new Date); }, 5000);
以上爲翻譯全文
幸虧本節不長內容很少,翻譯一個小時左右。對於文章尾部 「從進程外發送消息」,這個例子和說明不是很清晰,這裏再補充下:
socket.io-redis 和 socket.io-emitter 是兩個獨立的模塊,它們並不必定要組合使用。
對於實際的生產環境,咱們的socket.io 服務多是集羣部署,使用多個進程或者在多個服務器,在某一進程 emit 如何讓其它進程上的客戶端也能收到? 此時 socket.io-redis 就是一有效工具,它經過 redis自己自帶的 Pub/Sub 機制,達到也向其它進程上的客戶端廣播消息的目的。
而 socket.io-emmitter 纔是徹底從其它非socket.io 進程發送消息到socket.io 進程所要依賴的,同時結合 socket.io-redis 使用。