موجز
استخدم الأحداث المرسلة من الخادم (SSE) لتدفق استجابات واجهة برمجة التطبيقات عبر HTTP. أرسل Content-Type: text/event-stream واكتب الأحداث كـ data: {json}\n\n. تعمل SSE لتدفق استجابات الذكاء الاصطناعي، وتحديثات التقدم، والموجزات المباشرة. تستخدم واجهة برمجة تطبيقات متجر الحيوانات الأليفة الحديثة (Modern PetstoreAPI) SSE لتوصيات الحيوانات الأليفة بالذكاء الاصطناعي وتحديثات حالة الطلب.
مقدمة
تُنشئ واجهة برمجة التطبيقات الخاصة بك توصيات حيوانات أليفة بالذكاء الاصطناعي. تستغرق الاستجابة 10 ثوانٍ. هل تجعل المستخدمين ينتظرون، أم تدفق النتائج فور إنشائها؟
باستخدام الأحداث المرسلة من الخادم (SSE)، يمكنك تدفق الاستجابات في الوقت الفعلي. يرى المستخدمون النتائج فورًا عند إنشائها بواسطة الذكاء الاصطناعي، مما يخلق تجربة أفضل.
تستخدم واجهة برمجة تطبيقات متجر الحيوانات الأليفة الحديثة الأحداث المرسلة من الخادم (SSE) لتوصيات الحيوانات الأليفة بالذكاء الاصطناعي، وتحديثات حالة الطلب، وتغييرات المخزون.
إذا كنت تختبر واجهات برمجة التطبيقات المتدفقة، فإن Apidog يدعم اختبار SSE والتحقق منها.
أساسيات SSE
تعتبر SSE تدفقًا أحادي الاتجاه يعتمد على HTTP من الخادم إلى العميل.
تنسيق SSE
Content-Type: text/event-stream
Cache-Control: no-cache
data: {"message":"First chunk"}\n\n
data: {"message":"Second chunk"}\n\n
data: {"message":"Third chunk"}\n\n
كل حدث:
- يبدأ بـ
data: - يحتوي على الحمولة (payload)
- ينتهي بـ
\n\n(سطران جديدان)
الأحداث المسماة
event: recommendation
data: {"petId":"019b4132","score":0.95}
event: recommendation
data: {"petId":"019b4127","score":0.89}
event: complete
data: {"total":2}
معرفات الأحداث
id: 1
data: {"message":"First"}
id: 2
data: {"message":"Second"}
يمكن للعميل استئناف الاتصال من آخر معرف إذا انقطع الاتصال.
تطبيق خادم SSE
مثال Node.js/Express
app.get('/v1/pets/recommendations/stream', async (req, res) => {
// Set SSE headers
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
// Send recommendations as they're generated
const recommendations = await generateRecommendations(req.query.userId);
for (const rec of recommendations) {
res.write(`data: ${JSON.stringify(rec)}\n\n`);
await sleep(100); // Simulate streaming delay
}
// Send completion event
res.write(`event: complete\ndata: {"total":${recommendations.length}}\n\n`);
res.end();
});
مثال Python/FastAPI
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import json
import asyncio
app = FastAPI()
@app.get("/v1/pets/recommendations/stream")
async def stream_recommendations(user_id: str):
async def generate():
recommendations = await get_recommendations(user_id)
for rec in recommendations:
yield f"data: {json.dumps(rec)}\n\n"
await asyncio.sleep(0.1)
yield f"event: complete\ndata: {json.dumps({'total': len(recommendations)})}\n\n"
return StreamingResponse(
generate(),
media_type="text/event-stream",
headers={
"Cache-Control": "no-cache",
"Connection": "keep-alive"
}
)
تطبيق عميل SSE
جافاسكريبت/المتصفح
const eventSource = new EventSource(
'https://petstoreapi.com/v1/pets/recommendations/stream?userId=user-456'
);
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
displayRecommendation(data);
};
eventSource.addEventListener('complete', (event) => {
const data = JSON.parse(event.data);
console.log(`Received ${data.total} recommendations`);
eventSource.close();
});
eventSource.onerror = (error) => {
console.error('SSE error:', error);
eventSource.close();
};
خطاف React (React Hook)
import { useEffect, useState } from 'react';
function useSSE(url) {
const [data, setData] = useState([]);
const [complete, setComplete] = useState(false);
useEffect(() => {
const eventSource = new EventSource(url);
eventSource.onmessage = (event) => {
const item = JSON.parse(event.data);
setData(prev => [...prev, item]);
};
eventSource.addEventListener('complete', () => {
setComplete(true);
eventSource.close();
});
return () => eventSource.close();
}, [url]);
return { data, complete };
}
// الاستخدام
function Recommendations({ userId }) {
const { data, complete } = useSSE(
`https://petstoreapi.com/v1/pets/recommendations/stream?userId=${userId}`
);
return (
<div>
{data.map(rec => (
<PetCard key={rec.petId} pet={rec} />
))}
{!complete && <Spinner />}
</div>
);
}
كيف تستخدم Modern PetstoreAPI تقنية SSE
توصيات الحيوانات الأليفة بالذكاء الاصطناعي
تدفق التوصيات التي أنشأها الذكاء الاصطناعي:
GET /v1/pets/recommendations/stream?userId=user-456
Accept: text/event-stream
event: recommendation
data: {"petId":"019b4132","name":"Fluffy","score":0.95,"reason":"Matches your preference for cats"}
event: recommendation
data: {"petId":"019b4127","name":"Buddy","score":0.89,"reason":"Similar to pets you liked"}
event: complete
data: {"total":2,"processingTime":850}
تحديثات حالة الطلب
تدفق خطوات معالجة الطلب:
GET /v1/orders/019b4132/status/stream
Accept: text/event-stream
data: {"status":"payment_processing","timestamp":"2026-03-13T10:30:00Z"}
data: {"status":"payment_confirmed","timestamp":"2026-03-13T10:30:02Z"}
data: {"status":"preparing_shipment","timestamp":"2026-03-13T10:30:05Z"}
event: complete
data: {"status":"shipped","trackingNumber":"1Z999AA10123456784"}
تغييرات المخزون
تدفق تحديثات المخزون في الوقت الفعلي:
GET /v1/inventory/stream
Accept: text/event-stream
event: stock-change
data: {"petId":"019b4132","oldStock":5,"newStock":4}
event: price-change
data: {"petId":"019b4127","oldPrice":299.99,"newPrice":279.99}
انظر وثائق Modern PetstoreAPI SSE.
اختبار SSE باستخدام Apidog
Apidog يدعم اختبار SSE:
- إنشاء طلب SSE
- تعيين
Accept: text/event-stream - الاتصال وعرض الأحداث في الوقت الفعلي
- التحقق من صحة تنسيق الحدث
- اختبار إعادة الاتصال
أفضل الممارسات
1. تعيين رؤوس (Headers) مناسبة
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.setHeader('X-Accel-Buffering', 'no'); // Disable nginx buffering
2. إرسال نبضات القلب (Heartbeats)
للحفاظ على الاتصال نشطًا:
const heartbeat = setInterval(() => {
res.write(': heartbeat\n\n');
}, 15000);
res.on('close', () => clearInterval(heartbeat));
3. التعامل مع الأخطاء برشاقة
eventSource.onerror = (error) => {
if (eventSource.readyState === EventSource.CLOSED) {
// Connection closed, will auto-reconnect
} else {
// Other error
console.error('SSE error:', error);
}
};
4. استخدام معرفات الأحداث للاستئناف
let lastEventId = 0;
app.get('/stream', (req, res) => {
const startId = parseInt(req.headers['last-event-id'] || '0');
for (let i = startId + 1; i <= 100; i++) {
res.write(`id: ${i}\ndata: {"message":"Event ${i}"}\n\n`);
}
});
5. إغلاق الاتصالات
// العميل
eventSource.addEventListener('complete', () => {
eventSource.close();
});
// الخادم
res.on('close', () => {
// Cleanup resources
});
الخاتمة
SSE مثالية لتدفق استجابات واجهة برمجة التطبيقات. إنها أبسط من WebSocket للاتصال أحادي الاتجاه، وتعمل عبر HTTP، وتتعامل مع إعادة الاتصال تلقائيًا.
تستخدم واجهة برمجة تطبيقات متجر الحيوانات الأليفة الحديثة SSE لتدفق الذكاء الاصطناعي، وتحديثات الطلبات، والموجزات المباشرة. اختبر نقاط نهاية SSE باستخدام Apidog.
الأسئلة الشائعة
هل يمكن لـ SSE العمل عبر جدران الحماية للشركات؟
نعم، تستخدم SSE بروتوكول HTTP/HTTPS القياسي، لذا فهي تعمل عبر معظم جدران الحماية والوكلاء (proxies).
كم من الوقت يمكن أن تظل اتصالات SSE مفتوحة؟
إلى أجل غير مسمى، ولكن استخدم "نبضات القلب" كل 15-30 ثانية للحفاظ على الاتصالات نشطة عبر الوكلاء.
هل يمكنني إرسال بيانات ثنائية عبر SSE؟
لا، SSE مخصصة للنص فقط. قم بتشفير البيانات الثنائية باستخدام Base64 أو استخدم WebSocket بدلاً من ذلك.
هل تدعم SSE الاتصال ثنائي الاتجاه؟
لا، SSE هي من الخادم إلى العميل فقط. يستخدم العملاء طلبات HTTP العادية للاتصال من العميل إلى الخادم.
كم عدد اتصالات SSE التي يمكن أن يمتلكها المتصفح؟
تحد المتصفحات عدد اتصالات SSE لكل نطاق (عادةً 6). استخدم التعدد (multiplexing) أو WebSocket للعديد من الاتصالات.
