الإمكانات
الجزء الصعب من العمل اللحظي، يعمل بالفعل
أي ميزة لحظية هي قليل من كود المنتج فوق كمّ كبير من آليات التوصيل: من المشترك، ومن المسموح له، ومن ما زال حاضرًا. PushCaster هو ذلك الجزء الثاني.
Channels
أربعة أنواع، والبادئة هي العقد
اسم القناة يحدّد سلوكه. البادئة تخبر المكتبة إن كان عليها طلب التخويل من خادمك، وإن كان عليها توقّع قائمة أعضاء، وإن كان عليها التشفير.
| البادئة | من يمكنه الاشتراك | فيمَ تُستخدم | التخويل |
|---|---|---|---|
| public | أي أحد يملك الـ app key. | حالة البناء، والنتائج الحيّة، والتدفّقات العامة. | بلا |
| private- | خادمك يقرّر، لكل مشترك على حدة. | أي شيء محصور بحساب أو مورد. | موقَّع |
| presence- | مخوَّل، ويحمل قائمة الأعضاء. | الغرف والجلسات، حيث العضوية نفسها هي الميزة. | موقَّع |
| private-encrypted- | مخوَّل؛ والحمولات يشفّرها عملاؤك. | حمولات ينبغي أن تبقى غير مقروءة لنا نحن أيضًا. | موقَّع |
cache- قنوات توصّل أحداث حيّة لكنها لا تعيد بثّ حالة محفوظة — انظر الفروق المعروفة.
التخويل
خادمك يبقى صاحب القرار
نحن لا نمنح اشتراكات private وpresence. تطبيقك هو من يمنحها، ويوقّع جوابه بالـ app سرّ الخاص بك. ونحن نتحقّق من التوقيع ولا شيء غير ذلك.
- نقطة واحدةPOST /pusher/auth يحتفظ بشكل طلبه وجوابه.
- قواعدك أنتهل يجوز لهذا المقبس الانضمام إلى هذا القناة؟ سؤال لا يجيب عنه إلا أنت.
- الهوية في presenceالنداء نفسه يعيد العضو id وكل ما ينبغي أن يراه بقية الأعضاء.
import Pusher from 'pusher'const pusher = new Pusher({ appId: process.env.PUSHCASTER_APP_ID, key: process.env.PUSHCASTER_KEY, secret: process.env.PUSHCASTER_SECRET, host: 'api-eu1.pushcaster.io', useTLS: true,})// Called by the client library whenever it subscribes to a// private-, presence- or private-encrypted- channel.app.post('/pusher/auth', (req, res) => { const { socket_id, channel_name } = req.body const user = req.session.user if (!user || !mayJoin(user, channel_name)) { return res.sendStatus(403) } res.send( pusher.authorizeChannel(socket_id, channel_name, { user_id: String(user.id), user_info: { name: user.name }, }), )})Webhooks
ما تراه طبقة المقابس، يسمعه الواجهة الخلفية عندك
الإشغال والعضوية لا يُريان إلا عند الاتصال. الويب هوك تعيدهما إليك موقَّعين — لتبدأ العمل حين يصل أول مشاهد وتتوقّف حين يغادر آخرهم.
| Event | ينطلق حين |
|---|---|
| channel_occupied | انضمّ أول مشترك إلى قناة فارغ. |
| channel_vacated | غادر آخر مشترك. |
| member_added | انضمّ أحدهم إلى قناة من نوع presence. |
| member_removed | غادر أحدهم قناة من نوع presence. |
| client_event | أرسل عميل حدث مباشرة إلى قناة. |
| cache_miss | طُلبت من قناة من نوع cache حالة لا يملكها. |
app.post('/pushcaster/webhooks', (req, res) => { const hook = pusher.webhook({ headers: req.headers, rawBody: req.rawBody }) // The signature is computed with your app secret, so an // unsigned or mismatched delivery never reaches your logic. if (!hook.isValid()) return res.sendStatus(401) for (const event of hook.getEvents()) { if (event.name === 'channel_occupied') startFeed(event.channel) if (event.name === 'channel_vacated') stopFeed(event.channel) } res.sendStatus(200)})المكتبات
لا يوجد SDK لـ PushCaster، عن قصد
PushCaster يتحدّث بروتوكول Pusher Channels على السلك، فتعمل المكتبات الرسمية معه دون تعديل. لا حزمة منّا تضيفها، ولا شيء منّا ينكسر حين نُصدر.
- pusher-js
- Laravel Echo
- pusher/pusher-php-server
- pusher-http-node
- Python
- Go
- Ruby
- Java
- Android
- iOS
- Flutter
- Unity
سطر التثبيت كاملًا: npm i pusher-js.
البنية التحتية
طبقتان، وcluster تختاره أنت
التوصيل يعمل على طبقة منفصلة عن الفوترة والإعداد، فتعطُّل الـ control plane يُضعف لوحة المعلومات دون أن يقطع التوصيل.
يعمل الآن
- eu1غرب أوروبا
- eu2وسط أوروبا
العناقيد عالية التوافر للمراسلة لا لـ presence: إن فُقد مخزن presence، تتدهور presence وعدّ الحاضرين بينما تواصل قنوات الـ public والـ private التوصيل. قراءة ذلك هنا أفضل من اكتشافه لاحقًا.
انظر كيف تسير عملية النشر