Game Development 9 min read

How to Build a Custom TCP Protocol for Unity3D Multiplayer Games with Workerman

This guide explains how to implement a custom TCP protocol in PHP using Workerman for Unity3D multiplayer games, covering the sticky‑packet problem, protocol interface methods, two concrete protocol examples, and step‑by‑step testing of packet framing and splitting.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
How to Build a Custom TCP Protocol for Unity3D Multiplayer Games with Workerman

Background and Problem

When using Workerman to create a server for a Unity3D multiplayer game, developers often start with simple string‑based communication over TCP. In practice this leads to the classic sticky‑packet and split‑packet issues, where the receiver cannot reliably determine packet boundaries, causing parsing errors.

Workerman Custom Protocol Interface

Workerman allows developers to define their own application‑layer protocol by implementing ProtocolInterface. The three essential methods are:

Input : Inspects the incoming buffer, checks packet length, and returns 0 to wait for more data, a positive integer to indicate a complete packet, or false to close the connection.

Encode : Prepares data before sending it to the client, typically by adding a header such as packet length.

Decode : Extracts the payload from the received buffer after the header has been removed.

Sticky‑Packet Phenomenon

TCP is a stream protocol; it does not preserve message boundaries. Consequently, multiple logical packets may be concatenated (sticky) or a single logical packet may be split across several reads. Without a framing strategy, string‑based protocols can easily break.

Solutions

Two common framing strategies are demonstrated:

Header Length : Prefix each packet with a 4‑byte length field. The input method reads the first four bytes, determines the total length, and returns when the full packet is available.

Delimiter Character : Append a special delimiter (e.g., #) to each packet and search for it in the buffer. The input method returns the position of the delimiter plus one.

Protocol Example – Header Length (Game.php)

<?php
namespace Workerman\Protocols;
use Workerman\Connection\TcpConnection;
class Game {
    public static function input($buffer, TcpConnection $connection) {
        $bodyLen = intval(substr($buffer, 0, 4));
        $totalLen = strlen($buffer);
        if ($totalLen < 4) return 0;
        if ($bodyLen <= 0) return 0;
        if ($bodyLen > strlen(substr($buffer, 4))) return 0;
        return $bodyLen + 4;
    }
    public static function decode($buffer) { return substr($buffer, 4); }
    public static function encode($buffer) {
        $bodyLen = strlen($buffer);
        $headerStr = str_pad($bodyLen, 4, 0, STR_PAD_LEFT);
        return $headerStr . $buffer;
    }
}

Protocol Example – Delimiter (Tank.php)

<?php
namespace Workerman\Protocols;
use Workerman\Connection\ConnectionInterface;
class Tank {
    public static function input($buffer, ConnectionInterface $connection) {
        if (isset($connection->maxPackageSize) && strlen($buffer) >= $connection->maxPackageSize) {
            $connection->close();
            return 0;
        }
        $pos = strpos($buffer, "#");
        if ($pos === false) return 0;
        return $pos + 1; // include delimiter
    }
    public static function encode($buffer) { return $buffer . "#"; }
    public static function decode($buffer) { return rtrim($buffer, "#"); }
}

Testing the Protocol

The article provides a step‑by‑step test:

Start the Workerman worker listening on port 1234.

Connect a client and send packets formatted as method,params and terminated by #.

Observe the server logs to verify that packets are correctly framed, decoded, and dispatched (e.g., LOGIN, POS commands).

Perform sticky‑packet tests by sending two packets back‑to‑back without waiting, and split‑packet tests by sending a single packet in two parts.

Images in the original article illustrate the server start, client connection, and the results of sticky and split packet tests.

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.

TCPPHPgame servercustom protocolWorkermanSticky Packets
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.