Facebook, gmail वास्तविक समय सूचना कैसे भेजता है?


269

मैंने इस विषय के बारे में कुछ पोस्ट पढ़ी हैं और उत्तर धूमकेतु, रिवर्स अजाक्स, http स्ट्रीमिंग, सर्वर पुश आदि हैं।

जीमेल पर आने वाली मेल अधिसूचना कैसे काम करती है?

कैसे ग्राहक बातचीत के बिना AJAX अनुरोध करने में सक्षम GMail चैट है?

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

मुझे पता है कि इसे सर्वर साइड और क्लाइंट साइड दोनों में करना होगा। क्या कोई PHP और जावास्क्रिप्ट नमूना कोड है?

जवाबों:


428

जिस तरह से फेसबुक ऐसा करता है वह काफी दिलचस्प है।

इस तरह के नोटिफिकेशन को करने का एक सामान्य तरीका यह है कि अगर कुछ हो गया है, तो यह देखने के लिए सर्वर पर एक स्क्रिप्ट (AJAX का उपयोग करके) दिए गए अंतराल पर (शायद हर कुछ सेकंड में) एक स्क्रिप्ट का चुनाव करें। हालांकि, यह बहुत नेटवर्क गहन हो सकता है, और आप अक्सर व्यर्थ अनुरोध करते हैं, क्योंकि कुछ भी नहीं हुआ है।

फेसबुक जिस तरह से करता है वह एक अंतराल पर मतदान के बजाय धूमकेतु दृष्टिकोण का उपयोग कर रहा है, जैसे ही एक सर्वेक्षण पूरा होता है, यह एक और जारी करता है। हालाँकि, सर्वर पर स्क्रिप्ट के लिए प्रत्येक अनुरोध में एक बहुत लंबा समयबाह्य होता है, और सर्वर केवल अनुरोध का जवाब देता है एक बार कुछ हुआ है। आप फेसबुक पर रहते हुए फायरबग के कंसोल टैब को ला सकते हैं, यह संभवत: मिनटों की स्क्रिप्ट के अनुरोध के साथ हो सकता है। यह वास्तव में काफी सरल है, क्योंकि यह विधि दोनों अनुरोधों की संख्या पर तुरंत कटौती करती है, और आपको उन्हें कितनी बार भेजना है। अब आपके पास प्रभावी रूप से एक घटना ढांचा है जो सर्वर को 'आग' घटनाओं की अनुमति देता है।

इसके पीछे, उन चुनावों से लौटी वास्तविक सामग्री के संदर्भ में, यह एक JSON प्रतिक्रिया है, जो घटनाओं की एक सूची और उनके बारे में जानकारी प्रतीत होती है। यह छोटा है, लेकिन पढ़ने में थोड़ा कठिन है।

वास्तविक तकनीक के संदर्भ में, AJAX यहां जाने का तरीका है, क्योंकि आप अनुरोध टाइमआउट, और कई अन्य चीजों को नियंत्रित कर सकते हैं। मैं AJAX करने के लिए jQuery का उपयोग करके (यहां स्टैक ओवरफ्लो क्लिच) की सलाह दूंगा, यह बहुत अधिक क्रॉस-कम्पैटिबिलिटी को दूर ले जाएगा। PHP के संदर्भ में, आप बस अपने PHP स्क्रिप्ट में एक इवेंट लॉग डेटाबेस टेबल को पोल कर सकते हैं, और केवल क्लाइंट के पास वापस आ सकते हैं जब कुछ होता है? मुझे उम्मीद है, इसे लागू करने के कई तरीके हैं।

क्रियान्वयन:

सर्वर साइड:

PHP में धूमकेतु पुस्तकालयों के कुछ कार्यान्वयन प्रतीत होते हैं, लेकिन ईमानदार होने के लिए, यह वास्तव में बहुत सरल है, शायद निम्नलिखित छद्मकोश की तरह कुछ:

while(!has_event_happened()) {
   sleep(5);
}

echo json_encode(get_events());
  • Has_event_happened फ़ंक्शन केवल जाँच करेगा कि क्या कुछ घटना तालिका या कुछ और में हुआ था, और फिर get_events फ़ंक्शन तालिका में नई पंक्तियों की सूची लौटाएगा? वास्तव में समस्या के संदर्भ पर निर्भर करता है।

  • अपने PHP अधिकतम निष्पादन समय को बदलना न भूलें, अन्यथा यह समय से पहले समाप्त हो जाएगा!

ग्राहक की ओर:

धूमकेतु इंटरैक्शन करने के लिए jQuery प्लगइन पर एक नज़र डालें:

उस ने कहा, प्लगइन एक जटिलता का एक निष्पक्ष जोड़ने के लिए लगता है, यह वास्तव में ग्राहक पर बहुत सरल है, शायद (jQuery के साथ) कुछ इस तरह से:

function doPoll() {
   $.get("events.php", {}, function(result) {
      $.each(result.events, function(event) { //iterate over the events
          //do something with your event
      });
      doPoll(); 
      //this effectively causes the poll to run again as
      //soon as the response comes back
   }, 'json'); 
}

$(document).ready(function() {
    $.ajaxSetup({
       timeout: 1000*60//set a global AJAX timeout of a minute
    });
    doPoll(); // do the first poll
});

पूरी बात इस बात पर निर्भर करती है कि आपकी मौजूदा वास्तुकला को एक साथ कैसे रखा जाए।


2
यह बहुत अच्छा और विस्तृत विवरण है। धन्यवाद। क्या आपके पास इसे लागू करने के कई तरीकों में से एक के लिए कोई नमूना कोड है?
बिली

45
मुझे लगता है कि PHP को एक भाषा / मंच के रूप में लेबल करना जो अच्छी तरह से पैमाने पर नहीं है, जरूरी नहीं कि यह सच हो। इसका उपयोग अत्यंत बड़े पैमाने पर प्रणालियों को विकसित करने के लिए किया जा सकता है। फेसबुक पर देखो। यदि डेवलपर इसे सही करता है, तो यह पैमाने पर होगा, यदि नहीं, तो यह नहीं होगा। एक विशिष्ट वेब प्लेटफॉर्म का उपयोग करना स्केलेबिलिटी की गारंटी नहीं है। ओह, और भी, सवाल PHP के लिए पूछा था।
एलिस्टेयर इवांस

5
@Kazar: "Facebook PHP का उपयोग करता है" थोड़ा भ्रामक है - आखिरी बार मैंने सुना, उन्होंने PHP को C ++ में परिवर्तित करने के एक्सप्रेस उद्देश्य के लिए हिपहॉप विकसित किया, क्योंकि PHP बहुत अच्छा प्रदर्शन नहीं कर रहा था।
cHao

14
@cHao: यह एक उचित बिंदु है, हालांकि यह जवाब 2009 में लिखा गया था, इससे पहले कि फेसबुक ने हिपहॉप का उपयोग करना शुरू कर दिया था। उस समय facebook अभी भी एक बहुत बड़ी-स्केल वाली प्रणाली थी जो php का उपयोग कर रही थी।
एलिस्टेयर इवांस

6
इसलिए तकनीक एक कनेक्शन को लगातार खुला रखना है जो एक सर्वर को लगातार तनाव में रखेगा। एक औसत वेब-सर्वर के लिए समवर्ती कनेक्शन की एक विशिष्ट राशि लगभग 200 है, लेकिन एक साथ ऑनलाइन होने वाले फेसबुक उपयोगकर्ताओं की संख्या एक तरह से बड़ी है। वे यह काम कैसे करते हैं?
पॉल

43

अपडेट करें

जैसा कि मैंने इस पर आगे बढ़ना जारी रखा है, मुझे लगता है कि यह याद रखना उचित है कि यह उत्तर 4 साल पुराना है। वेब वास्तव में तेज़ गति से बढ़ा है, इसलिए कृपया इस उत्तर के बारे में ध्यान रखें।


मेरे पास हाल ही में एक ही मुद्दा था और इस विषय के बारे में शोध किया।

दिए गए समाधान को लंबे मतदान कहा जाता है, और इसे सही ढंग से उपयोग करने के लिए आपको यह सुनिश्चित करना होगा कि आपके AJAX अनुरोध में एक "बड़ा" समय समाप्त हो गया है और हमेशा वर्तमान समाप्त होने के बाद यह अनुरोध करना चाहिए (समय समाप्त, त्रुटि या सफलता)।

लंबा मतदान - ग्राहक

यहाँ, कोड को छोटा रखने के लिए, मैं jQuery का उपयोग करूंगा:

function pollTask() { 

    $.ajax({

        url: '/api/Polling',
        async: true,            // by default, it's async, but...
        dataType: 'json',       // or the dataType you are working with
        timeout: 10000,          // IMPORTANT! this is a 10 seconds timeout
        cache: false

    }).done(function (eventList) {  

       // Handle your data here
       var data;
       for (var eventName in eventList) {

            data = eventList[eventName];
            dispatcher.handle(eventName, data); // handle the `eventName` with `data`

       }

    }).always(pollTask);

}

यह याद रखना महत्वपूर्ण है कि ( jQuery डॉक्स से ):

JQuery 1.4.x और नीचे, XMLHttpRequest ऑब्जेक्ट अमान्य स्थिति में होगा यदि अनुरोध समय से बाहर हो; किसी भी वस्तु सदस्यों तक पहुँच एक अपवाद फेंक सकता है। फ़ायरफ़ॉक्स 3.0+ में, स्क्रिप्ट और JSONP अनुरोधों को टाइमआउट द्वारा रद्द नहीं किया जा सकता है; स्क्रिप्ट समयावधि के बाद आने पर भी चलेगी।

लंबा मतदान - सर्वर

यह किसी विशिष्ट भाषा में नहीं है, लेकिन यह कुछ इस तरह होगा:

function handleRequest () {  

     while (!anythingHappened() || hasTimedOut()) { sleep(2); }

     return events();

} 

यहां, hasTimedOutयह सुनिश्चित कर लें कि आपका कोड हमेशा के लिए प्रतीक्षा नहीं करता है, और anythingHappenedयह जांच करेगा कि क्या कोई भी ईवेंट खुश है। sleepअन्य सामान लेना-देना नहीं होता है, जबकि अपनी धागा प्रसारित करने की है। eventsJSON प्रारूप में घटनाओं की एक शब्दकोश (या किसी अन्य डेटा संरचना आप पसंद कर सकते हैं) वापस आ जाएगी (या किसी अन्य आप पसंद करते हैं)।

यह निश्चित रूप से समस्या को हल करता है, लेकिन, यदि आप मापनीयता और पूर्णता के बारे में चिंतित हैं जैसा कि मैं शोध कर रहा था, तो आप एक और समाधान पर विचार कर सकते हैं जो मुझे मिला।

उपाय

सॉकेट्स का उपयोग करें!

क्लाइंट की ओर से, किसी भी संगतता समस्याओं से बचने के लिए, सॉकेट का उपयोग करें । यह सीधे सॉकेट का उपयोग करने की कोशिश करता है, और सॉकेट उपलब्ध नहीं होने पर अन्य समाधानों में कमियां होती हैं।

सर्वर साइड पर एक सर्वर (उदाहरण के NodeJS का उपयोग कर बनाने के यहाँ )। क्लाइंट सर्वर के साथ बनाए गए इस चैनल (पर्यवेक्षक) की सदस्यता लेगा। जब भी कोई अधिसूचना भेजनी होती है, तो उसे इस चैनल में प्रकाशित किया जाता है और सबस्क्रिप्ट (क्लाइंट) को सूचित किया जाता है।

यदि आपको यह समाधान पसंद नहीं है, तो APE ( Ajax Push Engine ) आज़माएं ।

आशा है कि मैंने मदद की।


क्या आपको लगता है कि 1 दूसरे के लिए एक प्रतिस्थापन है या एक ही परियोजना पर दोनों प्रौद्योगिकियों की आवश्यकता है?
tq

अगर आपको APE और NodeJS से मतलब है, तो आप उनमें से किसी एक को चुन सकते हैं। अगर आपको समय-समय पर AJAX के अनुरोध और मेरे द्वारा सुझाए गए एक का मतलब है, तो सॉकेट के समर्थन में कमी (socket.io डॉक्स को देखें) के लिए मेरा समाधान ajax में वापस आ सकता है। दोनों ही मामलों में, आपको केवल एक समाधान की आवश्यकता है।
वाल्टर मैकम्बिरा

हे वाल्टर, मैं अपनी एक साइट पर आपके सुझाव का उपयोग करना चाहूंगा। क्या आप जानते हैं कि मुझे सॉकेट सर्वर कहां मिल सकता है? धन्यवाद!
Progo

1
आप इसे लागू कर सकते हैं। नोड यह वास्तव में सरल बनाता है।
वाल्टर मैकाम्बीरा

कैसे करें पता hasTimedOut()?
मोबशेर फसीह

18

फेसबुक के मैसेजिंग सिस्टम के बारे में एक स्लाइड शो के अनुसार , फेसबुक वेब ब्राउजरों को संदेश को "पुश" करने के लिए धूमकेतु तकनीक का उपयोग करता है। फेसबुक का धूमकेतु सर्वर खुले खट्टे Erlang वेब सर्वर mochiweb पर बनाया गया है।

नीचे दी गई तस्वीर में, वाक्यांश "चैनल क्लस्टर" का अर्थ है "धूमकेतु सर्वर"।

सिस्टम सारांश

कई अन्य बड़ी वेब साइटें अपने स्वयं के धूमकेतु सर्वर का निर्माण करती हैं, क्योंकि हर कंपनी की आवश्यकता के बीच अंतर हैं। लेकिन एक खुले स्रोत धूमकेतु सर्वर पर अपना स्वयं का धूमकेतु सर्वर का निर्माण एक अच्छा तरीका है।

तुम icomet कोशिश कर सकते हैं , एक C1000K C ++ धूमकेतु सर्वर libevent के साथ बनाया गया है। icomet एक जावास्क्रिप्ट लाइब्रेरी भी प्रदान करता है, इसे उपयोग करना आसान है:

var comet = new iComet({
    sign_url: 'http://' + app_host + '/sign?obj=' + obj,
    sub_url: 'http://' + icomet_host + '/sub',
    callback: function(msg){
        // on server push
        alert(msg.content);
    }
});

icomet ब्राउज़र और OS की एक विस्तृत श्रृंखला का समर्थन करता है, जिसमें Safari (iOS, Mac), IEs (Windows), फ़ायरफ़ॉक्स, क्रोम आदि शामिल हैं।


यह छवि परिदृश्य का बहुत अच्छी तरह से वर्णन करती है। अगर एक्शन का उदाहरण दिया जाता तो बहुत अच्छा होता। उदाहरण के लिए जब कोई व्यक्ति किसी दोस्त के साथ चैटबॉक्स खोलता है (आरंभ करता है) तो क्या होता है? इस विशिष्ट बातचीत में फेसबुक कैसे ट्यून करता है और संदेशों को दोनों छोर तक धकेलता है? (सिर्फ एक अनुमान: मैं केवल कल्पना कर सकता हूं कि एप्लिकेशन प्रोग्राम एक सॉकेट खोलता है और दोनों क्लाइंट पते को बांधता है और फिर बॉक्स में जब भी संदेश लिखा जाता है, तो बस सुनता और लिखता रहता
हूं

5

फेसबुक HTTP के बजाय MQTT का उपयोग करता है। मतदान से बेहतर है पुश। HTTP के माध्यम से हमें सर्वर को लगातार प्रदूषित करने की आवश्यकता है लेकिन MQTT सर्वर के माध्यम से ग्राहकों को संदेश पहुंचता है।

MQTT और HTTP के बीच तुलना: http://www.youtube.com/watch?v=-KNPXPmx88E

नोट: मेरे उत्तर मोबाइल उपकरणों के लिए सबसे उपयुक्त हैं।


3
इसके अतिरिक्त, Google Android के लिए GCM सेवा का उपयोग करता है, इसका उपयोग डेवलपर्स द्वारा पुश संदेश सेवा को लागू करने के लिए किया जा सकता है। developer.android.com/google/gcm/index.html कृपया जवाब उपयोगी होने पर स्वीकार करें।
अबी

5

लंबे मतदान के साथ एक महत्वपूर्ण मुद्दा त्रुटि से निपटने का है। त्रुटियों के दो प्रकार हैं:

  1. अनुरोध उस समय में हो सकता है जब ग्राहक को तुरंत कनेक्शन पुनः स्थापित करना चाहिए। लंबे मतदान में यह एक सामान्य घटना है जब कोई संदेश नहीं आया है।

  2. एक नेटवर्क त्रुटि या एक निष्पादन त्रुटि। यह एक वास्तविक त्रुटि है जिसे क्लाइंट को इनायत होकर स्वीकार करना चाहिए और सर्वर के ऑन-लाइन वापस आने का इंतजार करना चाहिए।

मुख्य मुद्दा यह है कि यदि आपकी त्रुटि हैंडलर कनेक्शन को तुरंत टाइप 2 त्रुटि के लिए भी पुन: स्थापित करती है, तो क्लाइंट सर्वर को डॉस करेगा।

कोड नमूने के साथ दोनों जवाब यह याद करते हैं।

function longPoll() { 
        var shouldDelay = false;

        $.ajax({
            url: 'poll.php',
            async: true,            // by default, it's async, but...
            dataType: 'json',       // or the dataType you are working with
            timeout: 10000,          // IMPORTANT! this is a 10 seconds timeout
            cache: false

        }).done(function (data, textStatus, jqXHR) {
             // do something with data...

        }).fail(function (jqXHR, textStatus, errorThrown ) {
            shouldDelay = textStatus !== "timeout";

        }).always(function() {
            // in case of network error. throttle otherwise we DOS ourselves. If it was a timeout, its normal operation. go again.
            var delay = shouldDelay ? 10000: 0;
            window.setTimeout(longPoll, delay);
        });
}
longPoll(); //fire first handler
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.