Wechat official account: Operation and maintenance development story, author: Jiang Zong

Hello, I’m Xiao Jiang.

The previous article looked at what the WebSocket protocol is. Here we review it and talk about how to use Nginx to proxy webSockets.

WebSocket is the next new protocol for HTML5. It realizes the full duplex communication between browser and server, which can save server resources and bandwidth and achieve the purpose of real-time communication. Like HTTP, it transmits data over an established TCP connection, but it differs from HTTP in that:

  • 1) WebSocket is a two-way communication protocol. After the connection is established, both WebSocket server and client can actively send or receive data to each other, just like Socket.

  • 2) WebSocket needs to establish a connection like TCP before communicating with each other.

Compared with HTTP, WebSocket can communicate multiple times after a successful handshake until the connection is closed. But the handshake in WebSocket is compatible with the HANDSHAKE in HTTP, which uses the Upgrade protocol header in HTTP to Upgrade the connection from HTTP to WebSocket. This makes it easier for WebSocket programs to use the existing infrastructure. Most modern browsers support WebSocket.

In the actual production environment, multiple WebSocket servers must have high performance and high availability, so the WebSocket protocol needs a load balancing layer, Nginx since ** “1.3” ** support WebSocket, It can act as a reverse proxy and load balancer for WebSocket programs.

The WebSocket protocol is different from the HTTP protocol, but the WebSocket handshake is compatible with HTTP. Use the HTTP upgrade tool to upgrade the connection from HTTP to WebSocket. This allows WebSocket applications to more easily fit into the existing infrastructure. For example, WebSocket applications can use standard HTTP ports 80 and 443, allowing existing firewall rules to be used.

“WebSocket applications can maintain a long-running connection between the client and the server,” helping to develop real-time applications. The HTTP Upgrade mechanism used to Upgrade a Connection from HTTP to WebSocket uses the Upgrade and Connection headers. Reverse proxy servers face some challenges in supporting Websockets. One is that WebSocket is a hop-by-hop protocol, so when the proxy server intercepts the upgrade request of the client, it needs to send its own upgrade request, including the corresponding header file, to the backend server. Also, because WebSocket connections are persistent, as opposed to the typical short-term connections used by HTTP, the reverse proxy needs to allow these connections to remain open rather than close them because they appear to be idle.

Nginx supports WebSockets, allowing the establishment of a tunnel between the client and the back-end server. For NGINX to send Upgrade requests from the client to the backend server, the Upgrade and Connection headings must be explicitly set.

Nginx enables the WebSocket proxy as follows:

1) Edit nginx.conf and make sure to add the following configuration in the HTTP area:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

Copy the code

** “Explain what the map directive does:” ** This is used to construct and change the value of connection_upgrade based on the value of the client request, i.e. create a new variable connection_upgrade based on the value of the variable. The rules are not matched, so the default is close if http_upgrade is an empty string.

2) Edit the configuration file of the virtual host under vhosts and add the following content to the location matching configuration:

Proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "$connection_upgrade"; # proxy_set_header Connection "Upgrade"; It is also possible to write UpgradeCopy the code

3) A complete example is shown below

upstream sre_backend { hash $remote_addr consistent; server sre1.ayunw.cn:8080; server sre2.ayunw.cn:8080; server sre3.ayunw.cn:8080; } server { listen 443 ssl; server_name sre.ayunw.cn; access_log /usr/local/nginx/logs/sre.ayunw.cn.access.log main; error_log /usr/local/nginx/logs/sre.ayunw.cn.. error.log error; ssl_certificate /data/certs/nginx/sre.ayunw.cn.crt; ssl_certificate_key /data/certs/nginx/sre.ayunw.cn.key; ssl_session_timeout 5m; Ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:! aNULL:! MD5; ssl_prefer_server_ciphers on; location / { proxy_pass http://sre_backend; proxy_ssl_server_name on; include proxy.conf; Proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "$connection_upgrade"; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; }}Copy the code

The above is one-way TLS authentication through nginx proxy WebSocket.

“Warm reminder:” By default, if the proxy server does not transfer any data within 60 seconds, the connection will be closed. You can increase this timeout using the proxy_read_timeout directive.

In summary:

“WebSocket and Http similarities”

  • It’s all the same TCP based, it’s all reliability transport protocol.

  • Both are application layer protocols.

“WebSocket vs. Http”

  • WebSocket is a two-way communication protocol that simulates the Socket protocol and can send or receive information in both directions. HTTP is one-way.

  • Websockets require a handshake between the browser and the server to establish a connection. HTTP is a connection initiated by the browser to the server that the server does not know about in advance.

** “WebSocket communicates with Http” ** When WebSocket establishes a handshake, data is transferred over Http. However, once established, the HTTP protocol is not required for actual transmission.

In WebSocket, the server and browser only need to shake hands through HTTP protocol, and then establish a SEPARATE TCP communication channel for data transmission. The procedure for a WebSocket connection is:

1) The client initiates an HTTP request and establishes a TCP connection after three handshakes. The HTTP request stores information about the Version supported by WebSocket, such as Upgrade, Connection, and websocket-version. 2) After receiving the handshake request from the client, the server also uses HTTP protocol to send back data; 3) After receiving the message that the connection is successful, the client starts to use the TCP transmission channel for full-duplex communication.

Nginx proxy webSocket frequently breaks (i.e. how to maintain long connections)

The problem is that nginx configuration requires several timeout Settings. As follows:

http { server { location / { root html; index index.html index.htm; proxy_pass http://sre_backend; Proxy_http_version 1.1; proxy_connect_timeout 5s; proxy_read_timeout 60s; proxy_send_timeout 30s; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "$connection_upgrade"; }}}Copy the code

“Explain the timeout configuration above”

** “proxy_read_timeout parameter” ** Default value: 60 seconds. This directive sets the read timeout time with the proxy server. This determines how long Nginx will wait to get a response to the request. This time is not the time to get the entire response, but the time for two reading operations. If you use Nginx to forward websockets, if there is no communication within 60 seconds, it will still be disconnected, so you can set it according to your requirements. For example, if I set it to 5 minutes, then if I have 5 minutes to communicate, or 5 minutes to do a heartbeat, I can stay connected. So this time is based on your business needs to adjust the length of time.

** “proxy_send_timeout parameter” ** Default value 60s: sets the timeout period for sending a request to the upstream server. The timeout is set not for the entire send period, but for both write operations. If upstream does not receive new data after a timeout, nginx will close the connection.

“WebSocket and Socket relationship:”

  • Socket is not a protocol, but a layer abstracted to facilitate the use of TCP or UDP. It is a group of interfaces between the application layer and the transmission control layer. When two hosts communicate with each other, they must be connected through a Socket, which uses TCP/IP to establish a TCP connection. TCP connections rely on the underlying IP protocol, and IP connections rely on the link layer and other lower layers.

  • WebSocket, like HTTP, is a typical application layer protocol.


  • Author: Ayunw Operations blog

  • Ayunw blog address: sre.ayunw.cn/

  • O&m Development Story blog :www.devopstory.cn/

  • Related topics: sre.ayunw.cn/posts/nginx…


Public account: Operation and maintenance development story

Making:Github.com/orgs/sunsha…

Love life, love operation