2011-10-03 12 views
25

तो मैं सर्वर से भेजा घटनाओं की अवधारणा (EventSource) को समझते हैं: सर्वर द्वारा भेजे गए ईवेंट वास्तव में कैसे काम करते हैं?

  • एक ग्राहक कि समाप्ति बिंदु को जोड़ता है के माध्यम से

    EventSource
  • ग्राहक सिर्फ endpoint

बात से भेजे गए संदेशों को सुनता है मैं उलझन में हूं कि यह सर्वर पर कैसे काम करता है। मैंने अलग-अलग उदाहरणों पर एक नज़र डाली है, लेकिन जो दिमाग में आता है वह है मोज़िला: http://hacks.mozilla.org/2011/06/a-wall-powered-by-eventsource-and-server-sent-events/

अब यह एक बुरा उदाहरण हो सकता है, लेकिन यह समझ में आता है कि सर्वर पक्ष कैसे काम करेगा, जैसा कि मैं समझता हूं :

  • कुछ इस तरह के एक डेटाबेस
  • सर्वर-साइड स्क्रिप्ट चुनाव डेटासंग्रह के रूप में एक डेटासंग्रह में बदल जाता है, हर वां दूसरा
  • मतदान स्क्रिप्ट एक परिवर्तन पर ध्यान करते हैं, तो एक सर्वर भेजा घटना के लिए निकाल दिया जाता है ग्राहक

क्या यह समझ में आता है? क्या वास्तव में यह एक barebones परिप्रेक्ष्य से कैसे काम करता है?

उत्तर

40

एचटीएमएल 5 डॉक्टर साइट पर great write-up सर्वर से भेजे गए कार्यक्रमों पर है, लेकिन मैं यहां एक (उचित रूप से) संक्षिप्त सारांश भी प्रदान करने की कोशिश करूंगा।

सर्वर द्वारा भेजे गए ईवेंट, इसके मूल पर, एक लंबे समय तक चलने वाले http कनेक्शन, एक विशेष माइम प्रकार (text/event-stream) और उपयोगकर्ता एजेंट जो EventSource API प्रदान करता है। साथ में, ये सर्वर और क्लाइंट के बीच एक यूनिडायरेक्शनल कनेक्शन की नींव बनाते हैं, जहां संदेशों को सर्वर से क्लाइंट पर भेजा जा सकता है।

सर्वर की ओर, यह अपेक्षाकृत सरल है। ,

Content-Type: text/event-stream 
Cache-Control: no-cache 
Connection: keep-alive 

कोड 200 और नहीं 204 या किसी अन्य कोड के साथ जवाब के लिए सुनिश्चित करें के रूप में इस शिकायत उपयोगकर्ता एजेंटों डिस्कनेक्ट करने के लिए कारण होगा: सभी तुम सच में क्या करने की जरूरत निम्नलिखित http हेडर निर्धारित है। साथ ही, सर्वर पक्ष पर कनेक्शन समाप्त नहीं करना सुनिश्चित करें। अब आप कनेक्शन को नीचे धक्का देना शुरू करने के लिए स्वतंत्र हैं। NodeJS (एक्सप्रेस का उपयोग) में, यह कुछ ऐसी नज़र आ सकते हैं:

app.get("/my-stream", function(req, res) { 
    res.status(200) 
     .set({ "content-type" : "text/event-stream" 
      , "cache-control" : "no-cache" 
      , "connection" : "keep-alive" 
      }) 

    res.write("data: Hello, world!\n\n") 
}) 

ग्राहक पर, आप सिर्फ EventSource एपीआई का उपयोग, जैसा कि आप ने कहा:

var source = new EventSource("/my-stream") 
source.addEventListener("message", function(message) { 
    console.log(message.data) 
}) 

और वह, यह मूल रूप से।

अब, वास्तव में, वास्तव में यहां क्या होता है यह है कि कनेक्शन एक आपसी अनुबंध के माध्यम से सर्वर और ग्राहक द्वारा जीवित रखा जाता है। जब तक यह फिट दिखाई देता है तब तक सर्वर कनेक्शन को जीवित रखेगा। अगर यह करना चाहते हैं, तो यह कनेक्शन को समाप्त कर सकता है और अगली बार जब ग्राहक कनेक्ट करने का प्रयास करता है तो 204 No Content के साथ प्रतिक्रिया दे सकता है। यह क्लाइंट को फिर से कनेक्ट करने का प्रयास करना बंद कर देगा। मुझे यकीन नहीं है कि कनेक्शन को समाप्त करने का कोई तरीका है जिस तरह से क्लाइंट को फिर से कनेक्ट नहीं करने के लिए कहा जाता है, जिससे ग्राहक एक बार फिर से कनेक्ट करने की कोशिश कर रहा है।

जैसा कि उल्लिखित ग्राहक भी कनेक्शन को जीवंत रखेगा, और इसे छोड़ने पर पुनः कनेक्ट करने का प्रयास करें। पुनः कनेक्ट करने के लिए एल्गोरिदम spec में निर्दिष्ट है, और काफी सीधे आगे है।

एक सुपर महत्वपूर्ण बिट जिसे मैंने अब तक स्पर्श किया है, हालांकि माइम प्रकार है। माइम प्रकार कनेक्टिंग के नीचे आने वाले संदेश के प्रारूप को परिभाषित करता है। ध्यान दें कि यह संदेश के सामग्री के प्रारूप को निर्देशित नहीं करता है, केवल संदेशों की संरचना स्वयं ही। माइम प्रकार बेहद सीधे आगे है। संदेश अनिवार्य रूप से जानकारी के महत्वपूर्ण/मूल्य जोड़े हैं। कुंजी एक पूर्वनिर्धारित सेट में से एक होना चाहिए: - संदेश

  • डेटा की आईडी -

    • आईडी वास्तविक डेटा
    • घटना - घटना प्रकार
    • पुन: प्रयास करें - उपयोगकर्ता एजेंट मिलीसेकन्ड इंतजार करना चाहिए असफल कनेक्शन को पुनः प्रयास करने से पहले

    किसी अन्य कुंजी को अनदेखा किया जाना चाहिए। संदेश तो दो नई पंक्ति वर्ण के उपयोग के द्वारा सीमांकित कर रहे हैं: \n\n

    निम्नलिखित एक वैध संदेश है: (पिछले नए लाइन वर्ण शब्दाडंबर के लिए जोड़ा)

    data: Hello, world! 
    \n 
    

    ग्राहक इस रूप में देखेंगे: Hello, world!

    के रूप में है इस: Hello,\nworld!:

    data: Hello, 
    data: world! 
    \n 
    

    ग्राहक इस के रूप में देखेंगे।

    यह बहुत अधिक बताता है कि सर्वर द्वारा भेजे गए ईवेंट क्या हैं: एक लंबे समय तक चलने वाले गैर-कैश किए गए http कनेक्शन, एक माइम प्रकार और एक साधारण जावास्क्रिप्ट एपीआई।

    अधिक जानकारी के लिए, मैं दृढ़ता से specification पढ़ने का सुझाव देता हूं। यह छोटा है और चीजों को बहुत अच्छी तरह से वर्णित करता है (हालांकि सर्वर पक्ष की आवश्यकताओं को थोड़ा बेहतर समझा जा सकता है।) उदाहरण के लिए, मैं अत्यधिक http स्थिति कोड के साथ अपेक्षित व्यवहार के लिए इसे पढ़ने का सुझाव देता हूं।

  • +3

    यह क्लाइंट के बारे में विस्तार से और कनेक्शन कैसे काम करता है, लेकिन यदि घटना को डेटाबेस परिवर्तन के लिए भेजा जाना आवश्यक है, तो मुझे लगता है कि सर्वर पर डेटाबेस को लगातार मतदान करने के अलावा कोई विकल्प नहीं है? मुझे लगता है कि ओप क्या पूछ रहा था? क्या कोई और अधिक कुशल समाधान सर्वर-साइड है - स्पष्ट रूप से यह छोटे व्यवसाय सर्वर पर कई कनेक्शन नहीं लेगा, अगर लूप लगातार डीबी परिवर्तनों की जांच कर रहे हैं तो चीजों को धीमा करना शुरू करें। –

    +1

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

    +2

    वह पुनः प्रयास करें: मिलीसेकंड बिट - प्रतिभा! मेरी त्वचा बचाई! –

    संबंधित मुद्दे