نبض القلب
ملاحظة: يجب أن تضيف تطبيقات الاتصال الدائم نبضة قلب، وإلا قد يتم قطع الاتصال قسراً من قبل أجهزة التوجيه بسبب عدم التواصل لفترة طويلة.
الوظيفة الرئيسية لنبضة القلب لها نقطتان رئيسيتان:
-
يقوم العميل بإرسال بيانات إلى الخادم في أوقات محددة، لمنع قطع الاتصال بسبب عدم التواصل لفترة طويلة والتي قد تؤدي إلى إغلاق الجدار الناري لبعض الأجهزة.
-
يمكن للخادم من خلال نبضة القلب التحقق مما إذا كان العميل متصلاً، إذا لم يرسل العميل أي بيانات خلال الوقت المحدد، يتم اعتبار العميل غير متصل. وهكذا يمكن الكشف عن أحداث انقطاع الاتصال للعميل بسبب ظروف قاسية (انقطاع التيار الكهربائي، فقدان الاتصال بالشبكة، إلخ).
القيمة الموصى بها لفترة نبضة القلب:
من الموصى به أن يرسل العميل نبضة القلب بفترة أقل من 60 ثانية، مثل 55 ثانية.
لا توجد متطلبات لصيغة بيانات نبضة القلب، يمكن للخادم التعرف عليها فقط.
مثال على نبضة القلب
<?php
use Workerman\Worker;
use Workerman\Timer;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
// فترة نبضة القلب 55 ثانية
define('HEARTBEAT_TIME', 55);
$worker = new Worker('text://0.0.0.0:1234');
$worker->onMessage = function(TcpConnection $connection, $msg) {
// تعيين خاصية lastMessageTime مؤقتًا للاتصال لتسجيل وقت استلام آخر رسالة
$connection->lastMessageTime = time();
// المنطق التجاري الآخر...
};
// بعد بدء العملية، إعداد مؤقت يعمل كل 10 ثوانٍ
$worker->onWorkerStart = function($worker) {
Timer::add(10, function() use($worker) {
$time_now = time();
foreach($worker->connections as $connection) {
// من الممكن أن لا يكون هذا الاتصال قد استقبل أي رسالة، لذا يتم تعيين lastMessageTime إلى الوقت الحالي
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// إذا كانت الفترة بين آخر تواصل تزيد عن فترة نبضة القلب، يعتبر العميل غير متصل، ويتم إغلاق الاتصال
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
$connection->close();
}
}
});
};
Worker::runAll();
التكوين أعلاه يعني أنه إذا لم يرسل العميل أي بيانات إلى الخادم لأكثر من 55 ثانية، فإن الخادم يعتبر العميل قد انقطع، ويغلق الاتصال ويشغل onClose.
إعادة الاتصال بعد الانقطاع (هام)
سواء كانت نبضة القلب من العميل أو من الخادم، فهناك احتمال لقطع الاتصال. على سبيل المثال، يتم إيقاف تشغيل جافا سكريبت عند تصغير المتصفح، أو عند التبديل إلى علامة تبويب أخرى، أو دخول الكمبيوتر في وضع السكون، أو تحولات الشبكة في الأجهزة المحمولة، وضعف الإشارة، أو إيقاف تشغيل الشاشة، أو تحويل تطبيق الهاتف إلى الخلفية، أو أعطال جهاز التوجيه، أو الانقطاع النشط لخدمة معينة، إلخ. خاصة في بيئات الشبكة الخارجية، حيث كثير من أجهزة التوجيه تقوم بتنظيف الاتصالات غير النشطة خلال دقيقة، وهذا هو السبب في التوصية بفترة نبضة القلب أقل من دقيقة.
من السهل جدًا قطع الاتصال في بيئة الشبكة الخارجية، لذلك يجب أن تكون إعادة الاتصال بعد الانقطاع وظيفة أساسية لتطبيقات الاتصال الدائم (يجب أن يتم ذلك من قبل العميل فقط، ولا يمكن للخادم القيام بذلك). على سبيل المثال، يحتاج WebSocket في المتصفح إلى مراقبة حدث onclose، وعند حدوث onclose، يجب إنشاء اتصال جديد (لتجنب الانهيار، يمكن تأجيل إنشاء الاتصال). بشكل أكثر صرامة، يجب أن يبدأ الخادم بإرسال بيانات النبض بشكل دوري، ويحتاج العميل إلى مراقبة بيانات نبضة القلب من الخادم للتحقق من تجاوز الوقت المحدد. إذا لم يتم استلام بيانات نبضة القلب من الخادم خلال الوقت المحدد، يجب اعتبار الاتصال قد انقطع، ويجب تنفيذ close لإغلاق الاتصال، وإعادة إنشاء اتصال جديد.