【问题标题】:libevent2 http server how to detect client closelibevent2 http服务器如何检测客户端关闭
【发布时间】:2013-09-11 14:27:57
【问题描述】:

我编写了一个简单的 Web 服务器来处理长轮询,这意味着服务器不会向客户端(Web 浏览器、curl 等)发送完整的 HTTP 响应,而只会发送 HTTP 标头并挂起连接。

我使用命令行 curl 向服务器发出请求,它很好地打印出 HTTP 响应标头,并且 curl 按预期挂起。然后我按 CTRL+C 终止 curl 过程。但是服务器永远不会知道这个关闭(永远不会调用 on_disconnect())。

部分代码:

void request_handler(struct evhttp_request *req, void *arg){
    // only send response headers, and one piece of chunked data
    evhttp_send_reply_start(req, HTTP_OK, "OK");
    evbuffer_add_printf(buf, "...\n");
    evhttp_send_reply_chunk(req, buf);
    // register connection close callback
    evhttp_connection_set_closecb(req->evcon, on_disconnect, sub);
}

void on_disconnect(struct evhttp_connection *evcon, void *arg){
    printf("disconnected\n");
}

evhttp_set_gencb(http, request_handler, NULL);

我的问题是,如何检测这种客户端关闭(收到 TCP FIN)?

github 处的错误

【问题讨论】:

    标签: http libevent


    【解决方案1】:

    我认为这是 libevent 中的一个错误。

    我对 libevent 2.0.21 有类似的问题,这就是我的情况:当 libevent 的 http.c 中的 evhttp_read_header() 完成从客户端读取 HTTP 标头时,它会通过调用 bufferevent_disable 禁用任何未来的读取事件(...,EV_READ)。但是,需要为底层缓冲区事件启用读取事件才能报告 EOF。这就是为什么当客户端关闭连接时,bufferevent 从不告诉 libevent 的 HTTP 代码。

    我通过简单地删除 evhttp_read_header() 中对 bufferevent_disable() 的调用解决了这个问题。我使用“连接:关闭”,只使用 GET 请求,因此客户端从不在标头之后发送任何数据,这个解决方案似乎适用于这个非常具体和简单的用例。但是,我不确定这是否会破坏其他用例,尤其是当您使用持久连接或“期望:100-继续”之类的东西时。

    你可能想把它带到 libevent 邮件列表。

    【讨论】:

    • 谢谢!你只是修改了libevent的源代码吗?我想知道是否有办法在我的应用程序中重新启用 EV_READ 事件,那会更好。
    • 是的,我只是修改了libevent源代码的http.c。但是,是的,好点,您还应该能够在请求处理程序中从您的应用程序重新启用 EV_READ:(1)从与 evhttp_connection_get_bufferevent() 的连接中获取 bufferevent,(2)使用 bufferevent_enable(..., EV_READ ) 在缓冲区事件上。不过,我还没有尝试过。
    • 我按照你说的测试了,重新启用EV_READ,就可以了!不过不知道会不会有什么不好的影响。
    • 不错。我很高兴听到这似乎到目前为止有效。最终,libevent 邮件列表上的人可能是唯一给你一个明确答案的人。但我认为,如果(1)你让你的服务器发送一个“连接:关闭”标头(这样 TCP 连接不会被重新用于后续的 HTTP 请求)和( 2)您的客户端仅使用 GET 请求(因此它永远不会在其 HTTP 请求中发送正文)。在这种情况下,客户端不应该在发送请求标头后发送任何数据。 (这对我有用。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多