wandenberg / nginx-push-stream-module

A pure stream http push technology for your Nginx setup. Comet made easy and really scalable.
Other
2.22k stars 295 forks source link

Pinging on a broken (client side closed) connection still return NGX_OK #265

Closed mr-pajamas closed 7 years ago

mr-pajamas commented 7 years ago

There may be some logical error when invoking nginx http connection api...

wandenberg commented 7 years ago

Sorry I could not understand your issue. Can you explain a little bit more? Give examples and describe the problem, please.

mr-pajamas commented 7 years ago

OK, Thank you for responding! There is a directive 'push_stream_ping_message_interval' which indicates that push stream module will send ping messages periodically to check whether subscriber connection is still alive. And I've checked the code and find that this module will finalize subscriber connection once ping check fails (rc != NGX_OK). The problem is, ping check seems not to work properly as it always return OK even when subscriber has disconnected. Pending flush, I guess, might cause this problem, as actual write failure cannot be caught and handled.

mr-pajamas commented 7 years ago

Here's the relevant code ngx_http_push_stream_module_utils.c

static void
ngx_http_push_stream_ping_timer_wake_handler(ngx_event_t *ev)
{
    ...

    if (rc != NGX_OK) {  // ALWAYS OK HERE!
        ngx_http_push_stream_send_response_finalize(r);  // NEVER REACH HERE
    } else {
        ngx_http_push_stream_timer_reset(pslcf->ping_message_interval, ctx->ping_timer);
    }
}
wandenberg commented 7 years ago

The point is that Nginx sends the data to the socket and while has space in the socket buffer it will return OK to the module. Once the buffer is full, it means the client is not reading the buffer and has gone, Nginx will return some kind of error to the module making it close the references to that client on the server side and stop trying to send messages to it. There is no other reliable way to ensure a client has disconnected. I already asked about that on the Nginx email list. This is especially true when using SSL.

mr-pajamas commented 7 years ago

So, can I infer that if I make the socket buffer size smaller than ping message body, I can tell if a client connection is alive or not through this way?

wandenberg commented 7 years ago

Not exactly. If you set the buffer size smaller than the ping message the module won't be able to send the message, and probably your messages will also be bigger than the ping. If you really want to detect that the client disconnected faster set a small buffer size, but remember that if you have a slow client the buffer may be full even with the client still online, forcing its disconnection.

mr-pajamas commented 7 years ago

I see. Thank you for the advice!