SMPP مقابل واجهات HTTP SMSC: أيّها ينبغي أن تتحدّث منصّتك؟
عندما تربط منصّة مراسلة بالعالم الخارجي، فأنت في الحقيقة تختار كيف تتحدّث إلى المشغّلين، وهناك إجابتان شائعتان في الاستخدام. الأولى هي SMPP، بروتوكول الاتصالات الثنائي الذي ينقل رسائل التطبيق إلى الشخص (A2P) منذ عقود. والثانية هي واجهة HTTP، الشكل نفسه من الطلب والاستجابة الذي يشغّل بقية الويب. وهما ليسا متنافسين بقدر ما هما أداتان لمهمّتين مختلفتين، والخلاصة الصادقة التي يتّجه إليها هذا الدليل هي أنّ أيّ شيء تسمّيه منصّة جادّة ينتهي به الأمر إلى التحدّث بكليهما. وفيما يلي ما يفصل بينهما فعليًا، ولماذا.
ما هو SMPP ولماذا لا يزال المشغّلون يستخدمونه
SMPP، أي بروتوكول Short Message Peer-to-Peer، هو بروتوكول ثنائي يُتحدّث به عبر اتصال TCP طويل العمر، عادةً على المنفذ 2775. فبدلًا من فتح اتصال جديد لكلّ رسالة، كما تفعل طلبات الويب، يُنشئ عميل SMPP جلسة دائمة تُسمّى bind، في أحد ثلاثة أوضاع: transmitter (إرسال فقط)، أو receiver (استقبال فقط)، أو transceiver (كلاهما على اتصال واحد). وبمجرّد الارتباط، يبثّ حزمًا ثنائية مضغوطة تُسمّى PDU: حزمة submit_sm لإرسال رسالة، وحزمة deliver_sm لاستقبال رسالة أو تقرير تسليم، وحزمة enquire_link بمثابة نبضة (heartbeat) لإبقاء الجلسة حيّة.
والسبب في أنّ المشغّلين وكبار المجمّعين ما زالوا يعتمدونه معياريًا يعود إلى الكفاءة عند الحجم الكبير. فالـbind الدائم يزيل عبء إنشاء الاتصال لكلّ رسالة، ويدعم SMPP آلية النوافذ (windowing): إذ يمكن للمرسل وضع عدّة رسائل قيد النقل قبل انتظار الإقرارات، فيستطيع bind واحد سليم أن يتحمّل من مئات إلى بضعة آلاف رسالة في الثانية. وهو مصمّم خصّيصًا لهذا المجال، بحقول أصلية لمعرّفات المرسِل، وترميز البيانات، وفترات الصلاحية، والتسليم المجدول، وأعلام التسليم المسجّل. وعندما يُقاس حجم حركتك بملايين الرسائل يوميًا، فإنّ تلك الكثافة والتحكّم ليسا ترفًا، بل هما الفرق بين خادم واحد وعشرة.
وثمن هذه القوّة هو التعقيد. فـSMPP محتفظ بالحالة، لذا عليك إدارة روابط bind، وإعادة الاتصال عند الانقطاع، والردّ على النبضات، واحترام النافذة، ومطابقة التقارير غير المتزامنة عبر معرّف الرسالة. كما أنّه يميل إلى طلب علاقة IP ثابتة، ولهذا كثيرًا ما تجلس روابط bind مع المشغّلين خلف قائمة سماح لعناوين IP أو شبكة VPN صغيرة بدلًا من الإنترنت المفتوح.
أين تناسب واجهات HTTP SMSC
تقوم واجهة HTTP بالمقايضة المعاكسة. فأنت ترسل طلبًا واحدًا لكلّ رسالة (أو لكلّ دفعة صغيرة) إلى عنوان URL، وتتلقّى استجابة واحدة بصيغة JSON أو نموذج، ولا توجد جلسة لصيانتها. والمصادقة رمز أو مفتاح في ترويسة، وتعود تقارير التسليم على هيئة استدعاءات webhook إلى عنوان URL تستضيفه أنت، ويمرّ كلّ ذلك عبر الجدران النارية وموازِنات الحمل العادية دون معالجة خاصّة. وبالنسبة للمطوّر، فإنّ ربط مورّد HTTP عمل بعد ظهيرة؛ أمّا ربط حزمة SMPP فمشروع.
وهذه البساطة تحديدًا هي سبب تكاثر موردي HTTP. فكثير من المزوّدين الإقليميين، ومجمّعي WhatsApp وRCS، والوافدين الأحدث في مجال CPaaS، يوفّرون HTTP أولًا وSMPP عند الطلب فقط أو لا يوفّرونه إطلاقًا. وبالنسبة للأحجام المنخفضة والمتوسّطة، أو لبلد تصل إليه عبر مورّد متخصّص واحد، فإنّ مسار HTTP ليس تنازلًا، بل هو الخيار المعقول. صحيح أنّ العبء لكلّ رسالة أعلى وسقف الإنتاجية الخام أدنى من bind مضبوط في SMPP، لكنّك توسّعه بالطريقة المملّة، أفقيًا، بإجراء مزيد من الطلبات المتزامنة؛ ولدى معظم مُعيدي البيع يفوق ذلك السقف حركتهم الفعلية بكثير.
والقيد الصادق هو التحكّم والاتساق. فكلّ مورّد HTTP يبتكر أسماء حقوله الخاصّة، وطريقته الخاصّة في التعبير عن Unicode والرسائل الطويلة، وصيغته الخاصّة لاستدعاء DLR. تحدّث إلى خمسة موردي HTTP، وتكون قد دمجت فعليًا خمسة منتجات مختلفة اختلافًا طفيفًا.
الفروق الحقيقية: الإنتاجية وDLR والترميز
ثلاثة تفاصيل تقنية تسبّب معظم الألم الواقعي، لذا يجدر أن نكون دقيقين بشأنها.
الإنتاجية والتحكّم في التدفّق. تحكم إنتاجية SMPP حجمُ النافذة وزمن الذهاب والإياب: فبنافذة من، لنقل، 10 حزم PDU غير مُقرَّة ووصلة سريعة، يدفع bind واحد حركة كبيرة، ويفرض المشغّلون معدّلًا متعاقدًا عليه يجب ألّا تتجاوزه وإلّا خنقوك. أمّا إنتاجية HTTP فيحكمها عدد الطلبات المتزامنة التي تجريها وحدّ المعدّل (rate limit) لدى المورّد، ويُعبَّر عنه عادةً بالطلبات في الثانية. والنتيجة العملية: يكافئ SMPP عددًا صغيرًا من الاتصالات الدائمة جيّدة الإدارة، بينما يكافئ HTTP مجموعة من العمّال (workers) يجرون استدعاءات متوازية. ويتغيّر تصميم طابور الانتظار والعمّال في منصّتك تبعًا لذلك.
تقارير التسليم. هنا تنكسر التكاملات الساذجة. ففي SMPP، ليس DLR استجابةً لطلب submit الخاصّ بك؛ بل يصل لاحقًا، دون طلب، على هيئة deliver_sm على الـbind الخاصّ بك، وعليك مطابقته بالرسالة الأصلية عبر المعرّف الذي خصّصه المشغّل وقت الإرسال. وإن لم تكن مُنصِتًا، أو فقدت الـbind، فقدت التقارير. وفي HTTP، يكون DLR استدعاءً يرسله المورّد بطريقة POST إلى webhook الخاصّ بك، ما يعني أنّ نقطة نهايتك يجب أن تكون قابلة للوصول، وعديمة الأثر عند التكرار (idempotent) لأنّ الموردين يعيدون المحاولة، وقادرة على المطابقة عبر مرجعك الخاصّ. المفهوم نفسه، مُسلَّم، فاشل، منتهٍ، مرفوض، مجهول، لكن آليّتان مختلفتان تمامًا لالتقاطه بموثوقية.
ترميز المحارف. الرسائل النصية لا ترحم هنا. فأبجدية GSM 03.38 تُدخِل 160 محرفًا في رسالة واحدة بسبع بتّات؛ وإن خرجت عنها (رمز تعبيري، أو كثير من المحارف المحرّكة أو غير اللاتينية) تتحوّل الرسالة إلى UCS-2، التي لا تسع سوى 70 محرفًا لكلّ جزء. ويُقسَّم النصّ الأطول إلى مقاطع مخيطة بترويسة بيانات المستخدم (UDH)، ويُحتسَب ثمن كلّ مقطع. ويعرض SMPP هذا مباشرةً عبر حقل data_coding ويتوقّع منك أن تُحسِن التعامل. وعادةً يحاول موردو HTTP تجريد ذلك، لكنّهم يفعلون بلا اتساق، والمورّد الذي يخفّض رسالة Unicode بصمت أو يخطئ في عدّ المقاطع سيكلّفك مالًا دون أن يُعلمك أو يشوّه نصّك. أيًّا كان البروتوكول، فالترميز أمر يجب أن تتولّاه منصّتك عمدًا، لا أن تأمل أن يصيبه المورّد.
لماذا تتحدّث المنصّة الجادّة كليهما
اجمع تلك الفروق، وتكتب الخلاصة نفسها بنفسها. فقد يكون أفضل مسار لك إلى بلد ما هو bind على SMPP مع مشغّل وطني؛ وقد يكون مسارك الوحيد إلى البلد التالي متخصّصًا في HTTP؛ وقد يكون احتياطيّك لكليهما مورّدًا ثالثًا على البروتوكول الذي يصادف أن يوفّره. وإن كانت منصّتك لا تتحدّث سوى واحد، فإنّ خيارات التوجيه لديك تُقطَع إلى النصف، وتصبح مفاوضاتك مع الموردين رهينة قيد تقني بدلًا من أن يقودها السعر وجودة التسليم.
لهذا تشغّل البوّابة الناضجة حزمة SMPP وعميل HTTP جنبًا إلى جنب، وتعرض عادةً كليهما لعملائها أيضًا: خادم SMPP يرتبط به العملاء التقنيّون، وواجهة HTTP لسائر العملاء. والقيمة الحقيقية للمنصّة ليست أيّ البروتوكولين، بل الطبقة فوقهما، محرّك التوجيه والفوترة وتوحيد تقارير التسليم، التي تجعل اختيار البروتوكول غير مرئيّ لمن يرسل رسالة. فمنصّة ذاتية الاستضافة مثل Smppcube توفّر خادم SMPP بمستوى المشغّل وواجهة HTTP معًا تحديدًا كي يقرّر المشغّل، لا البروتوكول، كيف تتدفّق الحركة. وإن كنت توازن تشغيل تلك الحزمة بنفسك، فإنّ دليل البوّابة ذاتية الاستضافة يغطّي الجانب التشغيلي.
محوّل مورّدين HTTP عامّ واحد (كيف يعمل فعليًا)
الفخّ في موردي HTTP، وهو أنّ كلّ واحد مختلف اختلافًا طفيفًا، قابل للحلّ، والحلّ نمط يجدر فهمه قبل الشراء أو البناء. فبدلًا من كتابة شيفرة مخصّصة لكلّ مورّد مبعثرة عبر قاعدة الشيفرة، تعرّف واجهة داخلية واحدة، شكلًا موحّدًا واحدًا لـ«أرسِل رسالة» و«هذا تقرير تسليم»، ثمّ تكتب لكلّ مورّد محوّلًا رفيعًا يترجم بين خصوصيات المورّد وذلك الشكل الداخلي.
ويمتلك كلّ محوّل الفروق تحديدًا: كيف يصادق هذا المورّد، وبماذا يسمّي حقلَي الوجهة والنصّ، وكيف يريد الإشارة إلى Unicode، وكيف يُفسَّر استدعاء DLR الخاصّ به إلى مجموعة الحالات المشتركة في المنصّة. وكلّ ما هو في الأعلى، طابور الانتظار والموجّه والفوترة والتقارير، لا يتحدّث إلّا مع الواجهة الداخلية ولا يعلم ولا يبالي أيّ مورّد خلفها. وعندئذٍ يصبح ضمّ مورّد HTTP جديد مسألة إعداد ومحوّل صغير، لا إعادة بناء؛ وإضافة موردي الصوت عبر API لاحقًا تتبع النمط نفسه بالضبط. هكذا تبقى المنصّة مفتوحة لعشرات الموردين الإقليميين دون أن تنهار تحت تبايناتهم، وهو التصميم الذي ينبغي لبوّابة ذاتية الاستضافة أن تطبّقه سلفًا كي لا تلمس شيفرة البروتوكول أبدًا لإضافة مسار.
أيّهما ينبغي أن تختار؟
إن كنت مُعيد بيع تربط أوّل مورّد لك وكان يوفّر HTTP، فابدأ من هناك: أسرع في التكامل، وسهل الاختبار، وكافٍ لإثبات عملك. أضِف SMPP حين يجعل الحجمُ، أو علاقةٌ مع مشغّل، أو عميل تقنيّ يريد الارتباط بك، الآليّةَ الإضافية جديرة بالعناء. وإن كنت مجمّعًا أو مشغّلًا يتعامل بأحجام جادّة وصفقات مباشرة مع المشغّلين، فإنّ SMPP ليس اختياريًا، بل هو اللغة التي يتحدّثها موردوك.
والنقطة المضادّة الصادقة لكلّ هذا: لا تختر بروتوكولًا على الإطلاق إن استطعت تجنّب ذلك. اختر منصّة تتحدّث كليهما سلفًا وتخفي الفرق، كي تذهب طاقتك إلى جودة المسارات والعملاء بدلًا من صيانة حزمة بروتوكول ثنائي. هذا هو جوهر شراء بوّابة بدلًا من بنائها، ويمكنك أن ترى أين يقع خيار ذاتيّ الاستضافة، مملوك بالكامل، في صفحة الأسعار. ينبغي أن يكون البروتوكول تفصيلًا تضبطه، لا جدارًا تبني عملك في مواجهته.
أسئلة
هل SMPP أفضل من واجهة HTTP لإرسال الرسائل النصية؟
لا أفضلية لأحدهما في المطلق؛ فهما يحلّان مشكلتين مختلفتين. فـSMPP بروتوكول اتصالات ثنائي مبني لحركة A2P مستدامة وعالية الإنتاجية عبر اتصال دائم، ولهذا يفضّله المشغّلون وكبار المجمّعين. أمّا واجهة HTTP فأبسط في التكامل، وودودة مع الجدران النارية، وكافية تمامًا للأحجام الأقلّ أو حين لا يوفّر المورّد سوى HTTP. والمنصّة الجادّة تتحدّث كليهما وتوجّه كلّ رسالة عبر الاتصال الذي يوفّره المورّد.
ما هو DLR، وهل يختلف بين SMPP وHTTP؟
DLR (تقرير التسليم) هو تأكيد المشغّل لما حدث للرسالة: مُسلَّمة، فاشلة، منتهية، مرفوضة. ففي SMPP يصل بشكل غير متزامن على الـbind نفسه، كحزمة deliver_sm، مرتبطًا عبر معرّف الرسالة. وفي HTTP يصل كاستدعاء webhook إلى عنوان URL تستضيفه، أو تستعلم أنت عن نقطة نهاية للحالة. المعلومة متشابهة؛ لكنّ آليّة التقاطها مختلفة تمامًا، ولهذا توحّد المنصّة كليهما في حالة داخلية واحدة.
هل أحتاج إلى تشغيل خادم SMPP خاصّ بي لإعادة بيع الرسائل؟
للاتصال بالمشغّلين في الأعلى، تعمل عادةً كعميل SMPP يرتبط (bind) بالـSMSC لديهم. ولكي يرسل عملاؤك عبرك بواسطة SMPP، تشغّل أيضًا خادم SMPP يرتبطون به. يبدأ كثير من مُعيدي البيع بتقديم واجهة HTTP فقط لعملائهم، ثمّ يضيفون لاحقًا مستمِع SMPP للعملاء التقنيّين الذين يطلبونه. والمنصّة التي تأتي بكليهما تعفيك من كتابة حزمة بروتوكول.
هل يمكن لمنصّة واحدة الاتصال بموردي SMPP وHTTP معًا؟
نعم، وينبغي لها ذلك. فجداول التوجيه الحقيقية تمزج أنواع الموردين: bind على SMPP إلى مشغّل رئيسي، ومورّد HTTP كاحتياطي أو لبلد بعينه، وربّما مورّد HTTP ثانٍ لمسار متخصّص. ومهمّة المنصّة إخفاء تلك الفروق خلف طبقة توجيه واحدة، كي يختار المشغّل مسارًا بحسب السعر والجودة، لا بحسب البروتوكول.