2013-07-04 185 views
62

我從socket.io + node.js開始,我知道如何在本地發送消息並廣播socket.broadcast.emit()函數: - 所有連接的客戶端都收到同樣的信息。如何使用socket.io發送消息給特定客戶端

現在,我想知道如何發送私人消息到一個特定的客戶端,我的意思是一個私人聊天2人(客戶端到客戶端流)之間的套接字。謝謝。

+0

對不起psiphi75,但這個鏈接沒有回覆我的答案,不是一個重複的問題。 –

+1

@ psiphi75,這是不可重複的 – softvar

+1

無法忍受像@psiphi這樣的人。你甚至是開發者嗎? HTML5特定問題如何與獨立庫相關聯?對於它的價值,WebSockets不是Socket.io。 Socket.io是一個可以使用WebSocket的庫,但我離題了。這也是一個更具體的與圖書館有關僅向特定客戶端發送數據的問題,而不是技術本身。 –

回答

74

當用戶連接時,它應該發送一條消息到服務器,用戶名必須是唯一的,比如電子郵件。

一對用戶名和插座的應當被存儲在一個對象是這樣的:

var users = { 
    '[email protected]': [socket object], 
    '[email protected]': [socket object], 
    '[email protected]': [socket object] 
} 

在客戶端,發射一個目的是在服務器與以下數據:

{ 
    to:[the other receiver's username as a string], 
    from:[the person who sent the message as string], 
    message:[the message to be sent as string] 
} 

在服務器,聽取消息。收到消息時,將數據發送給接收方。

users[data.to].emit('receivedMessage', data) 

在客戶端,監聽發射來自被稱爲「receivedMessage」服務器,並通過讀取誰它是從哪裏來的,你可以處理的數據和發送的消息。

+18

如果您使用此解決方案,那麼您必須瞭解: 1.當用戶斷開連接時,您必須清理'用戶'對象 2.它不支持第二個連接 - 例如從另一個瀏覽器。因此,如果用戶從其他瀏覽器連接 - 舊連接將被覆蓋。 –

+1

如何將套接字對象存儲在數據存儲中?我假設這不起作用,如果你有多個節點進程。 – chovy

+0

@chovy你必須使用redis。檢查此https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO –

8

您可以參考socket.io rooms。 握手套接字 - 您可以將其加入到命名空間,例如「user。#{userid}」。

之後,你可以方便的名義發送悄悄話給任何客戶端,例如:

io.sockets.in( 'user.125')發射( 'new_message',{文字: 「Hello world」})

在上面的操作中,我們向用戶「125」發送「new_message」。

謝謝。

+0

大家好,感謝您的第一個答案,我會嘗試一下,讓你知道這一點,因爲我不想建立一個聊天,而是一個私人信使,就像你可以在Facebook上使用一樣。 –

+0

有人可以幫我解決這個問題,我真的被困住了,我想添加一個用戶名和我的套接字連接,並允許我的應用程序向特定用戶發送消息,沒有聊天室,這是一個類似Messenger的Facebook。謝謝,如果你知道! –

+0

首先你必須明白,這個用戶名在所有用戶中必須是唯一的。第二個 - 你不忘記在客戶端訂閱發出的消息嗎? –

172

您可以使用socket.io房間。從客戶端發出一個事件(在這種情況下,「加入」,可以是任何東西)與任何唯一的標識符(電子郵件,ID)。

客戶端:現在

var socket = io.connect('http://localhost'); 
socket.emit('join', {email: [email protected]}); 

,從服務器端使用該信息來爲該用戶創建

服務器端的獨特房間:

var io = require('socket.io').listen(80); 

io.sockets.on('connection', function (socket) { 
    socket.on('join', function (data) { 
    socket.join(data.email); // We are using room of socket io 
    }); 
}); 

所以,現在每個用戶已加入以用戶電子郵件命名的房間。所以,如果你想發送特定用戶的消息,你只需要

服務器端:

io.sockets.in('[email protected]').emit('new_msg', {msg: 'hello'}); 

最後剩下的事就在客戶端被聽「new_msg」事件。

客戶端:

socket.on("new_msg", function(data) { 
    alert(data.msg); 
} 

我希望你的想法。

+0

客戶端看起來不會被綁定到特定的房間。 – chovy

+0

客戶端不必知道房間,您的服務器將您的客戶訂閱到特定房間。客戶只需要聽取事件,服務器端確保客戶端獲得客戶訂閱的房間的事件。 – az7ar

+2

請更改此行io.socket.in('[email protected]')。emit('new_msg',{msg:'hello'});像這樣io.sockets.in('[email protected]')。emit('new_msg',{msg:'hello'}); – silvesterprabu

1

在我們公司的一個項目,我們使用的是「房」的方式,它的名字是在交談的唯一標識符的所有用戶的用戶ID的組合(我們的實現更喜歡Facebook的信使),例如:

| id |名稱 | 1 | Scott | 2 |蘇珊

「房間」的名字將是「1-2」(IDS排序升序)和斷開socket.io自動清理房間

這樣您發送郵件只是爲了那個房間只在線(已連接)用戶(在整個服務器中發送的軟件包較少)。

15

肯定的: 簡單,

這是你所需要的:

io.to(socket.id).emit("event", data); 

每當用戶連接到服務器時,會產生插座細節,包括ID。這個ID確實有助於向特定的人發送消息。

首先我們需要所有的socket.ids存儲陣列,

var people={}; 

people[name] = socket.id; 

這裏的名字是接收器名稱。 例子:

people["ccccc"]=2387423cjhgfwerwer23; 

所以,現在我們可以得到,每當我們發送消息時,接收者名稱socket.id:

爲此,我們需要知道receivername。您需要將接收者名稱發送到服務器。

最後一件事是:

socket.on('chat message', function(data){ 
io.to(people[data.receiver]).emit('chat message', data.msg); 
}); 

希望這會很適合你。

祝您好運!

+0

這個工程。謝謝 – yasiriqbal776

+0

您可以創建客戶端和服務器端代碼嗎?我是scoket編程的新手。 [email protected] –

+0

@HARISH,請參考下面的鏈接,說明客戶端真的發生了什麼..我希望這可以幫助你更多..http://socket.io/get-started/chat/ – Trojan

相關問題