With the addition of WebSocket channels in Zato 3.0, a question arises of how to combine both HTTP and WebSocket channels in Zato environments. This article shows how a Docker container running in AWS can be configured to expose a single port to handle both kind of requests, including health-status checks from Amazon’s ALB (Application Load Balancer).

Configuration

The configuration we would like to arrive at is in the diagram below:

Screenshots
  • There is ALB (Application Load Balancer) which sends HTTP pings to Zato, expecting an HTTP 200 OK response if everything is fine
  • There are WebSocket-based clients (WSX) that send their own business requests, independent of regular HTTP ones
  • A Docker container holds a Zato environment, publishing port 11224 to the outside world, to ALB and WSX
  • Inside the container, Zato’s load-balancer, based on HAProxy, distributes requests individual TCP sockets of a Zato server
  • If the request begins with a well-known prefix (here, /ws), it is forwarded to a WebSocket channel on port 48902
  • All other requests, including the one from ALB, will go the default HTTP port at 17010

WebSocket channel

First step is to ensure that a WebSocket channel’s path begins with the desired prefix, such as /ws, as in the screenshot.

Screenshots

HAProxy

Now, HAProxy needs to be reconfigured in its source code view, from web-admin:

Screenshots
  • The changes required need to go the stanza called ‘front_http_plain’ - right after its current content add the lines with logic that will separate incoming requests into WebSocket ones or any other.

  • Next, add a new HAProxy backend pointing to the WebSocket channel created earlier.

  • Now, stop and start the load-balancer again

# ##############################################################################

frontend front_http_plain

    ...

    acl is_websocket path_beg /ws
    acl is_websocket hdr(Upgrade) -i WebSocket
    use_backend websockets if is_websocket

# ##############################################################################

backend websockets
    mode http
    option http-server-close
    option forceclose

    server http_plain--server1 127.0.0.1:48902 check inter 2s rise 2 fall 2

# ##############################################################################

That’s it

There are no more steps as far Zato is concerned - if a Docker container is now started with port 11224 mapped to 11223 inside the container, all the external applications will be able to access Zato-based services using both HTTP and WebSockets through a single port:

$ docker run -p 11224:11223 zato