How to Implement Reliable Client Heartbeat Detection with GatewayWorker and WebSocket

This guide explains why heartbeat detection is essential for long‑living TCP connections, describes the GatewayWorker architecture, and provides step‑by‑step server and client configurations—including PHP and JavaScript code—to reliably detect client disconnections in WebSocket applications.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
How to Implement Reliable Client Heartbeat Detection with GatewayWorker and WebSocket

Introduction

To detect when a WebSocket client goes offline, a heartbeat mechanism is required. This guide shows how to configure the GatewayWorker framework for client‑initiated heartbeat detection.

GatewayWorker Overview

GatewayWorker is a PHP framework built on Workerman for rapid development of TCP long‑connection services (push notifications, IM, games, IoT, etc.). It follows a Gateway‑Worker model: the Gateway process maintains client connections and forwards data to BusinessWorker processes, which execute business logic (by default in Events.php) and push results back to clients. Gateways and BusinessWorkers can be deployed on separate machines for clustering.

WebSocket Basics

WebSocket provides full‑duplex communication over a single TCP connection. After an initial HTTP handshake, the server can push data to the client at any time.

Why Heartbeat Detection?

In normal disconnections the client sends a FIN packet, triggering the server’s onClose callback. In abnormal cases (power loss, network cut, router failure) the client cannot send FIN, so the server remains unaware of the drop. Periodic heartbeat messages allow the server to detect such silent disconnects promptly and invoke onClose. Firewalls that close idle sockets also necessitate regular heartbeats to keep the connection alive.

Heartbeat Detection Principle

The client sends a small payload (often JSON) every X seconds (recommended < 60 s). The server is configured with a timeout; if no data is received for X seconds, the server treats the client as offline, closes the connection, and fires onClose. This both prevents idle‑timeout closures and informs the server of abnormal drops.

Configuring Heartbeat in GatewayWorker

GatewayWorker supports two modes:

Client‑initiated heartbeat (recommended): the client sends data periodically; the server defines a timeout.

Server‑initiated heartbeat (not recommended): the server pushes heartbeat data to the client.

Client‑Initiated Heartbeat (Recommended)

Server Configuration

$gateway = new Gateway("Websocket://0.0.0.0:8585");
$gateway->pingInterval = 55;            // seconds between checks
$gateway->pingNotResponseLimit = 1;   // allowed missed intervals
$gateway->pingData = '';

The server will consider a client offline if pingInterval * pingNotResponseLimit = 55 seconds pass without any data from that client.

Client‑Side Heartbeat Example (JavaScript)

// 1. Connect to WS
var ws = new WebSocket('ws://127.0.0.1:9503/ss');
ws.onmessage = function (event) {
  let _obj = JSON.parse(event.data);
  if (_obj.msg_type == 'init') {
    send_heartbeat();
  }
  console.log('Message: ' + event.data);
};
function send_heartbeat() {
  console.info('heartbeat ' + Math.random());
  ws.send('{"msg_type":"ping","msg_content":"I am online!"}');
  setTimeout(send_heartbeat, 10000); // every 10 s
}
ws.onclose = function () {
  console.log('Connection lost, going to sleep');
};

Server‑Initiated Heartbeat (Not Recommended)

Configure the gateway start script (e.g., start_gateway.php) as follows:

$gateway->pingInterval = 55;
$gateway->pingNotResponseLimit = 0; // client not required to send heartbeats
$gateway->pingData = '{"type":"ping"}';

With this setting the server sends a ping every 55 seconds. Setting pingNotResponseLimit = 1 would require the client to send any data within pingInterval * pingNotResponseLimit = 55 seconds, otherwise the connection is closed.

Parameter Explanation

$gateway->pingInterval = 55;

– heartbeat interval in seconds (0 disables heartbeat). $gateway->pingNotResponseLimit = 1; – number of consecutive intervals without any data after which the server closes the connection. A value of 0 means the client does not need to send heartbeats; the server relies on TCP keep‑alive, which may take >10 minutes to detect a drop. $gateway->pingData = ''; – payload the server sends when acting as the heartbeat initiator. Clients can ignore the content.

Note: Because heartbeats are periodic, the actual onClose trigger may occur later than pingInterval * pingNotResponseLimit . The deviation is bounded by pingInterval . For example, with pingInterval = 55 , the close may happen between 55 s and 110 s.

Additional Timing Notes

When the server initiates heartbeats, the first ping after a successful connection may be shorter than the configured interval. If the client has recently sent data, the server may skip a heartbeat and send the next one after roughly 1.5 * $gateway->pingInterval seconds.

Running Reference (Client Side)

var ws = new WebSocket('ws://127.0.0.1:9503');
ws.onmessage = function(event) {
    console.log('Message: ' + event.data);
};
ws.onclose = function() {
    var date = new Date();
    console.log('Connection lost, sleeping at ' + date.toLocaleString());
};
let _content = {
    "msg_type": "join",
    "room_id": "160",
};
ws.send(JSON.stringify(_content));
GatewayWorker heartbeat diagram
GatewayWorker heartbeat diagram
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendWebSocketPHPHeartbeatconnection monitoringGatewayWorker
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.