सॉकेट के साथ किसी विशेष क्लाइंट को एक संदेश कैसे भेजें


96

मैं सॉकेट.आईओ + नोड.जेएस के साथ शुरू कर रहा हूं, मुझे पता है कि स्थानीय रूप से संदेश भेजने और socket.broadcast.emit()फ़ंक्शन को प्रसारित करने का तरीका : - सभी कनेक्टेड क्लाइंट को एक ही संदेश प्राप्त होता है।

अब, मैं यह जानना चाहूंगा कि किसी विशेष ग्राहक को एक निजी संदेश कैसे भेजा जाए, मेरा मतलब 2 व्यक्ति (क्लाइंट-टू-क्लाइंट स्ट्रीम) के बीच एक निजी चैट के लिए एक सॉकेट है। धन्यवाद।


क्षमा करें, psiphi75 लेकिन यह लिंक मेरे उत्तर का उत्तर नहीं देता है, डुप्लिकेट प्रश्न नहीं है।
निज़ार बी।

1
@ psiphi75, यह कोई डुप्लिकेट नहीं है
सॉफ्टवार

1
@Psiphi जैसे लोगों को खड़ा नहीं कर सकते। क्या आप डेवलपर भी हैं? HTML5 विशिष्ट प्रश्न एक स्टैंडअलोन लाइब्रेरी से कैसे संबंधित है? और इसकी कीमत क्या है, इसके लिए वेब सॉकेट्स सॉकेट नहीं हैं। सॉकेट.आईओ एक पुस्तकालय है जो वेबसीएस का उपयोग कर सकता है, लेकिन मैं इसे खोदता हूं। यह केवल विशिष्ट ग्राहकों को डेटा भेजने के बारे में लाइब्रेरी से संबंधित एक और अधिक विशिष्ट प्रश्न है, न कि केवल तकनीक के बारे में।
लेवी रॉबर्ट्स


@ Bugwheels94 वास्तव में नहीं है, यह पोस्ट 2011 से है और चूंकि नोडज में कोड-वार परिवर्तनों का भार था। यह पोस्ट निश्चित रूप से इस मुद्दे के लिए एक वैध प्रश्न / उत्तर है।
निजार बी।

जवाबों:


102

जब कोई उपयोगकर्ता कनेक्ट होता है, तो उसे सर्वर को एक उपयोगकर्ता नाम के साथ एक संदेश भेजना चाहिए जो एक ईमेल की तरह अद्वितीय होना चाहिए।

उपयोगकर्ता नाम और सॉकेट की एक जोड़ी इस तरह से एक वस्तु में संग्रहित की जानी चाहिए:

var users = {
    'userA@example.com': [socket object],
    'userB@example.com': [socket object],
    'userC@example.com': [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)

क्लाइंट पर, 'ReceMessage' नामक सर्वर से उत्सर्जन के लिए सुनो, और डेटा को पढ़कर आप इसे संभाल सकते हैं कि यह किससे आया था और जो संदेश भेजा गया था।


26
यदि आप इस समाधान का उपयोग करते हैं तो आपको समझना होगा: 1. जब उपयोगकर्ता डिस्कनेक्ट करता है तो आपको 'उपयोगकर्ता' ऑब्जेक्ट को साफ करना होगा। यह दूसरे कनेक्शन का समर्थन नहीं करता है - उदाहरण के लिए दूसरे ब्राउज़र से। इसलिए यदि उपयोगकर्ता दूसरे ब्राउज़र से कनेक्ट होता है - पुराना कनेक्शन ओवरराइड हो जाएगा।
व्लादिमीर कुरिजोव

1
आप डेटासोर में सॉकेट ऑब्जेक्ट को कैसे स्टोर करेंगे? यदि आप एक से अधिक नोड प्रक्रिया रखते हैं तो मैं यह काम नहीं कर रहा हूँ।
चॉवी

@chovy आपको रेडिस का उपयोग करना होगा। इस github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO पर
व्लादिमीर कुरिज़ोव

11
मैं इस समाधान का उपयोग नहीं करने का सुझाव देता हूं। मैंने इस दृष्टिकोण की सीमाओं को दूर करने की कोशिश में बहुत समय बर्बाद कर दिया। @ Az7ar का समाधान देखें और यह स्पष्टीकरण कि यह बेहतर क्यों है
डैनियल Que

@ डैनियलक्यू 1। उपयोग की गई देशी कार्यक्षमता के लिए बेहतर है। धन्यवाद!
हारून लेलेयर

275

आप सॉकेट.आईओ कमरे का उपयोग कर सकते हैं। क्लाइंट की ओर से किसी भी विशिष्ट पहचानकर्ता (ईमेल, आईडी) के साथ एक घटना (इस मामले में "जुड़ें", कुछ भी हो सकता है) का उत्सर्जन करें।

ग्राहक की ओर:

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

अब, सर्वर की ओर से उस जानकारी का उपयोग उस उपयोगकर्ता के लिए एक अद्वितीय कमरा बनाने के लिए किया जाता है

सर्वर साइड:

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('user1@example.com').emit('new_msg', {msg: 'hello'});

क्लाइंट की तरफ से करने के लिए आखिरी चीज "new_msg" ईवेंट है।

ग्राहक की ओर:

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

मुझे उम्मीद है कि आपको यह विचार मिलेगा।


3
कृपया इस लाइन को बदल दें io.socket.in ('user1@example.com ')। emit (' new_msg ', {msg:' hello '}); इस तरह io.sockets.in (user1@example.com ’)। emit ('new_msg', {msg: 'hello'});
silvesterprabu

42
यह उत्तर वर्तमान में स्वीकृत उत्तर की तुलना में बहुत बेहतर है। यहाँ क्यों है: 1) आपको ग्राहकों की वैश्विक सरणी का प्रबंधन और सफाई करने की आवश्यकता नहीं है। 2) यह काम करता है भले ही उपयोगकर्ता के एक ही पृष्ठ पर कई टैब खुले हों। 3) इसे नोड क्लस्टर (कई प्रक्रियाओं) के साथ काम करने के लिए आसानी से बढ़ाया जा सकता है socket.io-redis
डैनियल Que

2
आप {email: user1@example.com}सभी कनेक्शन के लिए अलग कैसे बनाते हैं। सभी क्लाइंट जो ऐप में जाते हैं, उनके पास उपयोगकर्ता है user1@example.comमैं इसे user2@example.comदूसरे क्लाइंट के लिए कैसे उपयोगकर्ता बनाऊंगा जो कनेक्ट करता है इसलिए मेरे पास अलग-अलग कमरे हो सकते हैं। क्षमा करें यदि यह एक कष्टप्रद प्रश्न है।
जैक खाली

2
समाधान से प्यार था, लेकिन मेरा मानना ​​है कि यहां सुरक्षा से समझौता किया गया है। क्या होगा अगर मैं क्लाइंट साइड पर स्क्रिप्ट में ईमेल को बदल दूं। अब मैं अन्य निजी संदेश भी पढ़ पा रहा हूं। तुम क्या कह रहे हो?
गोपीनाथ शिव

3
यह ईमेल होना जरूरी नहीं है मैंने किसी भी विशिष्ट पहचानकर्ता का उल्लेख किया है
az7ar

32

इलाज: बस,

यह वही चीज़ है जिसकी आपको आवश्यकता है :

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

जब भी कोई उपयोगकर्ता सर्वर से जुड़ता है, तो सॉकेट विवरण आईडी सहित उत्पन्न हो जाएगा। यह वह आईडी है जो वास्तव में विशेष लोगों को संदेश भेजने में मदद करती है।

पहले हमें सभी सॉकेट स्टोर करने की आवश्यकता है।

var people={};

people[name] =  socket.id;

यहाँ नाम रिसीवर नाम है। उदाहरण:

people["ccccc"]=2387423cjhgfwerwer23;

इसलिए, अब हम उस सॉकेट को प्राप्त कर सकते हैं। रिसीवर के नाम के साथ जब भी हम संदेश भेज रहे हैं:

इसके लिए हमें रिसीवर का नाम जानना होगा। आपको सर्वर पर रिसीवर का नाम छोड़ना होगा।

अंतिम बात यह है:

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

आशा है कि यह आपके लिए अच्छा काम करेगा।

शुभ लाभ!!


क्या आप क्लाइंट साइड और सर्वर साइड कोड बना सकते हैं। मैं स्कूटेट प्रोग्रामिंग में नया हूं। hmahajaninosi@gmail.com
हरीश महाजन

@ हर्ष, नीचे दिए गए लिंक को देखें, जो बताता है कि ग्राहक की तरफ से वास्तव में क्या हो रहा है..मुझे उम्मीद है कि यह आपकी अधिक मदद करेगा
ट्रोजन

2
लेकिन क्या होगा अगर उपयोगकर्ता एक ही समय में 2 अन्य लोगों के साथ चैट कर रहा है। क्या दोनों उपयोगकर्ताओं का संदेश दोनों विंडो में नहीं आएगा?
शरण मोहनदास

यदि दो से अधिक उपयोगकर्ता हैं, तो यह सही काम नहीं करेगा
मोहम्मद हशाम

प्रत्येक बार जब उपयोगकर्ता सॉकेट आईडी में बदलाव करता है तो उपयोगकर्ता आपके ऐप को कई टैब में खोलता है, इसे एक प्रतिक्रिया मिलेगी जिसे आपने संग्रहीत किया है और अन्य सॉकेट कनेक्शनों को भेजा है
विकास कंडारी

8

आप सॉकेट के लिए उल्लेख कर सकते हैं । कमरे । जब आपने सॉकेट को हैंडशेक किया - तो आप उसे "नामित उपयोगकर्ता" # {userid} के लिए नामित कमरे में शामिल कर सकते हैं।

उसके बाद, आप किसी भी क्लाइंट को सुविधाजनक नाम से निजी संदेश भेज सकते हैं, उदाहरण के लिए:

io.sockets.in ('user.125')। emit ('new_message', {text: "Hello world"})

ऊपर ऑपरेशन में हम उपयोगकर्ता "125" को "new_message" भेजते हैं।

धन्यवाद।


हाय दोस्त, आपके पहले जवाब के लिए धन्यवाद, मैं इसे आज़माऊंगा और आपको इसके बारे में बताऊंगा, क्योंकि मैं एक चैट का निर्माण नहीं करना चाहता, लेकिन एक निजी दूत जैसे आप फेसबुक नेटवर्क पर उपयोग कर सकते हैं।
निज़ेर बी।

क्या कोई इस मामले में मेरी मदद कर सकता है, मैं वास्तव में फंस गया हूं, मैं अपने सॉकेट से जुड़ा एक उपयोगकर्ता नाम जोड़ना चाहूंगा और अपने आवेदन को एक विशिष्ट उपयोगकर्ता को संदेश भेजने की अनुमति दे सकता हूं, कोई चैट रूम नहीं, यह मैसेंजर जैसा फेसबुक है। धन्यवाद अगर आप जानते हैं!
निजेर बी।

सबसे पहले आपको यह समझना होगा कि यह उपयोगकर्ता नाम सभी उपयोगकर्ताओं के लिए विशिष्ट होना चाहिए। और दूसरा एक - क्या आप ग्राहक पक्ष पर उत्सर्जित संदेश के लिए सदस्यता लेना नहीं भूले?
व्लादिमीर कुरिजोव

इसके साथ समस्या यह है कि आप कॉलबैक का उपयोग करने की क्षमता को ढीला कर देते हैं, क्योंकि उन्हें प्रसारण में अनुमति नहीं है, जो कि आप वास्तव में यहां कर रहे हैं, उनके निजी कमरे में प्रसारण।
ब्लूहल्लु

@VladimirKurijov, श्री काट्चा रूम का उपयोग नहीं करना चाहते हैं और मैं मानता हूं कि यह उनकी समस्या का समाधान नहीं है।
miksiii

4

हमारी कंपनी की एक परियोजना में हम "कमरे" दृष्टिकोण का उपयोग कर रहे हैं और यह नाम एक अद्वितीय पहचानकर्ता के रूप में बातचीत में सभी उपयोगकर्ताओं के उपयोगकर्ता आईडी का संयोजन है (हमारा कार्यान्वयन फेसबुक मैसेंजर की तरह अधिक है), उदाहरण:

| आईडी | नाम | १ | स्कॉट | 2 | सुसान

"कमरा" नाम "1-2" होगा (आईडी एससी का आदेश दिया जाता है) और डिस्कनेक्ट सॉकेट पर। स्वचालित रूप से कमरे को अच्छी तरह से साफ करना चाहिए

इस तरह से आप उस कमरे में और केवल ऑनलाइन (कनेक्टेड) ​​उपयोगकर्ताओं (पूरे सर्वर में भेजे गए कम पैकेज) को संदेश भेजते हैं।


1

मुझे सॉकेट के साथ इसे सरल बनाने दें। कमरे। सर्वर से जुड़ने के लिए एक अद्वितीय पहचानकर्ता के साथ एक सर्वर का अनुरोध करें। यहाँ हम एक विशिष्ट पहचानकर्ता के रूप में एक ईमेल का उपयोग कर रहे हैं।

ग्राहक सॉकेट

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

जब उपयोगकर्ता किसी सर्वर से जुड़ता है, तो उस उपयोगकर्ता के लिए एक कमरा बनाएं

सर्वर सॉकेट

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

अब हम सभी जुड़ने के साथ तैयार हैं। सर्वर toरूम से कुछ उत्सर्जित करें , ताकि उपयोगकर्ता सुन सके।

सर्वर सॉकेट

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

messageक्लाइंट साइड पर ईवेंट को सुनने के साथ विषय को अंतिम रूप दें

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

सॉकेट.आईओ कमरे से संदर्भ

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.