Hi Andreas and Zhang,
Thank you for your hint with the http_echo_module! I read through their
code to get a hang of how the event loop and the event handling actually
works.
If I replace the hello_world command in my config files with the
echo/echo_flush/echo_sleep commands, everything works as expected.
If I use my modified hello_world module (code below), I still get a
three second pause and then all three "hello world" at once.
So I do not think that my configuration (which is the default Debian
Stretch configuration) is at fault.
I pasted the whole debug log here: https://pastebin.com/raw/uwuK4UJB
When I look into the debug log, I see four writev lines corresponding to
the initial header and the three "helloworld" outputs.
So I think the socket gets its data, but perhaps I am missing some magic
socket options? Which would be strange, as I cannot see the
http_echo_module doing such a thing.
This is my current code (all error handling omitted -- I will take care
of that):
struct ngx_http_hello_world_ctx
{
int counter;
ngx_event_t event;
};
static int numberOfMessages = 3;
static ngx_int_t ngx_http_hello_world_handler(ngx_http_request_t *r)
{
struct ngx_http_hello_world_ctx * ctx = ngx_http_get_module_ctx(r,
ngx_http_hello_world_module);
if(ctx == NULL)
{
ctx = ngx_pcalloc(r->pool, sizeof(struct
ngx_http_hello_world_ctx));
ngx_http_set_ctx(r, ctx, ngx_http_hello_world_module);
}
ctx->counter = 0;
ctx->event.data = r;
ctx->event.handler = ngx_http_hello_world_event_handler;
ctx->event.log = r->connection->log;
r->headers_out.content_type.len = sizeof("text/html") - 1;
r->headers_out.content_type.data = (u_char *) "text/html";
r->headers_out.status = NGX_HTTP_OK;
ngx_http_send_header(r);
r->main->count++; // Increments reference count
ngx_add_timer(&ctx->event, 0);
return ngx_http_output_filter(r, NULL);
}
static void ngx_http_hello_world_event_handler(ngx_event_t *ev)
{
ngx_http_request_t * r = ev->data;
struct ngx_http_hello_world_ctx * ctx = ngx_http_get_module_ctx(r,
ngx_http_hello_world_module);
if(ctx->counter < numberOfMessages)
{
ngx_buf_t *b;
ngx_chain_t out;
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
out.buf = b;
out.next = NULL;
b->pos = ngx_hello_world;
b->last = ngx_hello_world + sizeof(ngx_hello_world);
b->memory = 1;
b->flush = 1;
b->last_buf = (ctx->counter == numberOfMessages);
ngx_http_output_filter(r, &out);
ngx_http_send_special(r, NGX_HTTP_FLUSH);
ctx->counter++;
if(ctx->counter == numberOfMessages)
{
ctx->counter = 0;
ngx_http_send_special(r, NGX_HTTP_LAST);
ngx_http_finalize_request(r, NGX_OK); // Decrements
reference count
}
else
{
ngx_add_timer(&ctx->event, 1000);
}
}
}
Cheers
Johan
On 2017-07-10 04:04, Zhang Chao wrote:
Hello!
You mustn’t use standard sleep function for it will block Nginx’s
events loop, alternatively, you need to put your write event to a
timer, set the proper handler when the timer expires.
BTW, you should always check the return value of ngx_http_send_header
and ngx_http_output_filter.
On 10 July 2017 at 01:43:46, Johan Andersson (n...@firemail.cc) wrote:
Hi everyone,
I have some issues writing my nginx modules.
I am on Debian Stretch, installed nginx with the default
configuration,
and took the hello_world module. It works without a hitch. Then I
changed the handler to send three "hello world" responses, and sleep
for
one second between each response.
However, when I look at the result in my browser, the page loads,
pauses
for three seconds, and then displays all three "hello world"
messages at
once.
Actually I was flushing each response, so I expected each "hello
world"
message to appear one after the other, with one second pause between
them.
Am I doing something wrong? Is this event the correct way to achieve
this? All functions return NGX_OK. This is my code:
static ngx_int_t ngx_http_hello_world_handler(ngx_http_request_t *r)
{
ngx_buf_t *b;
ngx_chain_t out;
ngx_int_t result;
r->headers_out.content_type.len = sizeof("text/html") - 1;
r->headers_out.content_type.data = (u_char *) "text/html";
r->headers_out.status = NGX_HTTP_OK;
//r->headers_out.content_length_n = sizeof(ngx_hello_world);
ngx_http_send_header(r);
for(int i = 0; i < 3; i++)
{
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
out.buf = b;
out.next = NULL;
b->pos = ngx_hello_world;
b->last = ngx_hello_world + sizeof(ngx_hello_world);
b->memory = 1;
b->flush = 1;
b->last_buf = (i == 2);
result = ngx_http_output_filter(r, &out);
ngx_http_send_special(r, NGX_HTTP_FLUSH);
sleep(1);
}
return result;
}
Cheers
Johann
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx