实现一个HTTP服务器时,每个请求开一个协程处理,处理完请求后销毁,让我们优化这段逻辑,我们很容易联想到FASTCGI对比CGI的改进。无非就是预先生成几个worker进程,处理完成后不销毁复用嘛。
那协程也是同理,为了方便演示,只开一个协程,便于理解。
一个请求一个协程:
<?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");
});
}
}
});
协程复用:
<?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);
}
}
});
现实中,我们不会只开一个协程,下次有时间再来撸一个协程池,实现getWorker
和putWorker
,支持协程池动态扩容。
感谢https://github.com/panjf2000/ants
项目的启发。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。