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