GatewayWorker Documentation

repository·master·Indexed 22 days ago

https://github.com/walkor/gatewayworker

A PHP framework built on Workerman for long-connection applications such as IM, gaming, IoT, and smart home systems. It utilizes a distributed Gateway/Worker process model to separate connection maintenance from business logic, allowing services to be deployed on different servers for a distributed cluster architecture.

Tokens
7.3K
Snippets
16
Records
31
Agent score
77%

What's inside GatewayWorker

  1. What is GatewayWorker and its architecture

    master

    GatewayWorker is a framework built on top of Workerman designed for rapid development of long-connection applications such as App push servers, IM (Instant Messaging) servers, game servers, IoT, and smart home systems.

    It utilizes a classic Gateway and Worker process model:

    1. Gateway Processes: Responsible for maintaining client connections and forwarding client data to the Worker processes.
    2. Worker Processes: Responsible for handling actual business logic and pushing results back to the corresponding clients.

    Because of this separation, Gateway services and Worker services can be deployed on different servers to achieve a distributed cluster architecture.

  2. Get started with the GatewayWorker demo

    master

    For a quick start, you can download a demo package that includes the GatewayWorker core and the necessary startup entry files (start_gateway.php, start_business.php, etc.).

    1. Download the demo: GatewayWorker.zip
    2. Refer to the readme file within the source code for specific instructions on running the demo.
  3. Configure Gateway load balancing modes

    master

    The Gateway class supports two load balancing modes for distributing client connections among available BusinessWorkers. You can set the mode using the static property Gateway::$selectLoadBalancingMode.

    • Gateway::ROUTER_RANDOM: Uses random selection to pick a BusinessWorker.
    • Gateway::ROUTER_LEAST_CONNECTIONS: Selects the BusinessWorker with the fewest active client connections. This is the default mode.
    use GatewayWorker\Gateway;
    
    // Set to random load balancing
    Gateway::$selectLoadBalancingMode = Gateway::ROUTER_RANDOM;
  4. Understand the Register service role in GatewayWorker

    master

    The Register service acts as a central discovery hub for the GatewayWorker architecture. It manages the following lifecycle and communication tasks:

    1. Gateway Discovery: When a Gateway process connects, it sends a gateway_connect event containing its address. The Register service stores these addresses.
    2. Worker Discovery: When a BusinessWorker process connects, it sends a worker_connect event.
    3. Address Broadcasting: Whenever a new Gateway registers its address, the Register service broadcasts the updated list of all available gateway addresses to all connected BusinessWorker processes via the broadcast_addresses event.
    4. Security: It validates all incoming connection events against the configured $secretKey.

    Supported events for clients include gateway_connect, worker_connect, and ping.

  5. Handle session data in BusinessWorker

    master

    BusinessWorker manages client sessions by synchronizing them with the Gateway.

    Standard Usage (Non-Coroutine)

    In standard PHP environments, you can interact with the $_SESSION superglobal directly. The BusinessWorker automatically detects changes to $_SESSION and synchronizes them back to the Gateway.

    Coroutine Usage (Swoole/Swow)

    If you are running in a Swoole or Swow environment, using the $_SESSION global variable is prohibited because coroutines can cause data pollution between different client requests.

    Instead, you must use the \GatewayWorker\Lib\Gateway::setSession method to persist session data.

    Session Lifecycle

    • Initialization: When a message arrives, BusinessWorker decodes the session data from the Gateway and populates $_SESSION.
    • Persistence: If $_SESSION is modified, BusinessWorker encodes it and sends it back to the Gateway.
    • Cleanup: When onClose is triggered, the session version is cleared.
  6. Manage user identity (UID) binding

    master

    You can bind a unique user ID (uid) to a specific client_id. This allows you to target messages to a specific user regardless of how many devices (connections) they are using.

    • Bind UID: Use CMD_BIND_UID to associate a uid with a connection_id. If the connection already has a uid, the old binding is removed first.
    • Unbind UID: Use CMD_UNBIND_UID to remove the association between a connection_id and its current uid.
    • Get Client IDs by UID: Use CMD_GET_CLIENT_ID_BY_UID to find all active client_ids associated with a specific uid. This is useful for sending messages to all of a user's active devices.
  7. Understand the GatewayProtocol binary wire format

    master

    The GatewayProtocol is a binary protocol used for communication between Gateway and Worker. The packet structure consists of a fixed-length header, optional extended data, and a body.

    Packet Structure:

    • pack_len (unsigned int): Total length of the packet.
    • cmd (unsigned char): Command identifier.
    • local_ip (unsigned int): Local IP address.
    • local_port (unsigned short): Local port.
    • client_ip (unsigned int): Client IP address.
    • client_port (unsigned short): Client port.
    • connection_id (unsigned int): Connection ID.
    • flag (unsigned char): Protocol flags.
    • gateway_port (unsigned short): Gateway port.
    • ext_len (unsigned int): Length of the extended data.
    • ext_data (char[ext_len]): Extended data payload.
    • body (char[pack_len - HEAD_LEN]): The main message body.

    Header Length: The constant HEAD_LEN is 28 bytes.

  8. Use Groups to broadcast messages

    master

    Groups allow you to categorize connections and send messages to subsets of users (e.g., a chat room or a specific topic).

    • Join Group: Use CMD_JOIN_GROUP to add a client_id to a group.
    • Leave Group: Use CMD_LEAVE_GROUP to remove a client_id from a group.
    • Ungroup: Use CMD_UNGROUP to remove all members from a specific group and delete the group.
    • Send to Group: Use CMD_SEND_TO_GROUP to broadcast a message to all members of a group. You can also provide an exclude list of connection_ids to prevent specific clients from receiving the message.
    • Group Metadata: You can retrieve the number of clients in a group via CMD_GET_CLIENT_COUNT_BY_GROUP or get the session data of all members in a group via CMD_GET_CLIENT_SESSIONS_BY_GROUP.
  9. Manage client sessions in GatewayWorker

    master

    GatewayWorker allows you to manage persistent data (sessions) associated with a specific client_id. You can set, update, or retrieve these sessions to maintain state across different messages from the same client.

    • Set Session: Overwrite the existing session data for a connection_id using CMD_SET_SESSION.
    • Update Session: Merge new data into the existing session using CMD_UPDATE_SESSION. This uses a recursive merge (array_replace_recursive), meaning nested arrays will be merged rather than completely replaced.
    • Get Session: Retrieve the session data for a specific client_id using CMD_GET_SESSION_BY_CLIENT_ID or retrieve all client sessions using CMD_GET_ALL_CLIENT_SESSIONS.
  10. Handle Docker networking in Gateway

    master

    When running Gateway inside a Docker container, the lanIp (the IP the client connects to) might be different from the IP the internal _innerTcpWorker needs to listen on to receive connections from BusinessWorkers.

    If you encounter stream_socket_server(): Unable to connect to tcp://... (Address not available) errors, use the following pattern:

    1. Set $gateway->lanIp to the host's IP (so the GatewayClientSDK can connect).
    2. Set $gateway->innerTcpWorkerListen to the container's IP or 0.0.0.0 (so the internal worker listens correctly).
    $gateway->lanIp = '192.168.1.2'; // Host IP
    $gateway->innerTcpWorkerListen = '172.25.0.2'; // Container IP or '0.0.0.0'