خلاصة القول
استخدم أحداث المرسل من الخادم (Server-Sent Events - SSE) للتحديثات أحادية الاتجاه من الخادم إلى العميل مثل الإشعارات والخلاصات المباشرة. استخدم WebSocket للاتصال ثنائي الاتجاه مثل الدردشة والألعاب. SSE أبسط ويعمل عبر HTTP. WebSocket أكثر تعقيدًا ولكنه يدعم المراسلة ثنائية الاتجاه. تُطبق واجهة برمجة تطبيقات Modern PetstoreAPI كلاهما لحالات استخدام مختلفة في الوقت الفعلي.
مقدمة
تحتاج إلى تحديثات في الوقت الفعلي في واجهة برمجة التطبيقات (API) الخاصة بك. يتغير حالة حيوان أليف من "متاح" إلى "تم تبنيه" - يحتاج العملاء إلى معرفة ذلك على الفور. هل تستخدم WebSocket أم أحداث المرسل من الخادم (SSE)؟
يستخدم معظم المطورين WebSocket افتراضيًا لأنه "أكثر قوة". لكن SSE غالبًا ما يكون الخيار الأفضل. إنه أبسط، ويعمل عبر بروتوكول HTTP القياسي، ويتعامل مع إعادة الاتصال تلقائيًا. يضيف WebSocket تعقيدًا قد لا تحتاجه.
تُطبق واجهة برمجة تطبيقات Modern PetstoreAPI كلا البروتوكولين. SSE لتحديثات حالة الحيوانات الأليفة وإشعارات الطلبات. WebSocket للمزايدة في المزادات المباشرة والدردشة في الوقت الفعلي. يخدم كل بروتوكول حالات استخدام مختلفة.
في هذا الدليل، ستتعرف على الفروق بين SSE و WebSocket، وسترى أمثلة حقيقية من واجهة برمجة تطبيقات Modern PetstoreAPI، وستكتشف متى تستخدم كل بروتوكول.
ما هي أحداث المرسل من الخادم (SSE)؟
SSE هو بروتوكول قائم على HTTP لتدفق الأحداث من الخادم إلى العميل.
كيف تعمل SSE
يفتح العميل اتصالاً ويتلقى الأحداث فور حدوثها:
const eventSource = new EventSource('https://petstoreapi.com/v1/pets/notifications');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Pet update:', data);
};
eventSource.addEventListener('adoption', (event) => {
const data = JSON.parse(event.data);
console.log('Pet adopted:', data.petId);
});
يرسل الخادم الأحداث:
GET /v1/pets/notifications
Accept: text/event-stream
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
event: adoption
data: {"petId":"019b4132","userId":"user-456"}
event: status-change
data: {"petId":"019b4127","status":"AVAILABLE"}
ميزات SSE
1. اتصال أحادي الاتجاه
الخادم يدفع (يرسل) إلى العميل. لا يمكن للعميل إرسال رسائل عبر اتصال SSE (لكنه يمكنه استخدام طلبات HTTP العادية).
2. مبني على HTTP
يستخدم بروتوكول HTTP القياسي. يعمل عبر الخوادم الوكيلة (proxies) وجدران الحماية (firewalls) وشبكات توصيل المحتوى (CDNs).
3. إعادة الاتصال التلقائي
إذا انقطع الاتصال، يعيد المتصفح الاتصال تلقائيًا.
4. معرفات الأحداث للاستئناف
يمكن للخادم إرسال معرفات الأحداث. يستأنف العميل من آخر حدث تم استلامه:
id: 123
event: adoption
data: {"petId":"019b4132"}
id: 124
event: status-change
data: {"petId":"019b4127"}
إذا انقطع الاتصال، يرسل العميل رأس Last-Event-ID: 124 للاستئناف.
5. بروتوكول بسيط
تنسيق قائم على النص. سهل التصحيح باستخدام curl:
curl -N -H "Accept: text/event-stream" \
https://petstoreapi.com/v1/pets/notifications
قيود SSE
1. اتجاه واحد فقط
لا يمكن للعميل إرسال رسائل عبر SSE. يحتاج إلى طلبات HTTP منفصلة للاتصال من العميل إلى الخادم.
2. نصي فقط
يرسل SSE نصًا. يجب ترميز البيانات الثنائية بـ base64.
3. حدود اتصال المتصفح
تحد المتصفحات من اتصالات SSE لكل نطاق (عادةً 6). وهذا ليس مشكلة لمعظم التطبيقات.
4. لا يوجد ضغط مدمج
يعمل ضغط HTTP، ولكن لا يوجد ضغط على مستوى البروتوكول مثل WebSocket.
ما هو WebSocket؟
WebSocket هو بروتوكول ثنائي الاتجاه (full-duplex) عبر اتصال دائم.
كيف يعمل WebSocket
يمكن للعميل والخادم إرسال الرسائل في أي وقت:
const ws = new WebSocket('wss://petstoreapi.com/auctions/019b4132');
// Send message to server
ws.send(JSON.stringify({
type: 'bid',
amount: 500
}));
// Receive messages from server
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Auction update:', data);
};
ws.onclose = () => {
console.log('Connection closed');
// Manual reconnection logic needed
};
يمكن للخادم الإرسال في أي وقت:
{"type":"bid","userId":"user-456","amount":550}
{"type":"outbid","newAmount":550}
يمكن للعميل الإرسال في أي وقت:
{"type":"bid","amount":600}
{"type":"watch","petId":"019b4132"}
ميزات WebSocket
1. ثنائي الاتجاه
يمكن لكل من العميل والخادم إرسال الرسائل في أي وقت. اتصال حقيقي ثنائي الاتجاه.
2. زمن استجابة منخفض
اتصال دائم. لا يوجد حمل زائد لبروتوكول HTTP لكل رسالة. مثالي للألعاب والدردشة والتعاون المباشر.
3. دعم البيانات الثنائية
يمكن إرسال البيانات الثنائية مباشرة. لا حاجة لترميز base64.
4. بروتوكول مخصص
يستخدم ws:// أو wss:// (آمن). ليس HTTP بعد المصافحة الأولية.
5. قائم على الإطارات
الرسائل مؤطرة. يمكن إرسال رسائل جزئية وإعادة تجميعها.
قيود WebSocket
1. إعداد معقد
يتطلب خادم WebSocket. أكثر تعقيدًا من نقاط نهاية HTTP.
2. إعادة الاتصال اليدوية
لا يوجد إعادة اتصال تلقائي. يجب عليك تنفيذ منطق إعادة المحاولة.
3. مشاكل الوكيل
تحظر بعض الخوادم الوكيلة للشركات WebSocket. لا تفهم الخوادم الوكيلة HTTP بروتوكول ws://.
4. ذو حالة (Stateful)
يجب على الخادم تتبع الاتصالات. أصعب في التوسع من HTTP عديم الحالة (stateless).
5. لا توجد ميزات HTTP
لا يمكن استخدام التخزين المؤقت لـ HTTP، أو رموز الحالة، أو الرؤوس القياسية بعد المصافحة.
مقارنة جنبًا إلى جنب
| الميزة | SSE | WebSocket |
|---|---|---|
| الاتجاه | الخادم ← العميل | ثنائي الاتجاه |
| البروتوكول | HTTP | مخصص (ws://) |
| إعادة الاتصال | تلقائي | يدوي |
| دعم المتصفح | جميع المتصفحات الحديثة | جميع المتصفحات الحديثة |
| متوافق مع الوكيل | نعم | أحيانًا |
| التعقيد | بسيط | معقد |
| البيانات الثنائية | لا (نص فقط) | نعم |
| زمن الاستجابة | منخفض | منخفض جدًا |
| قابلية التوسع | عالية (عديم الحالة) | متوسطة (ذو حالة) |
| حالة الاستخدام | الإشعارات، الخلاصات | الدردشة، الألعاب، التعاون |
كيف تستخدم واجهة برمجة تطبيقات Modern PetstoreAPI كلاهما
تُطبق واجهة برمجة تطبيقات Modern PetstoreAPI كل من SSE و WebSocket لسيناريوهات مختلفة.
SSE لتحديثات الحيوانات الأليفة
نقطة النهاية: GET /v1/pets/notifications
const events = new EventSource(
'https://petstoreapi.com/v1/pets/notifications?userId=user-456'
);
events.addEventListener('adoption', (e) => {
const data = JSON.parse(e.data);
showNotification(`${data.petName} was adopted!`);
});
events.addEventListener('status-change', (e) => {
const data = JSON.parse(e.data);
updatePetStatus(data.petId, data.status);
});
تنفيذ الخادم:
app.get('/v1/pets/notifications', (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
const userId = req.query.userId;
// Subscribe to pet updates
const subscription = petUpdates.subscribe(userId, (event) => {
res.write(`event: ${event.type}\n`);
res.write(`data: ${JSON.stringify(event.data)}\n\n`);
});
req.on('close', () => {
subscription.unsubscribe();
});
});
حالات الاستخدام:
- تغيرات حالة الحيوان الأليف (متاح ← تم تبنيه)
- إشعارات الطلبات (تم وضعها، تم شحنها، تم تسليمها)
- تحديثات المخزون
- تغيرات الأسعار
WebSocket للمزادات المباشرة
نقطة النهاية: wss://petstoreapi.com/auctions/{auctionId}
const ws = new WebSocket('wss://petstoreapi.com/auctions/019b4132');
// Place bid
function placeBid(amount) {
ws.send(JSON.stringify({
type: 'bid',
amount
}));
}
// Receive updates
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
switch (msg.type) {
case 'bid':
updateCurrentBid(msg.amount, msg.userId);
break;
case 'outbid':
showOutbidNotification(msg.newAmount);
break;
case 'auction-end':
showAuctionResult(msg.winner);
break;
}
};
تنفيذ الخادم:
wss.on('connection', (ws, req) => {
const auctionId = req.params.auctionId;
const auction = auctions.get(auctionId);
ws.on('message', (data) => {
const msg = JSON.parse(data);
if (msg.type === 'bid') {
const result = auction.placeBid(msg.userId, msg.amount);
// Broadcast to all participants
auction.participants.forEach(participant => {
participant.send(JSON.stringify({
type: 'bid',
userId: msg.userId,
amount: msg.amount
}));
});
}
});
});
حالات الاستخدام:
- المزايدة في المزادات المباشرة
- الدردشة في الوقت الفعلي مع الدعم
- التخطيط التعاوني لرعاية الحيوانات الأليفة
- تحديثات المخزون المباشرة أثناء المبيعات
اختبار واجهات برمجة التطبيقات في الوقت الفعلي باستخدام Apidog
يدعم Apidog اختبار كل من واجهات برمجة تطبيقات SSE و WebSocket.
اختبار SSE
1. إنشاء طلب SSE:
GET https://petstoreapi.com/v1/pets/notifications
Accept: text/event-stream
2. التحقق من صحة الأحداث:
- التحقق من أنواع الأحداث
- التحقق من صحة حمولات JSON
- اختبار سلوك إعادة الاتصال
- التحقق من معرفات الأحداث
3. سيناريوهات الاختبار:
- انقطاع الاتصال
- إعادة تشغيل الخادم
- ترتيب الأحداث
- الاستئناف من آخر حدث
اختبار WebSocket
1. إنشاء اتصال WebSocket:
wss://petstoreapi.com/auctions/019b4132
2. إرسال رسائل اختبار:
{"type":"bid","amount":500}
{"type":"watch","petId":"019b4132"}
3. التحقق من صحة الاستجابات:
- التحقق من تنسيقات الرسائل
- اختبار التدفق ثنائي الاتجاه
- التحقق من معالجة الاتصال
- اختبار سيناريوهات الأخطاء
4. سيناريوهات الاختبار:
- اتصالات متزامنة متعددة
- ترتيب الرسائل
- مهلات الاتصال
- منطق إعادة الاتصال
متى تستخدم كل منهما
استخدم SSE عندما:
- تحديثات أحادية الاتجاه - يدفع الخادم للعميل، ولا يحتاج العميل إلى الإرسال مرة أخرى
- إعداد بسيط - تريد استخدام بنية HTTP التحتية القياسية
- إعادة الاتصال التلقائي - لا تريد تنفيذ منطق إعادة المحاولة
- متوافق مع الوكيل - تحتاج إلى العمل من خلال جدران الحماية للشركات
- الإشعارات - تحديثات الحالة، التنبيهات، الخلاصات المباشرة
أمثلة:
- إشعارات تبني الحيوانات الأليفة
- تحديثات حالة الطلب
- تغيرات المخزون
- تنبيهات الأسعار
- خلاصات الأخبار
استخدم WebSocket عندما:
- ثنائي الاتجاه - يرسل كل من العميل والخادم الرسائل بشكل متكرر
- زمن استجابة منخفض حرج - الألعاب، التعاون في الوقت الفعلي
- بيانات ثنائية - إرسال الصور، الصوت، الفيديو
- بروتوكول مخصص - تحتاج إلى تحكم كامل في تنسيق الرسائل
- تردد رسائل عالٍ - مئات الرسائل في الثانية
أمثلة:
- المزايدة في المزادات المباشرة
- الدردشة في الوقت الفعلي
- ألعاب متعددة اللاعبين
- التحرير التعاوني
- بث الفيديو المباشر
لا تستخدم WebSocket لمجرد أن:
- ❌ "إنه أكثر تقدمًا" - تعقيد بدون فائدة
- ❌ "الجميع يستخدمه" - غالبًا ما يكون SSE أبسط
- ❌ "إنه أسرع" - SSE سريع بما يكفي لمعظم حالات الاستخدام
- ❌ "إنه ثنائي الاتجاه" - هل تحتاج حقًا إلى ثنائي الاتجاه؟
الخاتمة
يمكّن كل من SSE و WebSocket الاتصال في الوقت الفعلي، ولكنهما مصممان لسيناريوهات مختلفة. يتفوق SSE في التحديثات أحادية الاتجاه من الخادم إلى العميل مع إعادة الاتصال التلقائي والتوافق مع HTTP. يبرز WebSocket في الاتصال ثنائي الاتجاه ومنخفض زمن الاستجابة.
توضح واجهة برمجة تطبيقات Modern PetstoreAPI كيفية استخدام كلا البروتوكولين بفعالية. SSE للإشعارات وتحديثات الحالة. WebSocket للمزادات المباشرة والدردشة. اختر بناءً على حالة الاستخدام الخاصة بك، وليس البروتوكول الذي يبدو "أفضل".
اختبر واجهات برمجة التطبيقات في الوقت الفعلي باستخدام Apidog لضمان عمل تطبيقات SSE و WebSocket بشكل صحيح عبر سيناريوهات مختلفة.
الأسئلة الشائعة
هل يمكن لـ SSE العمل عبر جدران الحماية للشركات؟
نعم. يستخدم SSE بروتوكول HTTP القياسي، لذلك فهو يعمل عبر الخوادم الوكيلة (HTTP proxies) وجدران الحماية. يستخدم WebSocket بروتوكولًا مخصصًا قد تحظره بعض الخوادم الوكيلة.
هل WebSocket أسرع من SSE؟
يتمتع WebSocket بزمن استجابة أقل قليلاً (لا يوجد حمل زائد لبروتوكول HTTP لكل رسالة)، ولكن بالنسبة لمعظم التطبيقات، يكون الفرق ضئيلًا. SSE سريع بما يكفي للإشعارات والخلاصات وتحديثات الحالة.
كيف تتعامل مع إعادة اتصال SSE؟
يتعامل المتصفح مع إعادة الاتصال تلقائيًا. أرسل معرفات الأحداث من الخادم، وسيستأنف العميل من آخر حدث تم استلامه باستخدام رأس Last-Event-ID.
هل يمكنك استخدام SSE مع تطبيقات الهاتف المحمول؟
نعم. يدعم نظامي iOS و Android SSE من خلال عملاء HTTP الأصليين أو المكتبات. يعمل SSE في أي مكان يعمل فيه HTTP.
ما هو أقصى وقت لاتصال SSE؟
لا يوجد حد صارم. يمكن أن تظل اتصالات SSE مفتوحة إلى أجل غير مسمى. قد يكون لبعض الخوادم الوكيلة أو موازنات التحميل مهلات (عادةً 30-60 ثانية)، ولكن المتصفح سيعيد الاتصال تلقائيًا.
هل يمكن لـ WebSocket إرسال بيانات ثنائية؟
نعم. يدعم WebSocket إطارات النص والبيانات الثنائية. يمكنك إرسال الصور أو الصوت أو أي بيانات ثنائية بدون ترميز base64.
كم عدد اتصالات SSE التي يمكن أن يمتلكها المتصفح؟
تحد المتصفحات من اتصالات SSE لكل نطاق (عادةً 6). نادرًا ما يكون هذا مشكلة - فمعظم التطبيقات تحتاج فقط إلى اتصالين أو ثلاثة من SSE.
هل تحتاج إلى خادم خاص لـ SSE؟
لا. يمكن لأي خادم HTTP التعامل مع SSE. ما عليك سوى تعيين الرؤوس الصحيحة (Content-Type: text/event-stream) والحفاظ على الاتصال مفتوحًا.
