การเชื่อมต่อที่ยาวนาน
เหตุการณ์ที่เซิร์ฟเวอร์ส่ง (SSE) เป็นการเชื่อมต่อ HTTP ที่ใช้งานมานาน ** ดังนั้นสำหรับผู้เริ่มต้นเราต้องการสิ่งนี้:
proxy_http_version 1.1;
proxy_set_header Connection "";
หมายเหตุ: การเชื่อมต่อ TCP ใน HTTP / 1.1 จะคงอยู่ตามค่าเริ่มต้นดังนั้นการตั้งค่าส่วนหัวการเชื่อมต่อให้ว่างเปล่าทำสิ่งที่ถูกต้องและเป็นคำแนะนำของ Nginx
การถ่ายโอนการเข้ารหัส Chunked
ตอนนี้กัน; การตอบสนองของ SSE ไม่ได้ตั้งค่าส่วนหัวความยาวเนื้อหาเพราะพวกเขาไม่สามารถรู้ได้ว่าจะส่งข้อมูลจำนวนเท่าใด แต่จะต้องใช้ส่วนหัวการเข้ารหัสการโอนย้าย [0] [1] สิ่งที่ช่วยให้สามารถเชื่อมต่อสตรีมได้ หมายเหตุ: หากคุณไม่เพิ่มเซิร์ฟเวอร์ HTTP ที่มีความยาวเนื้อหาส่วนใหญ่จะตั้งค่าTransfer-Encoding: chunked;
ให้คุณ HTTP chunking เตือนและทำให้เกิดความสับสน
ความสับสนเกิดจากคำเตือนที่ค่อนข้างคลุมเครือในส่วน Notes ของคำอธิบาย W3 EventSource:
ผู้เขียนยังได้รับการเตือนว่า HTTP chunking อาจมีผลกระทบเชิงลบที่ไม่คาดคิดต่อความน่าเชื่อถือของโปรโตคอลนี้ หากเป็นไปได้ควรปิดการใช้งาน chunking เพื่อให้บริการสตรีมเหตุการณ์เว้นแต่ว่าอัตราการส่งข้อความจะสูงพอสำหรับเรื่องนี้
ซึ่งจะนำไปสู่การเชื่อว่าTransfer-Encoding: chunked;
เป็นสิ่งที่ไม่ดีสำหรับ SSE อย่างไรก็ตาม: นี่ไม่จำเป็นต้องเป็นกรณีนี้เป็นเพียงปัญหาเมื่อเว็บเซิร์ฟเวอร์ของคุณกำลังทำการส่งข้อมูลให้คุณ (ไม่ทราบข้อมูลเกี่ยวกับข้อมูลของคุณ) ดังนั้นในขณะที่โพสต์ส่วนใหญ่จะแนะนำให้เพิ่มchunked_transfer_encoding off;
สิ่งนี้ไม่จำเป็นในกรณีทั่วไป [3]
บัฟเฟอร์ (ปัญหาจริง)
จุดที่ปัญหาส่วนใหญ่เกิดจากการบัฟเฟอร์ระหว่างแอพเซิร์ฟเวอร์กับไคลเอนต์ ตามค่าเริ่มต้น [4] Nginx ใช้
proxy_buffering on
(ดูที่uwsgi_buffering
และfastcgi_buffering
ขึ้นอยู่กับแอปพลิเคชันของคุณด้วย) และอาจเลือกที่จะบัฟเฟอร์ชิ้นที่คุณต้องการออกไปยังไคลเอนต์ของคุณ สิ่งนี้เป็นสิ่งที่ไม่ดีเนื่องจากลักษณะการแบ่งเวลาตามจริงของ SSE
อย่างไรก็ตามแทนที่จะเปลี่ยนproxy_buffering off
ทุกอย่างจะดีที่สุด (ถ้าคุณสามารถทำได้) เพื่อเพิ่มX-Accel-Buffering: no
ส่วนหัวการตอบกลับในรหัสเซิร์ฟเวอร์แอปพลิเคชันของคุณเพื่อปิดการบัฟเฟอร์เฉพาะสำหรับการตอบสนองแบบ SSE ไม่ใช่สำหรับการตอบกลับทั้งหมดที่มาจากแอปของคุณ เซิร์ฟเวอร์ โบนัส: นี้จะทำงานสำหรับและuwsgi
fastcgi
วิธีการแก้
ดังนั้นการตั้งค่าที่สำคัญจริงๆคือส่วนหัวการตอบกลับของแอปเซิร์ฟเวอร์:
Content-Type: text/event-stream;
Cache-Control: no-cache;
X-Accel-Buffering: no;
และอาจเป็นการใช้กลไกการ ping บางอย่างเพื่อให้การเชื่อมต่อไม่ได้ใช้งานนานเกินไป อันตรายของสิ่งนี้คือ Nginx จะปิดการเชื่อมต่อที่ไม่ได้ใช้งานตามที่กำหนดไว้โดยใช้การkeepalive
ตั้งค่า
[0] https://tools.ietf.org/html/rfc2616#section-3.6
[1] https://en.wikipedia.org/wiki/Chunked_transfer_encoding
[2] https://www.w3.org/TR / 2009 / WD-eventsource-20091029 / # text-event-stream
[3] https://github.com/whatwg/html/issues/515
[4] http://nginx.org/en/docs/http/ ngx_http_proxy_module.html # proxy_buffering
[5] https://tools.ietf.org/html/rfc7230#section-6.3
[6] https://gist.github.com/CMCDragonkai/6bfade6431e9ffb7fe88