Nginx serves as WebSockets agent
English Original: http://nginx.com/blog/websocket-nginx/
Chszs, reprint need to indicate. Blog home: Http://blog.csdn.net/chszsThe WebSocket protocol provides a way to create a Web application that supports real-time bidirectional communication between the client and the service side. As part of the HTML5 specification, WebSockets simplifies the difficulty of developing web real-time communication programs. Mainstream browsers now support WebSockets, including Firefox, IE, Chrome, Safari, and opera, and more and more server application frameworks are beginning to support WebSockets.
To use WebSockets in enterprise products, multiple WebSocket servers are required to meet high performance and high availability. The load balancer layer needs to support the WebSocket protocol. Nginx supports the WebSocket protocol from version 1.3 and can act as a reverse proxy for websocket applications and load balancing.
The WebSocket protocol differs from the HTTP protocol, but the handshake and HTTP for the WebSocket protocol are compatible, and it uses the HTTP upgrade protocol header to upgrade the connection from an HTTP connection to a websocket connection. This feature makes it easy for websocket applications to be applied to existing infrastructures. For example, WebSocket applications can use standard 80 and 443 HTTP ports, so they can be passed through existing firewall facilities.
The WebSockets application establishes a long connection between the client and the server, making it easy to develop real-time applications. The upgrade protocol header mechanism for HTTP is used to upgrade connections from an HTTP connection to an WebSocket connection, and the upgrade mechanism uses the upgrade protocol header and the connection protocol header. Reverse proxy servers face a number of challenges in supporting the WebSocket protocol. One of the challenges is that WebSocket is a piecemeal forwarding (hop-by-hop) protocol, so when a proxy server intercepts upgrade requests from clients, the proxy server needs to send its own upgrade request to the backend server, including the appropriate request header. Also, because the WebSocket connection is a long connection and is very different from the traditional HTTP end connection, the reverse proxy server also needs to allow these connections to be in open state, and not to shut down the connection because it is idle.
Nginx supports websockets communication by establishing a tunnel between the client and the back-end server. In order for Nginx to send the upgrade request from the client to the backend server, the header information of upgrade and connection must be explicitly set. As shown below:
location/wsapp/{ Proxy_pass http://wsbackend; Proxy_http_version 1.1; Proxy_set_header Upgrade $http _upgrade; Proxy_set_header Connection "Upgrade";}
Once we have completed the above setup, Nginx can handle the WebSocket connection.
Nginx WebSockets Instance
The following example describes how Nginx is acting for websocket. This example uses the WS module, which is a websocket implementation built on node. js. Nginx will act as a reverse proxy server, and the backend server is a simple WebSockets application that uses WS and node. js. The commands used in the example are tested on Ubuntu 13.10 and CentOS 6.5, but may require minor modifications for other operating systems. For this example, the IP address of the WebSocket server is the IP address of the 192.168.100.10,nginx server, which is 192.168.100.20. If you do not have node. js and NPM installed, you can install it by using the following command:
For Debian/ubuntu:
sudo apt-get install Nodejs NPM
For Rhel/centos:
sudo yum install Nodejs NPM
On Ubuntu, node. JS will be installed as "Nodejs", but it will be installed as "node" in CentOS. We use "node" uniformly in the example, so we'll create a symbolic connection on Ubuntu that allows us to use "node":
Ln-s/usr/bin/nodejs/usr/local/bin/node
Then install WS:
sudo npm install ws
Note: If you get an error: "Error:failed to fetch from REGISTRY:WS", then running the following command should solve the problem:
sudo npm config set registry http://registry.npmjs.org/
Next, you can run the sudo npm install WS again
The WS module comes from/root/node_modules/ws/bin/wscat and we will use it for the client, but we need to create a program to serve as our server. Save the following code in a server.js file:
Console.log ("Server started"); var Msg = '; var websocketserver = require (' ws '). Server , WSS = new Websocketserver ({port:8010}); Wss.on (' Connection ', function (WS) { ws.on (' message ', function (message) { Console.log (' Received from client:% s ', message); Ws.send (' Server received from client: ' + message); }); });
This program can be executed with the following command:
Node Server.js
The program outputs an initialization message "Server started" and then listens on port 8010, waiting for the client to connect. It processes all requests received and outputs the received message to the console, after which a message containing the message is returned to the client. We want Nginx to proxy client's request, which can be implemented by the following configuration:
Map $http _upgrade $connection _upgrade { default upgrade; ' close;} Upstream WebSocket { server 192.168.100.10:8010;} server { listen 8020; Location/{ Proxy_pass http://websocket; Proxy_http_version 1.1; Proxy_set_header Upgrade $http _upgrade; Proxy_set_header Connection "Upgrade"; }}
The above configuration will allow Nginx to listen to Port 8020 and forward any received requests to the backend WebSocket server, so that the backend server can better handle the WebSocket protocol. We can use Wscat as a client to test:
/root/node_modules/ws/bin/wscat–connect ws://192.168.100.20:8020
The above command establishes a connection through the Nginx reverse proxy server and the backend WebSocket server, and you can send any message to the server, and the server returns a message. Whenever you send a message on the client, you can see the output of the message on the back-end server, and then a message from the service side is displayed on the client.
Here is an example of an interaction:
Server: |
Client: |
$ node Server.js |
|
Server started |
|
|
Wscat–connect ws://192.168.100.20:8020 |
|
Connected (Press CTRL + C to quit) |
|
> Hello |
Received from Client:hello |
|
|
< Server received from Client:hello |
From this we can see that the client and the server can establish websockets communication through the Nginx reverse proxy, and the message can be transmitted continuously in two directions until the client or server disconnects. In order for Nginx to properly handle the WebSocket connection, it is only necessary to properly set the message header to handle the upgrade request to upgrade from an HTTP connection to a websocket connection.