सर्वर-सेंटेड इवेंट्स (SSE) के लिए, Nginx प्रॉक्सी कॉन्फ़िगरेशन क्या उपयुक्त है?


21

मैंने SSE के लिए Nginx कॉन्फ़िगरेशन क्या उपयुक्त है, इस पर विभिन्न प्रश्नों का एक समूह पढ़ा है और कुछ भ्रमित परिणामों के साथ आया कि किन सेटिंग्स का उपयोग करना है:

तो सही जवाब क्या है?

जवाबों:


46

लंबे समय तक चलने वाला कनेक्शन

सर्वर-सेंटेड इवेंट्स (SSE) एक लंबे समय तक चलने वाला HTTP कनेक्शन ** है, इसलिए शुरुआत के लिए हमें इसकी आवश्यकता है:

proxy_http_version 1.1;
proxy_set_header Connection "";

नोट: HTTP / 1.1 में टीसीपी कनेक्शन डिफ़ॉल्ट रूप से लगातार हैं, इसलिए कनेक्शन हेडर को खाली करने के लिए सही काम करता है और यह निग्नेक्स सुझाव है।

चंवर ट्रांसफर-एन्कोडिंग

अब एक तरफ; SSE प्रतिक्रियाओं ने एक सामग्री-लंबाई शीर्षलेख सेट नहीं किया है क्योंकि वे नहीं जान सकते हैं कि कितना डेटा भेजा जाएगा, इसके बजाय उन्हें स्थानांतरण-एन्कोडिंग हेडर [0] [1] का उपयोग करने की आवश्यकता है, जो स्ट्रीमिंग कनेक्शन के लिए अनुमति देता है। यह भी नोट करें: यदि आप एक कंटेंट-लेंथ नहीं जोड़ते हैं तो अधिकांश HTTP सर्वर Transfer-Encoding: chunked;आपके लिए सेट हो जाएंगे । अजीब बात है, HTTP chunking के खिलाफ चेतावनी दी और भ्रम का कारण बनता है।

W3 EventSource विवरण के नोट्स अनुभाग में कुछ अस्पष्ट चेतावनी से भ्रम पैदा होता है:

लेखकों को यह भी चेतावनी दी जाती है कि HTTP चूनिंग से इस प्रोटोकॉल की विश्वसनीयता पर अप्रत्याशित नकारात्मक प्रभाव पड़ सकता है। जहां तक ​​संभव हो, जब तक संदेशों की दर इतनी अधिक न हो, तब तक घटना की धाराओं के लिए चूनिंग को अक्षम किया जाना चाहिए।

जिससे विश्वास हो सके कि Transfer-Encoding: chunked;SSE के लिए एक बुरी बात है। हालाँकि: यह जरूरी नहीं है, यह केवल एक समस्या है, जब आपका वेबसर्वर आपके लिए चैंकिंग कर रहा है (आपके डेटा के बारे में जानकारी नहीं)। इसलिए, जबकि अधिकांश पोस्ट यह सुझाव देंगे कि chunked_transfer_encoding off;यह विशिष्ट मामले में आवश्यक नहीं है [3]।

बफरिंग (वास्तविक समस्या)

जहाँ सबसे अधिक समस्याएँ आती हैं, उनमें ऐप सर्वर और क्लाइंट के बीच किसी भी प्रकार की बफरिंग होती है। डिफ़ॉल्ट रूप से [४], निग्नेक्स का उपयोग करता है proxy_buffering on( अपने आवेदन पर uwsgi_bufferingऔर fastcgi_bufferingउसके आधार पर भी एक नज़र डालें ) और उन चुनिन्दाओं को बफर करने का विकल्प चुन सकता है जिन्हें आप अपने ग्राहक से बाहर निकालना चाहते हैं। यह एक बुरी बात है क्योंकि SSE का रियल टाइम नेचर टूट जाता है।

हालांकि, proxy_buffering offसब कुछ के लिए मुड़ने के बजाय , यह वास्तव में सबसे अच्छा है (यदि आप कर रहे हैं) तो X-Accel-Buffering: noअपने आवेदन सर्वर कोड में एक प्रतिक्रिया हैडर के रूप में जोड़ने के लिए केवल एसएसई आधारित प्रतिक्रिया के लिए बफरिंग बंद करें और आपके ऐप से आने वाली सभी प्रतिक्रियाओं के लिए नहीं। सर्वर। बोनस: यह भी के लिए काम करेंगे uwsgiऔर fastcgi

समाधान

और इसलिए वास्तव में महत्वपूर्ण सेटिंग्स वास्तव में ऐप-सर्वर प्रतिक्रिया हेडर हैं:

Content-Type: text/event-stream;
Cache-Control: no-cache;
X-Accel-Buffering: no;

और संभावित रूप से कुछ पिंग तंत्र के कार्यान्वयन ताकि कनेक्शन बहुत लंबे समय तक निष्क्रिय न रहे। इस का खतरा यह है कि keepaliveसेटिंग का उपयोग करके Nginx निष्क्रिय कनेक्शन को बंद कर देगा ।


[०] https://tools.ietf.org/html/rfc2616#section-3.6
[१] https://en.wikipedia.org/wiki/Chunked_transfer_encoding
[२] https://www.w3.org/TR / 2009 / WD-eventource-20091029 / # टेक्स्ट-इवेंट-स्ट्रीम
[3] https://github.com/whatwg/html/issues/515
[4] http://nginx.org/en/docs/http/ ngx_http_proxy_module.html #xy_buffering
[5] https://tools.ietf.org/html/rfc7230#section-6.3
[6] https://gist.github.com/ChCDragonkai/6bfade6431e9ffb7fe88


क्या आप विस्तृत कर सकते हैं कि पिंग तंत्र क्या है? क्या यह बस एक खाली संदेश को चैनल पर धकेल रहा है? मैंने nginx और app level headers की स्थापना की है, लेकिन मुझे अभी भी किसी भी इवेंट-सोर्स एंडपॉइंट के लिए nginx से 504 टाइमआउट मिल रहा है।
wgwz

एक पिंग सिर्फ कनेक्शन पर अंतराल पर भेजे गए कुछ (फर्जी) डेटा होगा, क्लाइंट पर आप इस पिंग को संभाल सकते हैं और इसे अनदेखा कर सकते हैं। नोट: यदि आपका कनेक्शन बिल्कुल काम नहीं कर रहा है, तो पिंगिंग से मदद नहीं मिलेगी, कुछ और गलत है।
15:14 पर c4urself

2
मैंने सुझाव के रूप में प्रतिक्रिया हेडर को जोड़ा और यह काम करता है। मैंने nginx v1.12 कॉन्फिगरेशन में कोई बदलाव नहीं किया है और अब तक कोई समस्या नहीं है।
मिकेल

1
X-Accel-Buffering: noहेडर जोड़ना मेरे लिए महत्वपूर्ण था, लेकिन महत्वपूर्ण बात, मुझे @ c4urself के रूप में करना था: "एक्स-एक्सेल-बफरिंग जोड़ें: आपके एप्लिकेशन सर्वर कोड में प्रतिक्रिया हेडर के रूप में नहीं "। इस हेडर को मेरे nginx कॉन्फिगरेशन में किसी लोकेशन सेक्शन में जोड़ने से काम नहीं चला - आवेदन समाप्त होने / समाप्त होने तक पूरी घटना स्ट्रीम भेजे जाने का इंतजार किया गया।
MDMower

है proxy_http_version 1.1; आवश्यक? मैं एक ब्राउज़र से 6 से अधिक SSE स्ट्रीम चलाने की कोशिश कर रहा हूं और इसलिए मुझे HTTP2 की आवश्यकता है।
बिलाल फजलानी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.