Well, this should be a rookie level question, but after reading the documentation, I still can’t figure it out.
Well, this should be a rookie level question, but after reading the documentation, I still can’t figure it out.
php’s socket is a resource type:
resource(4) of type (Socket), that is, each socket handle looks the same. .
And Linux C socket fd is an int integer, each one is a different number.
Native PHP cannot "actively push a message to the connected user with user uid=123",
But with the help of Swoole's socket implemented using Linux C, we can "actively send a message to the connected user" The user with uid=123, push a message."
Here we can use System V’s simplest share memory to share data IPC between processes and maintain a mapping table between user IDs and their socket connections.
The code is as follows:
<code><?php $serv = new swoole_server("127.0.0.1", 1024); $serv->set(array( 'worker_num' => 8, //工作进程数量 'daemonize' => false, //是否作为守护进程 )); $shmid = shm_attach(getmypid(), 1024*66); # allocate 66kB for shared memory define("SHARED_UID_CONNECTION_MAP", 12); shm_put_var($shmid,SHARED_UID_CONNECTION_MAP, []); $serv->on('connect', function ($serv, $fd) use($shmid) { echo "Client:Connect.\n"; }); $serv->on('receive', function ($serv, $fd, $from_id, $data) use($shmid) { $serv->send($fd, 'Swoole: '.$data); // $serv->close($fd); $trimdata = trim($data); if ($trimdata == 'i am lucky man') { $map = shm_get_var($shmid,SHARED_UID_CONNECTION_MAP); $map[] = $fd; #$map[$uidFromData] = $fd; shm_put_var($shmid,SHARED_UID_CONNECTION_MAP, $map); } if ($trimdata == 'broadcast to lucky man') { $map = shm_get_var($shmid,SHARED_UID_CONNECTION_MAP); // var_dump($map); $ $map is array whose valuse is int $fd foreach($map as $fd) { $serv->send($fd, "some body broadcast to you luck man"); } } # broadcast to all users // $start_fd = 0; // while(true) // { // $conn_list = $serv->connection_list($start_fd, 10); // if($conn_list===false or count($conn_list) === 0) // { // echo "finish\n"; // break; // } // $start_fd = end($conn_list); // var_dump($conn_list); // foreach($conn_list as $fd) // { // $serv->send($fd, "broadcast"); // } // } // var_dump($serv->connections); // foreach ($serv->connections as $k => $v) { // $lk = [$k,$v]; // var_dump($lk); // } }); $serv->on('close', function ($serv, $fd) { echo "Client: Close.\n"; }); $serv->start(); </code>
Then you can open n clients to test the code. For example, I open 3 telnets 127.0.0.1 1024. The last one sends a message to the server "i am lucky man", and the first one sends "broadcast to lucky" to the server. man", then the third one will receive "some body broadcast to you luck man" to send a message to a specific user
.It’s that simple,
Swoole is a good method, asynchronous io + multi-process is also the most mature ending solution (tribute to Nginx)
Hahaha
uid is just the uid you identify. The socket link to the service has a unique id. You can only send messages to the client through this unique id. You can make a mapping between the two, then That's it.