Kalp Atışı
Dikkat: Uzun bağlantı uygulamaları kalp atışı eklemelidir, aksi takdirde bağlantı uzun süre iletişim olmadığından dolayı yönlendirici düğümler tarafından zorla kapatılabilir.
Kalp atışının ana işlevleri şunlardır:
-
Müşteri, belirli aralıklarla sunucuya veri gönderir, böylece bağlantı uzun süre iletişim olmadığı için bazı düğümlerin güvenlik duvarları tarafından kapatılmasını önler.
-
Sunucu, kalp atışı aracılığıyla müşterinin çevrimiçi olup olmadığını belirleyebilir. Eğer müşteri belirlenen süre içerisinde herhangi bir veri göndermezse, müşteri çevrimdışı olarak kabul edilir. Bu, müşterinin aşırı durumlar (elektriğin kesilmesi, bağlantının kopması vb.) nedeniyle çevrimdışı kalma olaylarını tespit edebilir.
Kalp atışı aralığı önerilen değer:
Müşterinin kalp atışı aralığının 60 saniyeden az olması önerilir, örneğin 55 saniye.
Kalp atışının veri formatı için herhangi bir gereklilik yoktur, sunucu tarafından tanınması yeterlidir.
Kalp Atışı Örneği
<?php
use Workerman\Worker;
use Workerman\Timer;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
// Kalp atışı aralığı 55 saniye
define('HEARTBEAT_TIME', 55);
$worker = new Worker('text://0.0.0.0:1234');
$worker->onMessage = function(TcpConnection $connection, $msg) {
// connection için geçici bir lastMessageTime özelliği ayarlayın, son mesajın alındığı zamanı kaydetmek için
$connection->lastMessageTime = time();
// Diğer iş mantığı...
};
// Proses başlatıldığında 10 saniyede bir çalışan bir zamanlayıcı ayarlayın
$worker->onWorkerStart = function($worker) {
Timer::add(10, function()use($worker){
$time_now = time();
foreach($worker->connections as $connection) {
// Bu bağlantının daha önce mesaj almadığı durumlarda, lastMessageTime'ı mevcut zaman olarak ayarlayın
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// Son iletişim zamanı aralığı kalp atışı aralığından büyükse, müşteri çevrimdışı olarak kabul edilir ve bağlantı kapatılır
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
$connection->close();
}
}
});
};
Worker::runAll();
Yukarıdaki yapılandırma, eğer müşteri 55 saniye boyunca sunucuya herhangi bir veri göndermediyse, sunucunun müşterinin çevrimdışı olduğunu kabul edecek şekilde ayarlanmıştır ve sunucu bağlantıyı kapatır ve onClose tetiklenir.
Bağlantı Kesilmesi ve Yeniden Bağlanma (Önemli)
Müşteri kalp atışı gönderdiğinde veya sunucu kalp atışı gönderdiğinde bağlantının kesilme ihtimali her zaman vardır. Örneğin, tarayıcıda en küçük ekran küçültüldüğünde JavaScript duraklatılır, tarayıcı başka bir sekmeye geçildiğinde JavaScript duraklatılır, bilgisayar uyku moduna geçerse, mobil cihaz ağ değiştirirse, sinyal zayıflarsa, telefon ekranı kapanırsa, telefon uygulaması arka plana geçerse, yönlendirici arızası olursa veya iş amaçlı bağlantı manuel olarak kesilirse. Özellikle dış ağ ortamında karmaşık olduğu için, birçok yönlendirme düğümü 1 dakika içinde aktif olmayan bağlantıları temizler; bu da kalp atışı aralığının 1 dakikadan az olması önerilmektedir.
Dış ağ ortamında bağlantının kolayca kesilmesi nedeniyle, bağlantı kesilmesi ve yeniden bağlanma, uzun süreli bağlantı uygulamalarında gerekli bir işlevdir (bağlantı kesilmesi ve yeniden bağlanma yalnızca müşteri tarafından yapılabilir, sunucu bunu gerçekleştiremez). Örneğin, tarayıcı websocket'in onclose olayını dinlemesi gerekir, onclose meydana geldiğinde yeni bir bağlantı kurmalıdır (çökmeyi önlemek için bağlantının gecikmeli olarak kurulması önerilir). Daha katı bir şekilde, sunucu da düzenli olarak kalp atışı verileri göndermelidir ve müşteri, sunucunun kalp atışı verilerini zaman aşımına uğrayıp uğramadığını düzenli olarak kontrol etmelidir. Belirlenen sürede sunucudan kalp atışı verisi alınmadığında, bağlantının kesildiği kabul edilmeli ve close ile bağlantı kapatılmalı ve yeni bir bağlantı kurulmalıdır.