Current Location: Home> Latest Articles> Use socket_set_block to implement a messaging system with control flow

Use socket_set_block to implement a messaging system with control flow

gitbox 2025-05-29

1. What is socket_set_blocking?

The socket_set_blocking function in PHP is used to set the blocking mode of a socket resource:

  • Blocking mode: When calling socket-related functions, wait for the operation to complete, and the program will pause during this period.

  • Non-blocking mode: Returns immediately when calling socket-related functions, and does not wait for the operation to complete.

By default, socket is blocking. Blocking mode is suitable for simple synchronization scenarios, but for high-performance servers, a more detailed control flow mechanism is required.

 bool socket_set_blocking ( resource $socket , bool $mode )
  • $socket : socket resource.

  • $mode : true means blocking, false means non-blocking.


2. The significance of control flow

Control flow manages the sending and receiving rhythm of messages to prevent messages from being sent too quickly, resulting in network congestion, excessive resource usage or message loss. Designs with control flow can be implemented:

  • Queue message buffering, sending step by step.

  • Dynamically switch between blocking and non-blocking modes.

  • Timeout handling and error retry mechanism.


3. Design ideas

  • Both the server and the client use blocking mode to ensure the stability of sending and receiving.

  • Queue the message sending and send it only when there is data in the sending buffer to prevent blocking and waiting.

  • The receiver sets a reasonable timeout to avoid long-term hangs.

  • Use socket_select to achieve multiplexing, monitor read and write events, and improve efficiency.


4. Sample code

The following is a simplified TCP-based PHP socket server example, which demonstrates how to use socket_set_blocking to control blocking mode to realize flow control of messaging:

 <?php
$host = "0.0.0.0";
$port = 12345;

// createsocket
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, $host, $port);
socket_listen($sock);

echo "Server started at $host:$port\n";

// Set up monitoringsocketIn blocking mode,Waiting for client when accepting connection
socket_set_blocking($sock, true);

$clients = [];

while (true) {
    // use socket_select Listen to active connections
    $read = $clients;
    $read[] = $sock; // Join the monitorsocket
    $write = [];
    $except = null;

    // Blocking waiting for activitysocket
    if (socket_select($read, $write, $except, 5) < 1) {
        continue; // Timeout No activity
    }

    // Process new connections
    if (in_array($sock, $read)) {
        $newClient = socket_accept($sock);
        if ($newClient !== false) {
            socket_set_blocking($newClient, true); // Setting up the clientsocketFor blocking,Guaranteed complete message
            $clients[] = $newClient;
            echo "New client connected\n";
        }
        unset($read[array_search($sock, $read)]);
    }

    // Process existing client messages
    foreach ($read as $client) {
        $data = socket_read($client, 2048, PHP_NORMAL_READ);
        if ($data === false || $data === '') {
            // Client disconnection
            echo "Client disconnected\n";
            socket_close($client);
            unset($clients[array_search($client, $clients)]);
            continue;
        }
        $data = trim($data);
        echo "Received: $data\n";

        // Simple echo,With flow control:Make sure before sendingsocketBlocking mode,Prevent write failures
        socket_set_blocking($client, true);
        $sendResult = socket_write($client, "Echo: $data\n");
        if ($sendResult === false) {
            echo "Failed to send message to client\n";
        }
    }
}

5. Flow control design points for parsing code

  • Switching of blocking mode <br> Both the listening socket and the client socket are set to blocking, so that the integrity of the data can be guaranteed when reading and writing data, and avoid incomplete messages due to short read and short writes in non-blocking mode.

  • socket_select listen multiplexing
    socket_select blocks and waits for a socket to be readable, improving CPU utilization and avoiding waste of resources in a dead loop.

  • Message Queue Control (Extensible)
    Although it is read and written directly in the example, a message queue can be added according to the needs to control the size and frequency of each message sent to avoid client network congestion.


6. Further optimization suggestions

  • Use non-blocking mode to cooperate with event-driven libraries (such as libevent) to improve high concurrency performance.

  • Introduce message serial number and confirmation mechanism to ensure the integrity of message transmission.

  • Implement heartbeat packet detection connection status.

  • Use socket_set_option to optimize TCP parameters, such as setting TCP_NODELAY to reduce latency.


7. Conclusion

By rationally using PHP's socket_set_blocking function and combining the socket_select event listening mechanism, an efficient messaging and receiving system with control flow can be built. The control flow not only ensures the stability of message transmission, but also improves the system's response speed and resource utilization. I hope this article’s examples and ideas will be helpful to you in building your own message system.