Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does an Application Load Balancer support WebSockets?

I have an Elastic Beanstalk application which was initially configured to use a Classic Load Balancer. I found that this caused errors when connecting via WebSocket. Because of this, I configured the application to use an Application Load Balancer instead, because I was told that ALBs support WebSockets. However, it seems that they do not: I get exactly the same error when attempting to connect to my ALB via WebSocket.

Do ALBs actually support WebSocket? The AWS documentation is contradictory on this. This page says it only supports HTTP and HTTPS. There are no guides to setting up an ALB to support WebSocket.

like image 792
jameshfisher Avatar asked Sep 05 '16 18:09

jameshfisher


People also ask

Which Load Balancers support WebSockets?

The Application Load Balancer supports two additional protocols: WebSocket and HTTP/2. WebSocket allows you to set up long-standing TCP connections between your client and your server.

Can WebSockets be load balanced?

WebSocket load balancing is mutual problem of client and server. Without a hint from client, it is hardly possible to get 6D-tuple knowledge on the server side. A reasonable solution is to lift load balancing to the application level. It means that client application logic will be aware of server-side scaling.

Does Classic load balancer support WebSocket?

The Classic ELB doesn't support Websockets.

Does NLB support WebSocket?

Network Load Balancer (NLB) NLB is designed to handle tens of millions of requests per second while maintaining high throughput at ultra-low latency. NLB supports long-lived TCP connections that are ideal for WebSocket type of applications.


2 Answers

I was able to get WebSockets working with the new Application Load Balancer (ALB).

First, create a new Target Group for your ALB. This Target Group should use the same port as your application, and will need to have health checks configured. However, the main difference is that you must enable Stickiness.

Add Target Group with Stickiness

Next, add a new Listener Rule to your ALB. This rule must have a Path to route the WebSocket setup -- /socket.io. Also, set the Target Group Name to the Target Group you just created.

Add Listen rule for WebSocket

I am using Node/Hapi/Socket.io for my server (running on instance derived from Amazon Linux AMI). Basic setup is:

const hapi = require('hapi'); const websocket = require('./WebSocket');  var server = new hapi.Server(); server.connection(config.Application); websocket.Initialize(server.listener); 

where WebSocket.js is

var io = null;  module.exports = {      Initialize: function (http) {          io = require('socket.io')(http);          io.on('connection', function (socket) {             console.log('Websocket ' + socket.id + ' connected.');              socket.on('disconnect', function () {                 console.log('Websocket ' + socket.id + ' disconnected.');             });         });     } }; 

I am using Angular 1.5x for my client, with socket.io-client. It is important to configure the WebSocket client options as follows, or you will not be able to connect.

(function () {      'use strict';      angular         .module('XXXXX', [])         .run(runHandler);      runHandler.$inject = ['WebSocketService'];      function runHandler(WebSocketService) {        WebSocketService.Initialize();     } })(); 

The WebSocket service:

(function () {      'use strict';      angular         .module('XXXXX')         .factory('WebSocketService', WebSocketService);      WebSocketService.$inject = [];      function WebSocketService() {          var socket = null;          function initialize() {              var url = 'http://' + ALB_URL + ':5800';              socket = io(url, {transports: ['websocket'], upgrade: false});              socket.on('connect', function () {                 console.log('Socket connected');             });              socket.on('disconnect', function () {                 console.log('Socket disconnected');             });         }          return {             Initialize: initialize         };     } })(); 
like image 183
programmerj Avatar answered Sep 22 '22 11:09

programmerj


ALB support Websocket but the load balancer can close the connection if the instance doesn't send some data at least every "idle timeout" seconds.

like image 21
Namtrh Avatar answered Sep 23 '22 11:09

Namtrh