Socket.io ile belirli bir istemciye nasıl mesaj gönderilir


97

Socket.io + node.js ile başlıyorum, yerel olarak bir mesaj göndermeyi ve socket.broadcast.emit()işlevi yayınlamayı biliyorum : - bağlı tüm istemciler aynı mesajı alır.

Şimdi, belirli bir istemciye nasıl özel mesaj göndereceğimi öğrenmek istiyorum, yani 2 kişi arasında özel bir sohbet için bir yuva (İstemciden-İstemciye akış). Teşekkürler.


Üzgünüm psiphi75 ama bu bağlantı cevabıma cevap vermiyor, yinelenen bir soru değil.
Nizar B.

1
@ psiphi75, kopya
olamaz

1
İnsanlara @psiphi gibi katlanamıyorum. Hatta bir geliştirici misin? HTML5'e özgü bir soru bağımsız bir kitaplıkla nasıl ilişkilidir? Ve değeri ne olursa olsun, WebSocket'ler Socket.io DEĞİLDİR. Socket.io, WebSockets KULLANABİLEN bir kitaplıktır, ancak konu dışına çıkıyorum. Bu aynı zamanda kütüphaneyle ilgili, teknolojinin kendisi hakkında değil, yalnızca belirli istemcilere veri gönderme ile ilgili daha spesifik bir sorudur.
Levi Roberts


@ bugwheels94 Pek sayılmaz, bu gönderi 2011'den ve nodejs kod açısından pek çok değişiklik yaptığından beri. bu gönderi, bu konu için kesinlikle geçerli bir soru / cevaptır.
Nizar B.

Yanıtlar:


102

Bir kullanıcı bağlandığında, sunucuya e-posta gibi benzersiz olması gereken bir kullanıcı adıyla bir mesaj göndermelidir.

Bir çift kullanıcı adı ve soket aşağıdaki gibi bir nesnede saklanmalıdır:

var users = {
    'userA@example.com': [socket object],
    'userB@example.com': [socket object],
    'userC@example.com': [socket object]
}

İstemcide, aşağıdaki verilerle sunucuya bir nesne gönderin:

{
    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]
}

Sunucuda mesajları dinleyin. Bir mesaj alındığında, verileri alıcıya iletin.

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

İstemcide, 'ReceivedMessage' adlı sunucudan gelen gönderileri dinleyin ve verileri okuyarak, kimin geldiği ve gönderilen mesajı idare edebilirsiniz.


28
Bu çözümü kullanırsanız, şunu anlamalısınız: 1. Kullanıcı bağlantısı kesildiğinde, 'kullanıcılar' nesnesini temizlemeniz gerekir 2. İkinci bağlantıyı desteklemez - örneğin başka bir tarayıcıdan. Bu nedenle, kullanıcı başka bir tarayıcıdan bağlanırsa - eski bağlantı geçersiz kılınır.
Vladimir Kurijov

1
soket nesnesini bir veri deposunda nasıl saklarsınız? Birden fazla düğüm işleminiz varsa bunun işe yaramayacağını varsayıyorum.
chovy

@chovy redis kullanmanız gerekiyor. Bunu kontrol edin github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO
Vladimir Kurijov

11
Bu çözümü kullanmamayı öneririm. Bu yaklaşımın sınırlamalarının üstesinden gelmek için çok zaman harcadım. Bkz az7ar çözümüyle @ ve bu daha iyidir neden için açıklama .
Daniel Que

@DanielQue +1. Yerel işlevselliği kullanmanın daha iyi yolu. Teşekkürler!
Aaron Lelevier

280

Socket.io odalarını kullanabilirsiniz. İstemci tarafından, herhangi bir benzersiz tanımlayıcıyla (e-posta, kimlik) bir olay (bu durumda "katılma" herhangi bir şey olabilir) yayınlayın.

İstemci Tarafı:

var socket = io.connect('http://localhost');
socket.emit('join', {email: user1@example.com});

Şimdi, sunucu tarafında bu bilgileri o kullanıcı için benzersiz bir oda oluşturmak için kullanın

Sunucu Tarafı:

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
  });
});

Artık her kullanıcı, kullanıcının e-postasının adını taşıyan bir odaya katıldı. Dolayısıyla, belirli bir kullanıcıya mesaj göndermek istiyorsanız, yapmanız gereken

Sunucu Tarafı:

io.sockets.in('user1@example.com').emit('new_msg', {msg: 'hello'});

İstemci tarafında yapılacak son şey "new_msg" olayını dinlemektir.

İstemci Tarafı:

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

Umarım anlarsın.


3
lütfen bu satırı değiştirin io.socket.in ('kullanıcı1@example.com'). emit ('yeni_msg', {msg: 'merhaba'}); bunun gibi io.sockets.in ('kullanıcı1@example.com'). emit ('yeni_msg', {msg: 'merhaba'});
silvesterprabu

44
Bu cevap, şu anda kabul edilen cevaptan çok daha iyidir. İşte nedeni: 1) Global istemciler dizisini yönetmeniz ve temizlemeniz gerekmez. 2) Bir kullanıcının aynı sayfada birden çok sekmesi açık olsa bile çalışır. 3) Bir düğüm kümesi (çoklu süreçler) ile çalışmak için kolayca genişletilebilir socket.io-redis.
Daniel Que

2
{email: user1@example.com}Uygulamaya giden tüm istemcilerin kullanıcısı user1@example.comolmasaydı tüm bağlantılar için nasıl farklı hale user2@example.comgetirebilirsiniz, farklı odalara sahip olabilmem için bağlanan ikinci istemciyi nasıl kullanırım? bu can sıkıcı bir soruysa özür dilerim.
jack blank

2
çözümü sevdim, ancak burada güvenliğin tehlikeye girdiğine inanıyorum. İstemci tarafındaki komut dosyasındaki e-postayı değiştirirsem ne olur? Artık diğer özel mesajları da okuyabiliyorum. Ne diyorsun?
Gopinath Shiva

3
e-posta olmak zorunda değil Herhangi bir benzersiz tanımlayıcıdan bahsettim
az7ar

34

EMİN: Basitçe,

İhtiyacın olan şey bu :

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

ne zaman bir kullanıcı sunucuya katılırsa, kimlik dahil soket detayları üretilecektir. Bu kimlik, belirli kişilere bir mesaj göndermeye gerçekten yardımcı olur.

önce tüm socket.ids'leri dizide saklamamız gerekir,

var people={};

people[name] =  socket.id;

buradaki isim alıcının adıdır. Misal:

people["ccccc"]=2387423cjhgfwerwer23;

Böylece, şimdi mesaj gönderirken alıcı adıyla bu socket.id'i alabiliriz:

bunun için alıcı adını bilmemiz gerekiyor. Sunucuya alıcı adını vermeniz gerekir.

son şey:

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

Umarım bu sizin için iyi sonuç verir.

İyi şanslar!!


İstemci tarafı ve sunucu tarafı kodu oluşturabilir misiniz? Scoket programlamada yeniyim. hmahajan.dmi@gmail.com
Harish Mahajan

@HARISH, aşağıdaki bağlantıya bakın, istemci tarafında gerçekte neler olduğunu açıklar .. umarım bu size daha fazla yardımcı olur .. socket.io/get-started/chat
Trojan

2
Peki ya kullanıcı aynı anda 2 kişiyle sohbet ediyorsa? Her iki kullanıcıdan gelen mesaj her iki pencereye de gelmeyecek mi?
Sharan Mohandas


kullanıcılar her bağlandığında soket kimliği değişikliklerini değiştirdiğinde, kullanıcı uygulamanızı birden fazla sekmede açarsa, sizin sakladığınız ve diğer soket bağlantılarına gönderdiğiniz bir tanesine yanıt alacaktır
Vikas Kandari

8

Socket.io odalarına başvurabilirsiniz . El sıkıştığında soket - adlandırılmış odaya katılabilirsiniz, örneğin "user. # {Userid}".

Bundan sonra, herhangi bir istemciye uygun bir adla özel mesaj gönderebilirsiniz, örneğin:

io.sockets.in ('user.125'). emit ('new_message', {text: "Merhaba dünya"})

Yukarıdaki işlemde, "125" kullanıcısına "new_message" gönderiyoruz.

Teşekkürler.


Merhaba dostum, ilk cevabın için teşekkürler, deneyeceğim ve sana bunu bildireceğim, çünkü bir sohbet oluşturmak istemiyorum ama Facebook ağında kullanabileceğin gibi özel bir mesajlaşma uygulaması.
Nizar B.

Birisi bana bu konuda yardımcı olabilir mi, gerçekten takıldım, soketime bağlı bir kullanıcı adı eklemek ve uygulamamın belirli bir kullanıcıya mesaj göndermesine izin vermek istiyorum, sohbet odası yok, bu bir Facebook benzeri messenger. Biliyorsanız teşekkürler!
Nizar B.

İlk önce bu kullanıcı adının tüm kullanıcılar için benzersiz olması gerektiğini anlamalısınız. Ve ikincisi - müşteri tarafında yayınlanan mesajlara abone olmayı unutmadınız mı?
Vladimir Kurijov

Bununla ilgili sorun, yayınlarda izin verilmediğinden geri aramaları kullanma yeteneğinizi kaybetmenizdir, burada gerçekten yaptığınız şey, onun özel odasında bir yayın.
bluehallu

@VladimirKurijov, Bay Katcha Odaları kullanmak istemiyor ve sorununun çözümü olmadığını kabul ediyorum.
miksiii

4

Şirketimizin bir projesinde "odalar" yaklaşımını kullanıyoruz ve adı, benzersiz bir tanımlayıcı olarak bir görüşmedeki tüm kullanıcıların kullanıcı kimliklerinin bir kombinasyonudur (bizim uygulamamız daha çok facebook messenger'a benzer), örnek:

| id | isim | 1 | Scott | 2 | Susan

"oda" adı "1-2" olacaktır (kimlikler Asc. sıralanır) ve bağlantı kesildiğinde socket.io odayı otomatik olarak temizler

bu şekilde yalnızca o odaya ve yalnızca çevrimiçi (bağlı) kullanıcılara mesaj gönderirsiniz (sunucuya daha az paket gönderilir).


3

As az7ar cevap güzelce dedi ama Let edilir beni socket.io odalı kadar kolaylaştırır. bir sunucuya katılmak için benzersiz bir tanımlayıcıya sahip bir sunucu talep edin. burada benzersiz bir tanımlayıcı olarak bir e-posta kullanıyoruz.

İstemci Soketi.io

socket.on('connect', function () {
  socket.emit('join', {email: user@example.com});
});

Kullanıcı bir sunucuya katıldığında, o kullanıcı için bir oda oluşturun

Sunucu Soketi.io

io.on('connection', function (socket) {
   socket.on('join', function (data) {    
    socket.join(data.email);
  });
});

Şimdi hepimiz katılmaya hazırız. sunucu toodasından bir şeyler yaymasına izin verin , böylece kullanıcı dinleyebilir.

Sunucu Soketi.io

io.to('user@example.com').emit('message', {msg: 'hello world.'});

messageMüşteri tarafını dinleyerek konuyu sonlandıralım

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

Socket.io odalarından referans


1
Görünüşe göre cevabınız @ az7ar'ın aşağıdaki cevabının bir kopyası, eğer birinin cevabını değiştirerek kullanıyorsanız lütfen kredi verin
Rahul Gaur

Teşekkür ederim @RahulGaur, Evet benzer bir kopya değil. Ama kesinlikle cevabım değişti. O kullanılan inbir olayı yayacak şekilde. Ama benim durumumda, tobir olay yayardım. Umarım bunu daha önce görmüşsünüzdür
Lalit Mohan

Bunun bir kopya olmadığını duymak güzel, ama ilham verici görünüyor, bu yüzden
takdir

1
Noted Brother, Kesinlikle yapacaksın @RahulGaur.
Lalit Mohan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.