AWS WebSocket Considerations
Looking into what needs to be taken into account when using WebSockets with AWS services - primarily CloudFront, Application Load Balancer, and EC2. Will also look at NGINX WebSocket stuff too.
References
- Using WebSockets with CloudFront Distributions
- Listeners for Your Application Load Balancers
- How to Use Nginx as a Reverse Proxy for HTTPS and WSS - Self Signed Certificates and Trusted Certificates
Notes
How WebSockets Work on This Site
I am using WebSockets on this site for notifications and chat. For notifications, the WebSocket pings the backend at a specified interval to see if there are any new notifications. The servers sends push notifications during this process as well. The use of WebSockets for chat is self-explanatory.
I am using node's ws library for WebSockets on a Node.js server. The WebSocket server that is created on the EC2 instance shares the HTTP/S server that is currently set up on the EC2 instance. See this example on GitHub to see what I am taking about.
I am currently having the problem of what looks like WebSocket requests being converted to HTTP/S requests., so I am going to look into the AWS resources that I use for the server to see what might be causing this unwanted behavior.
CloudFront
Amazon CloudFront supports using WebSocket, a TCP-based protocol that is useful when you need long-lived bidirectional connections between clients and servers. A persistent connection is often a requirement with real-time applications. [...] Data over a WebSocket connection can flow in both directions for full-duplex communication.
WebSocket functionality is automatically enabled to work with any distribution. To use WebSockets, configure one of the following the cache behavior that's attached to your distribution:
- Forward all viewer request headers to your origin. You can use the AllViewer managed origin request policy.
- Specify forward the
Sec-WebSocket-Key
andSec-WebSocket-Version
request headers in your origin request policy.
The WebSocket protocol is an independent, TCP-based protocol that allows you to avoid some of the overhead - and potentially increased latency - of HTTP.
To establish a WebSocket connection, the client sends a regular HTTP request that uses HTTP's upgrade semantics to change the protocol. The server can then complete the handshake. The WebSocket connection remains open and either the client of server can send data frames to each other without having to establish new connections each time.
By default, the WebSocket protocol uses port 80 for regular WebSocket connections and port 443 for WebSocket connections over TLS/SSL. The options that you choose for your CloudFront Viewer protocol policy and Protocol (custom origins only) apply to WebSocket connections as well as to HTTP traffic.
To avoid unexpected compression-related issues when using WebSockets, it is recommended to include the following headers in an origin request policy:
Sec-WebSocket-Key
Sec-WebSocket-Version
Sec-WebSocket-Protocol
Sec-WebSocket-Accept
Sec-WebSocket-Extensions
Application Load Balancer
A listener is a process that checks for connection requests, using the protocol and port that you configure. Before start using your Application Load Balancer, you must add at least one listener. If your load balancer has no listeners, it can't receive traffic from clients. The rules that you define for your listeners determine how the load balancer routes requests to the targets that you register, such as EC2 instances.
Listener Configuration
Listeners support the following protocols and ports:
- Protocols: HTTP, HTTPS
- Ports: 1-65535
If your listener protocol is HTTPs, you must deploy at least one SSL server certificate on the listener. Create an HTTPS listener on your application load balancer. If you must ensure that the targets decrypt HTTPS traffic instead of the load balancer, you can create a Network Load Balancer with a TCP listener on port 443. With a TCP listener, the load balancer passes encrypted traffic through to the targets without decrypting it.
Application Load Balancers provide native support for WebSockets. You can upgrade an existing HTTP/1.1 connection into a WebSocket (ws
or wss
) connection by using an HTTP connection upgrade. When you upgrade, the TCP connection is used for requests (to the load balancer as well as to the target) becomes a persistent WebSocket connection between the client and the target through the load balancer. You can use WebSockets with both HTTP and HTTPS listeners. The options you choose for your listener apply to WebSocket connections as well as to HTTP traffic. For more information, see How the WebSocket Protocol Works in the Amazon CloudFront Developer Guide.
NGINX
Add the following under location /
in nginx.conf
:
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
Comments
You have to be logged in to add a comment
User Comments
Test of the notification system...