Migrating from Pusher.ar

الهجرة من Pusher إلى موجلي

موجلي بديل مباشر لقنوات Pusher. لأن موجلي يتحدّث نفس بروتوكول Pusher V1 الذي تعتمده جميع SDKs الرسمية لـ Pusher، فإن الهجرة تتم عبر تغيير في الإعدادات فقط — بدون إعادة كتابة كود، ولا SDKs جديدة، ولا تغييرات تكسر التوافق.

معظم الفِرق تكمل التبديل في أقل من 10 دقائق لكل بيئة.

هذا الدليل متاح أيضاً بالإنجليزية. نفس المحتوى، تخطيط LTR، وتعليقات كود إنجليزية.

لماذا الهجرة

أنت مرشّح للهجرة إلى موجلي إذا انطبق عليك واحد على الأقل مما يلي:

  • مستخدموك في الشرق الأوسط أو الخليج. أقرب مجموعة لـ Pusher موجودة في فرانكفورت أو مومباي، ما يضيف نحو 150-200 مللي ثانية على كل حدث. مجموعة موجلي في الرياض تقدّم زمن استجابة أقل من 50 مللي ثانية للسعودية والإمارات ومصر وقطر.
  • فاتورة Pusher أصبحت بنداً ملحوظاً. موجلي أرخص بنسبة 30٪ من سعر Pusher الشهري في كل خطة مدفوعة — وبما أن موجلي يمنح شهرين مجاناً على الفوترة السنوية بينما Pusher يحاسب 12 شهراً كاملاً بدون أي خصم سنوي، العملاء السنويون يوفّرون حتى 42٪.
  • عانيت من تجربة التصحيح في Pusher. وحدة التصحيح الحية في موجلي تبث كل حدث من تطبيقك في الزمن الحقيقي، مع تصفية حسب القناة/الحدث وإعادة تشغيل الأحداث بنقرة واحدة. اترك سطور console.log — اقرأ حركتك من لوحة التحكم.
  • تحتاج واجهة عربية لفريقك أو لمراجعي الامتثال. لوحة موجلي وفواتيرها وواجهة الإدارة كلها ثنائية اللغة EN/AR مع دعم RTL كامل.
  • متطلبات إقامة البيانات تستدعي مزوّداً مستضافاً في الشرق الأوسط. موجلي يعمل في السعودية وملتزم بمعايير نظام حماية البيانات الشخصية (PDPL).

إذا لم ينطبق أي من هذا، فـ Pusher منتج جيد — ابقَ هناك.

الهجرة في 5 دقائق

هناك بالضبط أربع قيم إعدادات تغيّرها. لا شيء غيرها.

الإعدادقيمة Pusherقيمة موجلي
wsHost (أو host)ws-mt1.pusher.com (أو مجموعتك في Pusher)ws-sa.mawjly.com
clustermt1 (أو مجموعتك في Pusher)sa
key<مفتاح_تطبيق_Pusher><مفتاح_تطبيق_موجلي>
secret<سر_Pusher> (للجانب الخلفي فقط)<سر_موجلي>

app_id يختلف أيضاً بين المزودين، لكنه يُستخدم فقط في الاستدعاءات من جانب الخادم وفي قسم بيانات الاعتماد بلوحة التحكم.

في الأسفل أمثلة دقيقة لتبديل الإعدادات لكل SDK رسمي تدعمه Pusher.

JavaScript / TypeScript (المتصفّح)

// قبل — Pusher
import Pusher from 'pusher-js';
 
const pusher = new Pusher('YOUR_KEY', {
  cluster: 'mt1',
});
// بعد — موجلي
import Pusher from 'pusher-js';
 
const pusher = new Pusher('YOUR_MAWJLY_KEY', {
  wsHost: 'ws-sa.mawjly.com',
  cluster: 'sa',
  forceTLS: true,
});

هذا كل شيء. subscribe() وbind() وقنوات presence- والقنوات المشفّرة كلها تعمل بشكل متطابق.

React (مع نفس pusher-js)

إذا كنت تغلّف pusher-js داخل React hook أو context، فقط الـ constructor يتغيّر. كود الـ hook لديك يظل كما هو:

// قبل
const pusher = new Pusher(KEY, { cluster: 'mt1' });
 
// بعد
const pusher = new Pusher(KEY, {
  wsHost: 'ws-sa.mawjly.com',
  cluster: 'sa',
  forceTLS: true,
});

PHP — pusher/pusher-php-server

// قبل
$pusher = new Pusher\Pusher('KEY', 'SECRET', 'APP_ID', [
    'cluster' => 'mt1',
    'useTLS'  => true,
]);
// بعد
$pusher = new Pusher\Pusher('KEY', 'SECRET', 'APP_ID', [
    'host'    => 'ws-sa.mawjly.com',
    'cluster' => 'sa',
    'useTLS'  => true,
]);

Laravel + pusher-php-server (البث Broadcasting)

في config/broadcasting.php:

// قبل
'pusher' => [
    'driver' => 'pusher',
    'key'    => env('PUSHER_APP_KEY'),
    'secret' => env('PUSHER_APP_SECRET'),
    'app_id' => env('PUSHER_APP_ID'),
    'options' => [
        'cluster' => env('PUSHER_APP_CLUSTER'),
        'useTLS'  => true,
    ],
],
// بعد
'pusher' => [
    'driver' => 'pusher',
    'key'    => env('MAWJLY_APP_KEY'),
    'secret' => env('MAWJLY_APP_SECRET'),
    'app_id' => env('MAWJLY_APP_ID'),
    'options' => [
        'host'    => 'ws-sa.mawjly.com',
        'cluster' => 'sa',
        'useTLS'  => true,
    ],
],

Laravel Echo (الواجهة الأمامية)

// قبل
window.Echo = new Echo({
  broadcaster: 'pusher',
  key: import.meta.env.VITE_PUSHER_APP_KEY,
  cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
  forceTLS: true,
});
// بعد
window.Echo = new Echo({
  broadcaster: 'pusher',
  key: import.meta.env.VITE_MAWJLY_APP_KEY,
  wsHost: 'ws-sa.mawjly.com',
  cluster: 'sa',
  forceTLS: true,
});

Python — pusher

# قبل
import pusher
p = pusher.Pusher(
    app_id='APP_ID', key='KEY', secret='SECRET',
    cluster='mt1', ssl=True,
)
# بعد
import pusher
p = pusher.Pusher(
    app_id='APP_ID', key='KEY', secret='SECRET',
    host='ws-sa.mawjly.com', cluster='sa', ssl=True,
)

Ruby — pusher

# قبل
Pusher.app_id = 'APP_ID'
Pusher.key = 'KEY'
Pusher.secret = 'SECRET'
Pusher.cluster = 'mt1'
 
# بعد
Pusher.app_id = 'APP_ID'
Pusher.key = 'KEY'
Pusher.secret = 'SECRET'
Pusher.host = 'ws-sa.mawjly.com'
Pusher.cluster = 'sa'

Node.js — pusher

// قبل
const Pusher = require('pusher');
const pusher = new Pusher({
  appId: 'APP_ID',
  key: 'KEY',
  secret: 'SECRET',
  cluster: 'mt1',
  useTLS: true,
});
// بعد
const Pusher = require('pusher');
const pusher = new Pusher({
  appId: 'APP_ID',
  key: 'KEY',
  secret: 'SECRET',
  host: 'ws-sa.mawjly.com',
  cluster: 'sa',
  useTLS: true,
});

Go — pusher-http-go

// قبل
client := pusher.Client{
    AppID: "APP_ID", Key: "KEY", Secret: "SECRET",
    Cluster: "mt1", Secure: true,
}
 
// بعد
client := pusher.Client{
    AppID: "APP_ID", Key: "KEY", Secret: "SECRET",
    Host: "ws-sa.mawjly.com", Cluster: "sa", Secure: true,
}

.NET — PusherServer

// قبل
var options = new PusherOptions {
    Cluster = "mt1",
    Encrypted = true,
};
var pusher = new Pusher("APP_ID", "KEY", "SECRET", options);
// بعد
var options = new PusherOptions {
    HostName = "ws-sa.mawjly.com",
    Cluster = "sa",
    Encrypted = true,
};
var pusher = new Pusher("APP_ID", "KEY", "SECRET", options);

هجرة Webhooks

webhooks في Pusher تُضبط من لوحته. webhooks في موجلي تُضبط من تطبيق موجلي ← تبويب Webhooks. شكل البيانات (Payload) متطابق (بروتوكول Pusher V1)، لذا كود استقبال الـ webhook لديك لا يتغيّر.

دوّن وجهات webhooks في Pusher

افتح Pusher ← App ← Webhooks. دوّن الـ URL، والأحداث المشترك بها (channel_occupied / channel_vacated / member_added / member_removed / client_event)، وسر التوقيع إن كنت تتحقق من التواقيع.

أعِد إنشاءها في موجلي

في لوحة موجلي، اذهب إلى تطبيقك ← Webhooks ← “إضافة webhook”. الصق نفس الـ URL، اختر نفس الأحداث. سيُصدر موجلي سرّ توقيع جديداً.

تحقّق من التواقيع (إن كنت تفعل ذلك)

webhooks موجلي موقّعة بـ HMAC-SHA256 على الـ body الخام، بسرّ تطبيقك. اسم الترويسة X-Pusher-Signature (محتفظ بنفس اسم Pusher عمداً)، لذا أي كود تحقّق من التواقيع كان يعمل مع Pusher يستمر في العمل — يتغيّر فقط السرّ.

اختبر التسليم

في لوحة موجلي، اضغط “Test fire” على webhook الجديد. سترى حالة التسليم، الـ response body، وزر إعادة تشغيل بنقرة واحدة إن فشل.

هجرة القنوات المشفّرة

القنوات المشفّرة (private-encrypted-*) مشفّرة من طرف لطرف بـ مفتاح رئيسي أنت تزوّده. انقل نفس المفتاح الرئيسي إلى تطبيق موجلي:

  1. لوحة موجلي ← التطبيق ← تبويب Keys ← “Encryption master key” ← الصق مفتاحك الحالي من Pusher.
  2. كود الجانب العميل لا يتغيّر — pusher-js سيفك التشفير بنفس المفتاح.

إذا لم يكن لديك مفتاح حالي (أعددت القنوات المشفّرة منذ زمن ولم تحفظه)، يمكنك توليد واحد جديد من لوحة موجلي. المشتركون الحاليون في القناة المشفّرة سيحتاجون إلى تحديث اتصالهم لاستقبال الرسائل الجديدة.

هجرة قنوات الحضور

قنوات الحضور تعمل بشكل متطابق. نقطة التحقّق لديك توقّع socket_id:channel_name:channel_data بـ HMAC-SHA256 لسر تطبيقك — نفس الخوارزمية التي يستخدمها Pusher، نفس الشكل الذي يتحقّق منه موجلي. لا حاجة لأي تغيير عدا قيم الإعدادات الأربع أعلاه.

إذا واجهت 403 بعد الهجرة، استخدم مختبِر استدعاء التحقّق (Auth callback tester) في لوحة موجلي ← التطبيق ← تبويب Keys. يستدعي نقطة التحقّق لديك بنفس الـ POST الموقّع الذي يرسله pusher-js ويخبرك بما هو خاطئ (حقل auth مفقود، مفتاح خاطئ، توقيع غير صحيح، إلخ).

قائمة ما قبل الهجرة

قبل أن تقلب متغيرات البيئة في الإنتاج، افعل هذا بالترتيب:

  1. أنشئ تطبيقك في موجلي. سجّل، أنشئ تطبيقاً، احفظ بيانات الاعتماد. دوّن app_id وkey وsecret و(إن كنت تستخدمه) المفتاح الرئيسي للتشفير.
  2. هاجِر webhooks (انظر أعلاه) لتصل الأحداث التي تطلقها بعد التبديل إلى نفس الوجهات.
  3. اختبر في staging. اضبط القيم الأربع في بيئة التجربة وتأكد من أن الدردشة/الإشعارات/اللوحات تعمل.
  4. قارن زمن الاستجابة. افتح وحدة التصحيح الحية، أرسل بضعة أحداث، شاهد كم تظهر بسرعة. من الخليج، توقّع أقل من 50 مللي ثانية متوسط.
  5. تحقّق من نقطة التحقّق. استخدم مختبِر استدعاء التحقّق في لوحة موجلي للتأكد من أن قنوات الحضور/الخاصة ستعمل.

التبديل في الإنتاج

أنظف تبديل هو إجراؤه في نشر واحد لكل بيئة — غيّر القيم الأربع معاً. لا حاجة لتشغيل Pusher وموجلي بالتوازي.

إن أردت أمان إضافي، يمكنك جعل تبويب المتصفح نفسه يشترك في كلا المزوّدين مؤقتاً ومقارنة تسليم الأحداث — لكن في الواقع، بما أن البروتوكول متطابق، هذا مبالغة. التغيير مكافئ وظيفياً.

خطة التراجع

إذا حدث شيء غير متوقع، التراجع متماثل: أعِد القيم الأربع إلى بيانات اعتماد Pusher وأعد النشر. حساب Pusher لديك لم يُمَس طوال العملية.

لهذا السبب نوصي بإبقاء حساب Pusher نشطاً لمدة 7 أيام على الأقل بعد التبديل. ألغِه عندما تكون واثقاً.

حاسبة التكلفة

استخدم الحاسبة التفاعلية لتقدير فاتورتك بحسب حجم رسائلك ومستوى اتصالاتك المتزامنة الحالي. الحاسبة تستخدم حدود الخطط الفعلية وتعرض التوفير السنوي مقارنةً بـ Pusher.

رصيد الهجرة

إذا كنت تنتقل من Pusher وكان مجموع فواتيرك في آخر 3 أشهر يتجاوز 200 دولار، راسلنا على hello@mawjly.com ومرفقاً نسخة. سنضيف رصيداً لحسابك في موجلي يصل إلى شهر مجاني لتغطية تكلفة التبديل.

أسئلة شائعة

هل سيعمل إصدار pusher-js / pusher-php-server الحالي لديّ؟

أي إصدار صدر بعد بداية 2018 يدعم خيار wsHost / host. إن كنت على إصدار قديم جداً (2017 أو أقدم)، حدّث SDK لـ Pusher أولاً — التغيير متوافق مع الإصدارات السابقة.

هل أحتاج لتغيير تسمية القنوات؟

لا. اصطلاحات بادئات القنوات private- وpresence- وprivate-encrypted- جزء من بروتوكول Pusher وموجلي يحترمها كلها.

ماذا يحدث للأحداث في الطريق وقت التبديل؟

عندما تنشر بإعدادات جديدة، عملاؤك يعيدون الاتصال بموجلي. الأحداث المنشورة إلى Pusher بعد تلك اللحظة لا تذهب لأي مكان من ناحية موجلي — والعكس صحيح. لذا إما:

  • صرّف ناشري Pusher أولاً (دع الطوابير في الطريق تنتهي)، ثم انشر.
  • أو اقبل ثوانٍ قليلة من الفجوة (مقبول للدردشة/الإشعارات، غير مقبول للتدفقات المرتبة).

هل يمكنني الاستمرار باستخدام لوحة Pusher للتحليلات؟

Pusher سيُظهر تحليلات الأحداث التي تستمر في إرسالها إليه فقط. بعد التبديل، كل تحليلاتك في الزمن الحقيقي تعيش في لوحة موجلي (الرسوم البيانية لكل تطبيق تحت تبويب Analytics).

هل يدعم موجلي نفس SDKs العملاء التي يدعمها Pusher؟

نعم — كل SDK عميل تدعمه Pusher رسمياً يعمل دون تغيير: pusher-js و pusher-websocket-swift و pusher-websocket-java (Android) و pusher-websocket-react-native، إضافة إلى مكتبات الخادم المذكورة أعلاه.

ماذا عن Pusher Beams (إشعارات الموبايل)؟

موجلي v1 لا يتضمن مكافئاً لـ Beams. إن كنت تستخدم Pusher Beams، أبقِ ذلك الحساب نشطاً بجوار موجلي. سنقيّم إضافة منتج مماثل بناءً على طلب العملاء — أعلِمنا.

ماذا عن إضافات Pusher Channels المحدّدة (حدود معدّل القناة، قوائم IP المسموحة)؟

كلها قابلة للضبط لكل تطبيق في تبويب Settings في موجلي. حدود معدّل القناة جزء من خطة الاشتراك (انظر الأسعار).

محتاج مساعدة؟

الهجرة بسيطة عمداً، لكن إن واجهت شيئاً غير متوقع، راسل support@mawjly.com بـ SDK وإصداره الذي تستخدمه وسنرد خلال يوم عمل واحد. معظم أسئلة الهجرة تُجاب في أقل من ساعة.

لهجرات الفِرق (تطبيقات إنتاج متعدّدة، fan-out معقّد لـ webhooks)، نقدّم مكالمة مجانية لمدة 30 دقيقة — رد على بريد التسجيل أو اكتب إلى hello@mawjly.com.