Join 4,000+ others and never miss out on new tips, tutorials, and more.
Latest version:
pecl install openswoole-22.1.2 | composer require openswoole/core:22.1.5
<?php OpenSwoole\Server->bind(int $fd, int $uid): bool
The file descriptor number of the client connection you want bind
The UID to bind the client connection to, must be non-zero
If success, it returns true
, otherwise it returns false
.
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 OpenSwoole\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->getClientInfo($fd)['uid'];
$bindUid = $bindUid >> 31 ? (~($bindUid - 1) & 0xFFFFFFFF) * -1 : $bindUid;
var_dump($bindUid === $uid);
false
if you do<?php
$serv = new OpenSwoole\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 (OpenSwoole\Server $serv, $fd, $reactor_id, $data)
{
$conn = $serv->getClientInfo($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();