Hey guys,
first of all, the stats: running Ubuntu 11.10, nginx 1.0.5 (package
installed) and PHP 5.3.6 (package php-fpm).
So I have this HTML5 event stream that every 0,5 seconds does some
database operation and sends events to the browser (which the javascript
then handles). Everything was working alright, but then I noticed the
events were getting bundled (3 or 4 of them together) and sent all at
the same time. Basically, I’d see an event coming, then after waiting 2
or 3 seconds, I’d see 4 or 5 arrive at the same time. As the idea here
is a real-time stream, this is definitely not good - the events should
be sent to the browser as soon as they are created (ie. every 0,5
seconds - plus some processing time for DB access etc).
So I started playing around with the buffer size. I noticed that my
events are always roughly 800 bytes, so I used the following parameters:
[php.ini]
output_buffering = Off
[nginx site file]
fastcgi_buffer_size 500;
fastcgi_buffers 2 900;
fastcgi_busy_buffers_size 900;
fastcgi_max_temp_file_size 0;
proxy_buffering off;
With these settings, everything works great, I see the events arriving
in order, all of them individually, and it looks great.
But then, of course, everything got wrong again when I started using
HTTPS. After a lot of nginx debugging (including looking at its source
code), I realized that nginx buffers the data sent to OpenSSL, and that
this buffer is 16k bytes. Since I couldn’t find any config options to
change/disable this SSL buffer, I decided to pad my events with
whitespaces, in order for them to be roughly 16k long, and set the
buffers to:
fastcgi_buffer_size 17000;
fastcgi_buffers 2 17000;
fastcgi_busy_buffers_size 17000;
Unfortunately, that doesn’t work either: looking at the nginx debug log,
I see that the events arrive at nginx fine, the buffer is just big
enough for them, and for every event, nginx writes it immediately to
SSL:
SSL buf copy: 6
SSL buf copy: 15974
SSL to write: 16384
SSL_write: 16384
Yet the javascript only sees the first event (confirmed with
console.log)
Basically, I’d love to have some help from you guys to solve my problem.
All I need is a real-time event stream in HTTPS. I already tried dozens
of buffer size combinations, either really small (so that’s nothing is
buffered) or values around 800bytes (+headers), or values around 16000
with padding. I also tried compiling nginx from source with
NGX_SSL_BUFFERED (source/core/ngx_connection.h) set to 0x00 , but that
didn’t help… Is there any way to just disable SSSL buffering all
together?!
I am attaching the nginx debug log, hopefully it will make sense to
someone! (Tip: in the php script, I error_log “Sending event with
<num_bytes> bytes” before echo’ing the event output and error_log
“SENT!” after - these show up in the log after the “FastCGI sent in
stderr” messages)
Thanks in advance,