2012-11-22 18 views
28

我有一個Node.js網絡服務器,它運行頂層的套接字服務器,它使用Socket.io創建。基本上,這是有效的。Socket.io:Namespaces,channels&co

我現在想要實現的是,連接的客戶端是按羣組聚集的。因此,可能有一些客戶組成了組A以及組成組B的一些其他客戶。他們應該通過對特定的URL(localhost:3000/Alocalhost:3000/B)進行選擇來選擇他們屬於哪個組。

在Socket.io中,我現在想發送消息給A組中的所有客戶端,或B組中的所有客戶端或所有客戶端,而無需查看他們的組。

它基本上就像帶客房的聊天,你必須對所有客戶端或者消息的特定的房間內,或任何客戶端,不管他在哪個房間。

什麼是設計最好的辦法這樣的系統使用Socket.io?

我一直在嘗試使用命名空間到目前爲止,基本上可以創建組A和B,但是然後我失去了向所有客戶端發送消息的能力,無論他們在哪個房間。至少我沒有知道如何做到這一點。

我該如何建模?我應該尋找什麼樣的正確條款?

UPDATE:@sdedelbrock答案我可以使用命名空間或房間:

  • 如果使用命名空間,我沒多久能夠發送到每個人,不論其命名空間。這是因爲io.socketsio.of('')的快捷方式,當然這與命名空間不再匹配。
  • 這意味着我應該使用房間,但我不知道房間和名稱空間之間的語義差異是什麼。

簡而言之:爲什麼同一個(?)想法有兩個概念?

回答

29

你可能會使用的房間,所以你會做以下發出來大家都在一個房間裏

io.sockets.in('a').emit('inA', 'foo') 

然後發出來大家就可以使用

io.sockets.emit('everyone','bar'); 

您也可以使用名字空間好:

io.of('/b').emit('inB', 'buzz'); 

要發射給除觸發您將使用的用戶外的所有人:

io.sockets.broadcast.emit("hello"); 

[編輯]這裏是一個更詳細的回答:

背後名稱間距的想法是,它是從其他命名空間(甚至全球)分開處理。把它看作是一個全新的socket.io實例,你可以運行新的握手,新事件,授權等,而不會有不同的名稱空間相互干擾。

這將爲發言權/chat/tracking其中連接事件將具有非常不同的邏輯是有用的

Socket.io爲您完成所有的工作,就好像它是兩個單獨的實例,但仍限制了信息傳遞給一個連接,這非常聰明。

可能有一種解決方法,您可以在其中向所有名稱空間進行廣播(以下示例)。但總之你不應該這樣做,你應該使用房間。

for (var nameSpace in io.sockets.manager.namespaces){ 
    io.of(nameSpace).emit("messageToAll", message); 
} 
+0

我試過這個。當使用第二種方法(名稱空間)時,無論名稱空間如何,我都無法發送給每個人。這是因爲'io.sockets'是'io.of('')'的快捷方式,當然這與命名空間不再匹配。所以這意味着我應該使用房間。 無論如何,我不知道房間和命名空間之間的語義差異是什麼?爲什麼同一個(?)想法有兩個概念? –

+1

我相信這是它們可以單獨管理,但我確實發現了一個很好的寫法[Socket.io Namespaces](http://gordonkoo.com/blog/2012/02/28/under-the-hood -of-socket-io-namespaces /) – Sdedelbrock

+0

這篇文章絕對是一個很好的閱讀,但不幸的是它不能回答我的問題。我仍然不明白何時應該使用名稱空間,何時使用空間,以及它們之間的語義差異。另外:我如何向所有客戶端發送消息,而不管他們的名稱空間如何? –

4

這是你可以使用模板的應用程序(適用於9.16;對1.x的未經測試,但它應該工作):

var namespaces = [ 
    io.of('/ns1'), 
    io.of('/ns2'), 
    io.of('/ns3') 
]; 

for (i in namespaces) { 
    namespaces[i].on('connection',handleConnection(namespaces[i])); 
} 

function handleConnection(ns) { 
    return function (socket){ //connection 
    console.log("connected "); 
    socket.on('setUsername',setUsernameCallback(socket,ns));      
    socket.on('disconnect', disconnectCallback(socket,ns));       
    socket.on('messageChat',messageChatCallback(socket,ns)); 
    socket.on('createJoinRoom',createJoinRoomCallback(socket,ns)); 

    }; 
} 

function disconnectCallback(socket,ns) { 
    return function(msg){ 
    console.log("Disconnected "); 
    socket.broadcast.send("It works!"); 
    }; 
} 

你可以自己寫其他句柄:)