WebSocket ضد Server-Sent Events: أيهما أفضل لواجهات برمجة التطبيقات في الوقت الفعلي؟

Ashley Innocent

Ashley Innocent

13 مارس 2026

WebSocket ضد Server-Sent Events: أيهما أفضل لواجهات برمجة التطبيقات في الوقت الفعلي؟

Apidog للمؤسسات

نشر محلي

SSO & RBAC

متوافق مع SOC 2

استكشاف Apidog Enterprise

خلاصة القول

استخدم أحداث المرسل من الخادم (Server-Sent Events - SSE) للتحديثات أحادية الاتجاه من الخادم إلى العميل مثل الإشعارات والخلاصات المباشرة. استخدم WebSocket للاتصال ثنائي الاتجاه مثل الدردشة والألعاب. SSE أبسط ويعمل عبر HTTP. WebSocket أكثر تعقيدًا ولكنه يدعم المراسلة ثنائية الاتجاه. تُطبق واجهة برمجة تطبيقات Modern PetstoreAPI كلاهما لحالات استخدام مختلفة في الوقت الفعلي.

مقدمة

تحتاج إلى تحديثات في الوقت الفعلي في واجهة برمجة التطبيقات (API) الخاصة بك. يتغير حالة حيوان أليف من "متاح" إلى "تم تبنيه" - يحتاج العملاء إلى معرفة ذلك على الفور. هل تستخدم WebSocket أم أحداث المرسل من الخادم (SSE)؟

يستخدم معظم المطورين WebSocket افتراضيًا لأنه "أكثر قوة". لكن SSE غالبًا ما يكون الخيار الأفضل. إنه أبسط، ويعمل عبر بروتوكول HTTP القياسي، ويتعامل مع إعادة الاتصال تلقائيًا. يضيف WebSocket تعقيدًا قد لا تحتاجه.

تُطبق واجهة برمجة تطبيقات Modern PetstoreAPI كلا البروتوكولين. SSE لتحديثات حالة الحيوانات الأليفة وإشعارات الطلبات. WebSocket للمزايدة في المزادات المباشرة والدردشة في الوقت الفعلي. يخدم كل بروتوكول حالات استخدام مختلفة.

💡
إذا كنت تقوم بإنشاء أو اختبار واجهات برمجة تطبيقات في الوقت الفعلي، فإن Apidog يدعم اختبار كل من 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. التحقق من صحة الأحداث:

3. سيناريوهات الاختبار:

اختبار WebSocket

1. إنشاء اتصال WebSocket:

wss://petstoreapi.com/auctions/019b4132

2. إرسال رسائل اختبار:

{"type":"bid","amount":500}
{"type":"watch","petId":"019b4132"}

3. التحقق من صحة الاستجابات:

4. سيناريوهات الاختبار:

متى تستخدم كل منهما

استخدم SSE عندما:

أمثلة:

استخدم WebSocket عندما:

أمثلة:

لا تستخدم WebSocket لمجرد أن:

الخاتمة

يمكّن كل من 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) والحفاظ على الاتصال مفتوحًا.

ممارسة تصميم API في Apidog

اكتشف طريقة أسهل لبناء واستخدام واجهات برمجة التطبيقات