Swoole Server bind()

Declaration

<?php
Swoole\Server->bind(int $fd, int $uid): bool

Parameters

fd

The file descriptor number of the client connection you want bind

uid

The UID to bind the client connection to, must be non-zero

Return

success

If success, it returns true, otherwise it returns false.

Description

Bind the specified $fd with the system user $uid. Connects a user-defined binding with a client connection.

The dispatch of different socket connections to the Swoole server is influenced by the configuration option of dispatch_mode.

In the default dispatch_mode that the Swoole server uses, which is 2, the socket connection may be dispatched to different worker processes after reconnection. You can set the configuration of dispatch_mode to 5 and call Swoole\Server->bind to bind a $uid number to the socket connection. And then the same $uid socket connection will be dispatched to the same worker process.

Things to Consider

  • You can use $server->getClientInfo($fd) to view the bound UID value

  • After the client connects to the server, it sends multiple packets continuously, which may cause timing problems. In the bind operation, the subsequent packet may have dispatched, according to these data packets are still using the currently assigned fd to the current process. Only bind once the data will be completely received, only then should you assign and bind to the new UID assignment.

  • If the binding UID is negative, it will be converted to a 32-bit unsigned integer, you needs to convert to a 32-bit signed integer, for example you could do this:

<?php
$uid = -10;
$server->bind($fd, $uid);
$bindUid = $server->connection_info($fd)['uid'];
$bindUid = $bindUid >> 31 ? (~($bindUid - 1) & 0xFFFFFFFF) * -1 : $bindUid;
var_dump($bindUid === $uid);
  • You can only bind a connection once, you cannot bind multiple times, it will return false if you do

Example

<?php
$serv = new Swoole\Server('0.0.0.0', 9501);

$serv->fdlist = [];

$serv->set([
    'worker_num' => 4,
    'dispatch_mode' => 5,   //uid dispatch
]);

$serv->on('connect', function ($serv, $fd, $reactor_id)
{
    echo "{$fd} connect, worker:" . $serv->worker_id . PHP_EOL;
});

$serv->on('receive', function (Swoole\Server $serv, $fd, $reactor_id, $data)
{
    $conn = $serv->connection_info($fd);
    print_r($conn);
    echo "worker_id: " . $serv->worker_id . PHP_EOL;

    if(empty($conn['uid']))
    {
        $uid = $fd + 1;
        if ($serv->bind($fd, $uid))
        {
            $serv->send($fd, "bind {$uid} success");
        }
    }
    else
    {
        if(!isset($serv->fdlist[$fd]))
        {
            $serv->fdlist[$fd] = $conn['uid'];
        }

        print_r($serv->fdlist);

        foreach ($serv->fdlist as $_fd => $uid)
        {
            $serv->send($_fd, "{$fd} say:" . $data);
        }
    }
});

$serv->on('close', function ($serv, $fd, $reactor_id)
{
    echo "{$fd} Close". PHP_EOL;
    unset($serv->fdlist[$fd]);
});

$serv->start();