Real-Time Web Applications with WebSocket and NGINX

In the blog post NGINX as a WebSocket Proxy we discussed using NGINX to proxy WebSocket application servers. In this post we will discuss some of the architecture and infrastructure issues to consider when creating real-time applications with WebSocket, including the components you need and how you can structure your systems.

WebSocket Adds Interactivity to HTTP

HTTP works well for web applications that are request/response based, where the communications flow always has the client initiating the request to which a backend server responds. Web applications with a more interactive, message-based interaction between the client and server need something beyond simple HTTP. Previous attempts to simulate full-duplex communication over HTTP were complicated and had many drawbacks. The WebSocket protocol, along with the WebSocket JavaScript interface, provide a much easier way to build these types of applications while also reducing the amount of data transferred and the latency.

The ability to create a full-duplex socket connection between the client and server allows for the development of real-time event-driven web applications that utilize push, poll, or streaming communications. Using WebSocket, either the client or the server can initiate communication after the connection is established. This enables many types of web applications, including online games, chat, stock tracking, and real-time reporting of sports scores.

Another use case for WebSocket is developing WebRTC-based applications. WebRTC is used to create applications that do browser-to-browser communications. It requires a separate signaling channel for setup of communications, and WebSocket is a good protocol to use for this.

Technical Requirements for a WebSocket Application

The minimum infrastructure required for a WebSocket web application is a client browser running a WebSocket JavaScript application and communicating with a WebSocket server. The recent releases of all major browsers now support WebSocket, but it is important to make sure that the clients have a browser with WebSocket support. There are many options for WebSocket servers and here are some examples for different environments (this list is provided for your convenience and doesn’t constitute endorsement by NGINX, Inc.):

   Node.js Ruby
ws websocket-rails
socket.io em-websocket
SockJS webmachine-ruby
   
Perl Tomcat
Mojolicious WebSocket How-To
Net::WebSocket::Server
   
PHP WebLogic
Ratchet Using WebSockets in WebLogic Server
PHP-Push-WebSocket
PHP-Websockets
   
Python
websockets
ws4py

Scaling WebSocket to High Traffic Volumes

It’s possible to use a single WebSocket server, but application performance is limited by the capacity of the server, which is also a single point of failure. Many real-time applications are developed with the hope of seeing widespread adoption, but it can difficult to predict the rate of growth. To support the increasing popularity of a real-time application the infrastructure must be able to:

  • Scale to support a large number of concurrent users
  • Provide low latency when handling communications between client and server
  • Support high availability (implying there is no single point of failure)
  • Allow for the configuration to be easily changed and adapt to changing conditions

This can be accomplished by putting NGINX in front of the WebSocket servers and HTTP servers (since most WebSocket applications also use HTTP), to act as a WebSocket-aware reverse proxy and load balancer. Not all reverse proxies provide direct support for WebSocket. Some, such as Elastic Load Balancing (ELB) in the Amazon Web Services (AWS) environment, have to run in TCP mode, meaning that they cannot deal with HTTP headers. The Proxy Protocol was developed to deal with this limitation and NGINX supports it as well, meaning WebSocket is fully supported in AWS. Using NGINX as a WebSocket reverse proxy brings additional benefits, such as routing flexibility and the ability to have NGINX terminate SSL connections.

A typical WebSocket configuration using NGINX might look something like this:

Here we show a variety of desktop and mobile clients connecting to a highly available pair of NGINX servers that are load balancing a set of HTTP and WebSocket servers. This type of configuration can withstand the failure of a WebSocket server or an NGINX server and you can easily add or remove WebSocket servers. Also, all the routing details of how to connect to the WebSocket servers is hidden from the clients, making for a robust and scalable WebSocket application infrastructure. Web performance and reliability for real-time web applications is critical. Contact us today to learn how NGINX Plus can help improve the performance, reliability, and availability of your applications.

For more information, please see:

Cover image
Microservices: From Design to Deployment
The complete guide to microservices development