When implementing an HTTP server, a coroutine is opened for each request and destroyed after the request is processed. Let us optimize this logic. We can easily think of the improvement of FASTCGI compared to CGI. It is nothing more than generating several worker processes in advance, and not destroying the reuse after processing.
The same is true for the coroutine. For the convenience of demonstration, only one coroutine is opened for easy understanding.
One request one coroutine:
<?php
Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]);
use function Co\run;
run(function () {
$socket = stream_socket_server(
'tcp://0.0.0.0:9998',
$errno,
$errstr
);
if (!$socket) {
echo "$errstr ($errno)" . PHP_EOL;
exit(1);
}
while (true) {
$conn = stream_socket_accept($socket);
if ($conn) {
go(function() use ($conn) {
fwrite($conn, "HTTP/1.1 200 OK\r\nContent-Length:11\r\n\r\nHello!world");
});
}
}
});
Coroutine reuse:
<?php
Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]);
use Co\Channel;
use function Co\run;
run(function () {
$channel = new Channel(1);
go(function() use ($channel) {
while (($conn = $channel->pop()) !== false) {
fwrite($conn, "HTTP/1.1 200 OK\r\nContent-Length:11\r\n\r\nHello!world");
}
});
$socket = stream_socket_server(
'tcp://0.0.0.0:9999',
$errno,
$errstr
);
if (!$socket) {
echo "$errstr ($errno)" . PHP_EOL;
exit(1);
}
while (true) {
$conn = stream_socket_accept($socket);
if ($conn) {
$channel->push($conn);
}
}
});
In reality, we will not just open a coroutine, and we will come to a coroutine pool next time when we have time to achieve getWorker
and putWorker
, and support dynamic expansion of the coroutine pool.
Thanks for the inspiration from the https://github.com/panjf2000/ants
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。