rtm-ctrlz / keepalive
TCP-Keepalive调整工具
0.3.2
2021-12-14 22:08 UTC
Requires
- php: ^7.2 || ^8.0
- ext-sockets: *
Requires (Dev)
- phpstan/phpstan: ^1.2
- squizlabs/php_codesniffer: ^3.6
Suggests
- ext-openssl: to run ssl-examples
README
这是一个设置适当的TCP-Keepalive选项和值的辅助工具。
原因
在套接字上启用TCP-Keepalive的常用方法如下
socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1);
是的,它确实启用了keepalive,但keepalive参数是什么?上面的例子将使用系统默认值!
大多数系统(操作系统)有以下默认值
因此,使用默认值,第一个TCP-Keepalive数据包将在最后一个数据包后2小时发送,然后等待最多10分钟(75s * 8
)后再关闭死连接。
这是否正是您的情况?
对我不是这样,我想在1分钟或更短的时间内断开连接!
安装
composer require rtm-ctrlz/keepalive
用法
以下是一些“客户端”示例(socket/stream/ssl-stream),但相同的操作也可以用于“服务器端”。
以下示例中使用的参数如下
- 空闲时间:45秒
- 探测间隔:5秒
- 探测次数:3次
因此,我们将得到最大等待时间为1分钟。
原始套接字
// create socket $socket = \socket_create(AF_INET, SOCK_STREAM, SOL_TCP); // enable tcp-keepalive \RtmCtrlz\Keepalive\Keepalive::enable($socket, 45, 5, 3);
流(tcp)
// create stream $stream = \stream_socket_client('tcp://127.0.0.1:80); // get socket $socket = \socket_import_stream($stream); // enable tcp-keepalive \RtmCtrlz\Keepalive\Keepalive::enable($socket, 45, 5, 3);
流(ssl)
这会比较困难,因为socket_import_stream
不能导入套接字。
但我们可以做一个技巧
- 创建TCP连接(stream_socket_client())
- 导入套接字(socket_import_stream())
- 启用TCP-Keepalive
- 启用加密(stream_socket_enable_crypto())
// create stream // NOTE: stream has "tcp" proto $stream = \stream_socket_client( 'tcp://127.0.0.1:443', // target $errno, // error number $errstr, // error description 1.1, // timeout STREAM_CLIENT_CONNECT, // flags stream_context_create( // context [ 'ssl' => [ // ... ssl options ], ] ) ); // get socket $socket = \socket_import_stream($stream); // enable tcp-keepalive \RtmCtrlz\Keepalive\Keepalive::enable($socket, 45, 5, 3); // enable encryption \stream_socket_enable_crypto($stream, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
更多示例
请参阅示例目录中的更多示例。
注意事项
选项号
不幸的是,PHP(以及ext-sockets)没有TCP_KEEPIDLE
、TCP_KEEPINTVL
和TCP_KEEPCNT
常量。
找到的值
Linux: Linux tcp.h Darwin: Darwin XNU tcp.h BSD: FreeBSD tcp.h
Windows支持
嗯,Windows应该支持TCP-Keepalive选项,但是
- 我没有Windows机器进行测试
- 我没有在Windows上查找
TCP_KEEP*
值
请随时提交PR ;)