مقابس الويب и SSE
1) قصير: ماذا ولماذا
WebSocket (WS/WSS) - ترقية اتصال HTTP إلى قناة مزدوجة كاملة. مناسب للدردشة والألعاب الحية والتعاون والقياس عن بعد ثنائي الاتجاه.
أحداث إرسال الخادم (SSE) - تدفق باتجاه واحد من الخادم إلى المتصفح (MIME 'النص/تدفق الحدث'). مثالي للمؤشرات والإشعارات والاقتباسات وتقدم المهمة. العميل - «EventSource».
- تحتاج إلى مدخلات من العميل في الوقت الفعلي (غالبًا كثيرًا) → WebSocket.
- فقط تحديثات الدفع من الخادم والتوافق والبساطة أكثر أهمية من SSE →.
2) الشبكة والبروتوكولات
2. 1 النقل والتوافق
WebSocket: يبدأ مثل HTTP 'GET... الترقية: جيب الويب '(HTTP/1. 1). بالنسبة HTTP/2، RFC 8441 (CONNECT + ': protocol = webcocket') ممكن، يعتمد الدعم على الوكيل. يعمل بالإضافة إلى TLS (WSS) - إلزامي في المبيعات.
SSE: استجابة HTTP الطويلة العادية («200 موافق») مع البث. يمر بشكل جيد عبر HTTP/1. 1/2/3، متوافقة مع CDN/proxy (إذا لم يتم إنهاء الوصلات الطويلة).
2. 2 الوكلاء/المتوازنون/CDN
تحقق: دعم الاتصالات طويلة الأمد، والخمول والإجازات، والجلسات اللزجة (إذا كانت الحالة على العقدة).
بالنسبة لـ WS: قم بتضمين "proxy _ read _ timeout' و" ترقية "الرؤوس وحدود كل اتصال.
بالنسبة لـ SSE، تأكد من أن الوكيل لا يخفف من الاستجابة (وإلا فلن يرى العميل الأحداث في الوقت المناسب).
3) نموذج الرسالة والتحكم في التدفق
مقبس ويب: نص أو إطارات ثنائية ؛ هناك «بينج/بونج»، ولكن لا يوجد ضغط خلفي مدمج - نفذ على التطبيق (قوائم الانتظار والنوافذ وسياسة الإسقاط).
SSE: أحداث نصية (UTF-8) ؛ والعميل قادر على إعادة الاتصال بالتأخير المدمج ؛ يمكن للخادم تحديد «retry:». هناك «id:» و «Last-Event-ID» لاستئنافها من الموضع المطلوب.
- اقتبس الرسائل الصادرة لكل عميل.
- الحد من طابور الأحداث غير المخطوطة ؛ على الفائض - التخلص من الأولوية/المجموع المنخفض.
- بالنسبة لـ WS، استخدم نافذة منزلقة و ACK على مستوى التطبيق.
4) موثوقية الاتصالات
4. 1 الكشف والحفظ
WS: إرسال 'ping' كل N ثانية ؛ فجوة المهلة - أعد الاتصال مع التراجع الأسي + الرحلات.
SSE: يرسل الخادم «تعليقات» ':\n' كنبضات قلب حتى لا يتم احتساب الاتصال عاطلاً ؛ العميل سيعيد الاتصال بنفسه
4. 2 استعادة التدفق
WS: احتفظ برسائل التعويض/التسلسل واطلب دلتا بعد إعادة الاتصال.
SSE: استخدم «id:» لكل حدث و «Last-Event-ID» في الطلب - يرسل الخادم الأحداث الفائتة.
5) التوثيق والإذن
حامل JWT في طلب URL (WS) غير آمن (تسريبات في جذوع الأشجار). استخدم رأسًا (عبر مصافحة HTTP الأساسية) أو ملفات تعريف الارتباط مع الأعلام «Secure» و «HttpOnly» و «SameSite».
يمكن توقيع mTLS (خاصة بالنسبة لـ B2B)، بالإضافة إلى التوقيع (HMAC) على الطلب الأصلي.
بالنسبة لـ SSE مع ملفات تعريف الارتباط، تذكر عن CORS ("Access-Control-Learn-Origin" و "Engine-Credicals').
دوران الرمز: لا تقطع التيار. Pass' ستنتهي صلاحيته قريبًا "→ سيعيد العميل فتح الاتصال بالرمز الجديد.
6) تنسيق البيانات وضغطها
WebSocket: تمكين تفريغ التصريح بعناية (وحدة المعالجة المركزية) ؛ تجنب الضغط على الأشكال المضغوطة بالفعل (Proto، Avro). الحمولة الثنائية أكثر اقتصادا من JSON.
SSE: هذا نص ؛ وبالنسبة للبيانات الكبيرة، أرسل وصلة إلى ملفات الموارد أو القطع ؛ gzip النقل لـ SSE - مناسب، ولكن راقب التخزين المؤقت بالوكالة/CDN.
7) التوسع والمروحة
7. 1 القياس الأفقي
حافظ على التطبيق خاليًا من العيوب لإعادة التشغيل. حالة الاتصال - في الطبقة الأمامية ؛ بيانات - من الوسيط.
هناك حاجة إلى التجزئة (التجزئة حسب الجلسة/المستخدم) إذا كانت هناك قوائم انتظار محلية.
المثل الأعلى هو الجبهة عديمة الجنسية: العقدة فقط متعددة الإرسال الاشتراكات ؛ الأحداث تأتي من حانة/فرعية مشتركة.
7. 2 حانة/فرعية ووسطاء
للحصول على مروحة واسعة، استخدم Kafka/NATS/Redis Streams.
تشترك طبقة «Fanout Gateway» في الموضوعات وتزعج العملاء عبر WS/SSE.
استخدم مفتاح التوجيه (على سبيل المثال، «معرف المستخدم»، «معرف المطابقة») لموازنة الحمل بين العقد.
8) تكوينات الإنتاج
8. 1 NGINX - WebSocket
nginx map $http_upgrade $connection_upgrade { default upgrade; '' close; }
server {
listen 443 ssl http2;
server_name ws. example. com;
location /ws {
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1. 1;
proxy_read_timeout 75s; # increase for long sessions proxy_send_timeout 15s;
proxy_pass http://ws-backend;
}
}
8. 2 NGINX - SSE (مهم لتعطيل التخزين المؤقت)
nginx location /events {
proxy_http_version 1. 1;
proxy_set_header Connection "";
proxy_buffering off; # is critical for proxy_cache off threads;
chunked_transfer_encoding on;
proxy_read_timeout 60m;
proxy_pass http://sse-backend;
}
8. 3 Kubernetes (شروح الدخول، دخول NGINX)
yaml metadata:
annotations:
nginx. ingress. kubernetes. io/proxy-read-timeout: "3600"
nginx. ingress. kubernetes. io/proxy-send-timeout: "3600"
nginx. ingress. kubernetes. io/enable-websocket: "true"
nginx. ingress. kubernetes. io/proxy-buffering: "off" # для SSE
9) أمثلة الكود
9. 1 عميل SSE (متصفح)
js const es = new EventSource("/events? channel=odds", { withCredentials: true });
es. addEventListener("message", (e) => {
const data = JSON. parse(e. data);
renderOdds(data);
});
es. addEventListener("error", () => {
//EventSource will reconnect itself; can be shown spinner
});
9. 2 خادم SSE (عقدة. js/Express)
js app. get('/events', (req, res) => {
res. writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});
res. write ('retry: 3000\n\n') ;//3s backoff to client
const sub = subscribe(req. query. channel, (event) => {
res. write(`id: ${event. id}\n`);
res. write(`event: message\n`);
res. write(`data: ${JSON. stringify(event. payload)}\n\n`);
});
req. on('close', () => sub. unsubscribe());
});
9. 3 عميل WebSocket (متصفح)
js const ws = new WebSocket("wss://ws. example. com/ws");
ws. onopen = () => ws. send(JSON. stringify({ type: "join", room: "chat-1" }));
ws. onmessage = (m) => handle(JSON. parse(m. data));
ws. onclose = () => scheduleReconnect();
10) الأمن والحد
تحديد المعدل لكل اتصال ولكل مستخدم: الحد من معدل الرسائل الواردة (WS) ومعدل التدفق الصادر (WS/SSE).
الحصة حسب عمر الاتصال وحركة المرور الإجمالية.
حد حجم الرسالة и الحد الأقصى للرسائل/الثانية.
مرشحات WAF/bot في مرحلة المصافحة ؛ الحماية من فيضانات الاتصال (العديد من الروابط القصيرة).
عزل المستأجر/مساحة الاسم: مجمعات الموارد الفردية.
11) إمكانية الملاحظة
المقاييس:- "connections _ active"، "connections _ new _ total"، "bytes _ in/out'،
- «messages _ in/out _ total»، «droped _ messages _ total»،
- «reconnects _ total», «latency _ delivery _ ms {p50, p95, p99}».
- السجلات: IP/UA، userId/tenantId، سبب الإغلاق («close _ code»)، المدة.
- التعقب: ربط الأحداث بالقيادة الأصلية (معرفات الارتباط) ؛ بالنسبة لـ WS، استخدم امتدادات الجزار «الافتراضية».
12) الفروق الدقيقة التشغيلية
إنهاء TLS بالقرب من العميل (CDN/edge).
دوران استباقي للاتصالات (رشيق) أثناء الاستنفاد: أعط العلم «إعادة الاتصال».
قص المفتاح لتوزيع القنوات «الساخنة» بالتساوي.
لقطات الحالة للمشتركين المتأخرين (لقطة + دلتا).
آخر مخبأ للقيمة (SSE على وجه الخصوص) - مفيد للعميل البارد.
13) الأنماط المضادة
قم ببث قطع ثنائية كبيرة عبر SSE أو JSON عبر WS - استخدم تنزيل HTTP والربط في الرسالة.
الإذن فقط وقت الاتصال وعدم إعادة التحقق من الجلسات الطويلة.
لزج عالمي بلا داع → اختلال التوازن والعقد الساخنة.
المهلات/الحدود → الاتصالات المجمدة تلتهم المسبح.
يصبح التخزين المؤقت لـ SSE/CDN → «الوقت الفعلي» دقائق تأخير.
عدم وجود تسلسل/تعويض → بعد إعادة الاتصال، يفقد العميل سلامة البيانات.
14) قائمة التنفيذ المرجعية
- يتم اختيار WS (ثنائي الاتجاه) أو SSE (أحادي الجانب).
- المهلات المعدة والحفظ وإعادة الاتصال (backoff + jitter).
- التسلسل/الأوفست المصمم و (لـ SSE) «معرف »/« آخر حدث - معرف».
- الحجم/السرعة/الوصلات/الحصص، حماية DoS محددة.
- تكوين الوكيل/الدخول: الترقية، proxy_buffering إيقاف (SSE)، اقرأ/أرسل المهلات.
- التحجيم: حانة/وسيط فرعي، بوابة مروحة، لزجة فقط إذا لزم الأمر.
- المصادقة: نقل رمزي آمن، تناوب بدون كسر.
- إمكانية الرصد: المقاييس، والسجلات، والآثار ؛ لوحات القيادة والتنبيهات.
- خطة الإصدار: وصلات تصريف رشيقة، تشير إلى العميل لإعادة الاتصال.
- أيام اللعبة: فواصل الشبكة، قطرات العقدة، الحمل الزائد للوسيط، RTTs الطويلة.
15) الأسئلة الشائعة
هل يمكن إخفاء SSE عبر CDN ؟
عادة لا: إنه تدفق شخصي. بالنسبة للقنوات العامة - ربما باستخدام TTL القصير والتسليم المقطوع، ولكن من السهل كسر «الوقت الفعلي».
هل يعمل WebSocket فوق HTTP/2/3 ؟
يبدأ متصفح WS HTTP/1. 1-ترقية ؛ يوجد RFC 8441 لـ h2، والدعم في الوكيل/الخادم مطلوب بشكل منفصل. مع h3 - في الحركة ؛ للبث، h3 لديها WebTransport، لكنها واجهة برمجة تطبيقات مختلفة.
gRPC مقابل WS للمتصفح ؟
المتصفح النظيف لا يقول gRPC ؛ بحاجة إلى gRPC-Web عبر المبعوث. بالنسبة لواجهات المستخدم التفاعلية، غالبًا ما يكون WS + REST أسهل.
16) المجاميع
WebSocket - عندما تحتاج إلى حوار في الوقت الفعلي وقناة مدمجة ثنائية الاتجاه.
SSE - عندما تحتاج إلى دفعة بسيطة وموثوقة من الخادم إلى العميل، فإن الحد الأدنى من التعقيد وإعادة الاتصال التلقائي.
النجاح في المبيعات هو المهلة والحدود الصحيحة، والتعافي من التعويض، والحانة/المروحة الفرعية، وإعدادات الوكيل الصحيحة، وإمكانية المراقبة الواضحة.