workerman http协议问题

huazai

问题描述

前提
workerman 使用http协议开发,当使用Connection: keep-alive设置头

问题
1.这个keep-alive的时间是多长,在哪设置和可以看到
2.时间到了,是服务器主动断开还是客户端断开
3.这个断开是如何检测的(即如何判断时间到了,我需要断开),我看workerman 没有检测的代码,也没有心跳
4.我网页访问,把网页关闭了,前面保持的连接还在吗?什么时候销毁,服务器如何感知并触发onClose事件,是基于四次握手吗?但是我是突然把网页进程给关闭了啊

327 1 0
1个回答

walkor 打赏

workerman作为底层只实现了http协议,没有实现完整的webserver逻辑。
协议本身并不会检测Connection头,也不会根据Connection头主动做出关闭连接操作。
服务端如果不关闭连接,浏览器会主动关闭,时间多久不同浏览器可能行为不一样,估计30-60秒
断开连接一般用定时器,连接关闭服务端会受到fin包表示连接关闭
浏览器关闭后连接就不存在了,服务端会立刻受到fin包,onclose会立刻触发。

  • huazai 2024-06-20

    收到,谢谢大佬,刚才通过自己做实验和查阅相关知识,大概明白了,我的思路和理解是

    1.通过在onClose 执行debug_backtrace()方法,打印调用栈,定位到了和onClose有关系的Event.php的loop方法和TcpConnection.php的baseRead方法
    2.通过查询文档,socket的读写事件是交给libevent进行loop循环的,当有事件触发会激发先前自己注册的方法
    3.浏览器进程突然kill掉,会由内核和服务器交互断开链接.正常情况下,会由浏览器进程自己处理超时,和服务器断开链接(我自己电脑好几分钟才触发断开,我想这就是为什么需要心跳包原因了,容易资源浪费)
    4.链接断开回触发四次握手,客户端发送fin包。libevent收到fin包,触发可读事件,激发了baseRead方法,在baseRead执行到
    try {
    $buffer = @\fread($socket, self::READ_BUFFER_SIZE);
    } catch (\Exception $e) {} catch (\Error $e) {}

        // Check connection closed.
        if ($buffer === '' || $buffer === false) {
            if ($check_eof && (\feof($socket) || !\is_resource($socket) || $buffer === false)) {
                $this->destroy();
                return;
            }
        } 

    由于需要断开链接了,读不到内容,触发了$this->destroy(),从而在触发onClose里面的东西。

×
🔝