Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cookie based sticky sessions support? #775

Closed
peteruithoven opened this issue Nov 3, 2014 · 13 comments
Closed

Cookie based sticky sessions support? #775

peteruithoven opened this issue Nov 3, 2014 · 13 comments

Comments

@peteruithoven
Copy link

I'm using HAProxy to load balance between different node instances. I've enabled sticky sessions using cookies, so that I can easily test the load balancing behind the same remote ip address.
But I'm noticing that it doesn't work in Node.js, while it does work in a browser.
The error I receive is xhr poll error, which is what I usually get when I forget to enable sticky sessions.
My theory is that socket.io-client running in Node.js, doesn't accept the cookies from HAProxy. I've seen several issues around cookies but never in combination with sticky sessions.

Issues like the following don't seem hopeful:
socketio/engine.io-client#304
#587

Code example:

var io = require('socket.io-client');
var socket = io("https://myserver.com");
socket.on("connect",function() {
  console.log("connected");
});
socket.on("error",function(data) {
  console.log("error: ",data);
});

HAProxy:

global

    # By default, only one process is created, which is the recommended mode of operation. 
    nbproc                      1
    maxconn                     4096

    # Logging
    log 127.0.0.1 local0

    ## SSL
    # Set DH params to 2048 bits
    tune.ssl.default-dh-param 2048
    # Strong ciphers
    # Do not forget to add 'no-sslv3' to each ssl enabled frontend (POODLE)
    ssl-default-bind-ciphers        EECDH+AES:EDH+AES:-SHA1:EECDH+AES256:EDH+AES256:AES256-SHA:!aNULL:!eNULL:!EXP:!LOW:!MD5:!RC4
    ssl-default-server-ciphers      EECDH+AES:EDH+AES:-SHA1:EECDH+AES256:EDH+AES256:AES256-SHA:!aNULL:!eNULL:!EXP:!LOW:!MD5:!RC4

defaults
    mode http
    log global
    # this enables logging of HTTP request, session state and timers
    option httplog
    # enable HTTP connection closing on the server side
    option http-server-close
    # disable logging of null connections as these can pollute the logs
    option dontlognull
    # enable session redistribution in case of connection failure, which is important in a HA environment
    option redispatch
    option contstats
    # enables the insertion of the X-Forwarded-For header to requests sent to servers
    option forwardfor
    # Default timeouts
    # See also http://blog.haproxy.com/2012/11/07/websockets-load-balancing-with-haproxy/
    timeout connect 5s
    timeout client 30s
    timeout server 30s
    timeout tunnel 3600s
    timeout http-keep-alive 1s
    timeout http-request 15s
    timeout queue 30s
    timeout tarpit 60s
    timeout check 5s
    retries 3
    backlog 4096
    default-server inter 3s rise 2 fall 3

frontend https
    bind 0.0.0.0:443 ssl crt /etc/haproxy/ssl/server.pem no-sslv3 
    option              httpclose
    default_backend     nodeapp
    tcp-request inspect-delay 500ms
    tcp-request content accept if HTTP

backend nodeapp
    mode                http
    balance             leastconn
    option              forwardfor
    option              http-server-close
    option              forceclose
    no option           httpclose

    http-request set-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Proto https if { ssl_fc }

    cookie SRV_ID insert

    server nodeapp1 127.0.0.1:5000 cookie nodeapp1 check
    server nodeapp2 127.0.0.1:5001 cookie nodeapp2 check
    server nodeapp3 127.0.0.1:5002 cookie nodeapp3 check
    server nodeapp4 127.0.0.1:5003 cookie nodeapp4 check

@peteruithoven
Copy link
Author

I see lot's of recommendations for using query strings, but I'm not if HAProxy supports sticky-sessions using query strings. I also need to check whether that requires custom code on the client side.

@peteruithoven
Copy link
Author

I sort of understand that cookies are not allowed:
#344 (comment)

Just to clarify:

  • I don't want to add client sided code because I'm trying to develop a general API, that people should be able to connect to using just socket.io.
  • I need Node.js (non browser) support because some clients run on embedded devices. It's also very convenient for testing.

The following thread seems interesting:
socketio/engine.io#207 (comment)

@peteruithoven
Copy link
Author

We figured it out (using url parameters): socketio/engine.io#207 (comment)

@nkzawa
Copy link
Contributor

nkzawa commented Mar 7, 2015

It seems the issue has been solved.

@BilalBoulifa
Copy link

Hi @peteruithoven I'm facing the same problem, can you please give me more detail how it was resolved?
in the load balancer I used url_param but what need to be done on the client side ?

@darrachequesne
Copy link
Member

@fithwith would that example help? (cookie-based sticky session with haproxy).

@BilalBoulifa
Copy link

thank you @darrachequesne I already have this config, which resolved part of the problem, which is the socket from the browser side, but in my app I have another client which is a nodejs client using socket.io-client module and with this client the cookie solution is not working because I'm unable to get and send back this cookie to the server, I ready found some possible solutions, one tweaking xhr module from the client in order to send cookie but I didn't find a way to receive the cookie from the server and another solution about using url_param in haproxy but didn't understand how its working from the client side.

@gabzim
Copy link

gabzim commented Apr 12, 2017

+1 on this, I have a working implementation that only works when connecting from a browser, but the minute I want a node.js app to connect, I get: Error: xhr poll error

@gabzim
Copy link

gabzim commented Apr 12, 2017

I'm using AWS Application Load Balancer (ALB) and it uses a cookie for sticky sessions, but the socket.tio-client does not suppport cookies.

@DaVincii
Copy link

@darrachequesne Any updates on this?

@jonathanroze
Copy link

Any updates ?

@darrachequesne
Copy link
Member

@jonathanroze hi! Please check the example here: https://socket.io/how-to/deal-with-cookies#nodejs-client-and-cookies

@jonathanroze
Copy link

@jonathanroze hi! Please check the example here: https://socket.io/how-to/deal-with-cookies#nodejs-client-and-cookies

Thanks a lot !!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants