On Mon, Sep 29, 2014 at 9:15 PM, William Lewis <[email protected]> wrote:

> Hi all
>
> I have a problem with a website which uses Server-Sent Events where the
> long lived connection for the Server Events seems to be blocking other
> resources from loading on iOS clients only and only when I have haproxy
> between client and server.
>
> This is my test case.
>
>  * Create a node express app which serves a html page which subscribes to
> an EventSource and asynchronously adds 200 300x100px images to the DOM
>  * Node app is configured to serve resources with 500ms delay to reliably
> reproduce the problem
>  * Configure basic haproxy between node app and client
>  * Reset cache on iOS device and connect to server
>
> Expected result
>
>  * Client open 5 simultaneous http connections to the server
>  * 1 connection is blocked listening for events from the EventSource
>  * The remaining 4 connections are used to download the 200 images
>
> Actual Result
>
>  * Connection to EventSource is established and events start to be logged
> to the console
>  * Images start to download on the page
>  * Several of the images get blocked and never load
>
>
> Clearing the device cache and connecting directly to the server, all
> resources load, although the loading pattern of images is significantly
> different.
>
> If anyone has any ideas I would greatly appreciate any suggestions??
>
>
> Sources and config included below.
>
> ** index.html*
>
> <html>
> <head>
>     <style>
>     img {
>         width: 30px;
>         height: 10px;
>         border-style: solid;
>         border-color: black;
>         border-width: 1px;
>     }
>     </style>
> </head>
> <body>
>     <script type="text/javascript">
>     var source = new EventSource('/events');
>
>     source.onmessage = function(e) {
>         console.log(e.data);
>     }
>
>     var body = document.querySelectorAll('body');
>     var createImage = function(i) {
>         var element = document.createElement('img');
>         element.src = '/' + i + '.png';
>
>         body[0].appendChild(element);
>     }
>
>     window.setTimeout(function() {
>         for (var i = 1; i < 200; i++) {
>             createImage(i);
>         }
>     }, 1000);
>     </script>
> </body>
> </html>
>
> ** app.js*
>
> var express = require('express');
> var app = express();
>
> app.get('/events', function(req, res) {
>
>     // let request last as long as possible
>     req.socket.setTimeout(Infinity);
>
>     var messageCount = 0;
>
>     res.writeHead(200, {
>         'Content-Type': 'text/event-stream',
>         'Cache-Control': 'no-cache',
>         'Connection': 'keep-alive'
>     });
>     res.write('\n');
>
>     var timeout;
>
>     var emitEvent = function() {
>         res.write('id:' + ++messageCount + '\n');
>         res.write('data:' + new Date().getTime() + '\n\n');
>
>         timeout = setTimeout(emitEvent, 3000);
>     }
>
>     req.on("close", function() {
>         clearTimeout(timeout);
>     });
>
>     emitEvent();
>
> });
>
> var staticHandler = express.static(__dirname + '/public');
>
> app.use(function serveStatic(req, res, next) {
>     setTimeout(function() {
>         staticHandler(req, res, next);
>     }, 500);
> });
>
> var server = app.listen(3000, function() {
>     console.log('Listening on port %d', server.address().port);
> });
>
>
> ** haproxy config*
>
> global
>     daemon
>     quiet
>     maxconn 1024
>     pidfile haproxy.pid
>     log     127.0.0.1       local0
>     log     127.0.0.1       local1 notice
>
> defaults
>     log global
>
>     balance roundrobin
>     mode http
>
>
> frontend external
>     bind :80
>     default_backend test
>
> backend test
>     server test localhost:3000
>
>
>
>
>

Hi William,

Could you please turn on option httplog and provide us the logs reported by
HAProxy?
Also, which version of HAProxy are you running?

Baptiste

Reply via email to