1. 前言
项目一些信息需要通过站内信主动推动给用户,使用websocket。web服务器选用nginx,但是域名是以前通过阿里云申请的,解析ip也是阿里云的服务器,甲方不希望更换域名。新的系统需要部署在内网服务器,简单拓扑图如下所示:

其中第二台服务器运维不在我们这边,nginx反向代理需要经过多级配置,相关软件版本如下:
| 软件 | 版本 | 描述 | 
|---|---|---|
| centos | 7 | 操作系统inux发行版本 | 
| nginx | ngx_openresty/1.4.3.6 | web服务器软件 | 
2. nginx配置代理websocket
nginx转发websocket添加配置如下:
            
            
              nginx
              
              
            
          
          map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
}
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
## 或者
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";完整nginx server配置如下:
            
            
              nginx
              
              
            
          
          map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
}
server {
    listen       80;
    server_name   www.abc.com;
      # ws 转发
      location /websocket {
          proxy_pass http://xxx.xxx.xxx.xxx; 
          proxy_set_header  Host  $host;
          proxy_set_header  X-real-ip $remote_addr;
          proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection $connection_upgrade;
      }    
     location / {
         proxy_set_header  Host  $host;
         proxy_set_header  X-real-ip $remote_addr;
         proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
         
         client_max_body_size 500M;
         
         proxy_pass http://xxx.xxx.xxx.xxx;
     }
}
server {
        listen 443 ssl;
        #配置HTTPS的默认访问端口为443。
        #如果未在此处配置HTTPS的默认访问端口,可能会造成Nginx无法启动。
        #如果您使用Nginx 1.15.0及以上版本,请使用listen 443 ssl代替listen 443和ssl on。
        server_name www.abc.com; #需要将yourdomain替换成证书绑定的域名。
        
        proxy_set_header  Host  $host;
        proxy_set_header  X-Real-Ip $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        ssl_certificate cert/www.abc.com.pem;         #需要将cert-file-name.pem替换成已上传的证书文件的名称。
        ssl_certificate_key cert/www.abc.com.key; #需要将cert-file-name.key替换成已上传的证书私钥文件的名称。
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        #表示使用的加密套件的类型。
        ssl_protocols TLSv1.1 TLSv1.2; #表示使用的TLS协议的类型。
        ssl_prefer_server_ciphers on;
        
        client_max_body_size 500M;
        
        # wss 转发
        location /websocket {
            proxy_pass http:http://xxx.xxx.xxx.xxx; 
            proxy_set_header  Host  $host;
            proxy_set_header  X-Real-Ip $remote_addr;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
	          proxy_http_version 1.1;
	          proxy_set_header Upgrade $http_upgrade;
	          proxy_set_header Connection $connection_upgrade;
	      }
        location / {
            proxy_pass http://xxx.xxx.xxx.xxx;
        }
 }- 
/websocket是我们的前端websocket的链接路径 
- 
www.abc.com:可以更换为自己的域名 
- 
如果域名走http协议,只需要配置监听80端口;如果需要走https协议,只需要配置监听443端口即可 
关于域名,证书,nginx相关知识自行搜索相关内容。
3.多级nginx配置
多级nginx转发,同样每级都需要添加如下三项配置:
            
            
              nginx
              
              
            
          
          map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
}
# .......
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
## 或者
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";如果任一一级nginx没添加该配置,那么请求就是普通的http或者https请求,容易报错404。
完整配置参考2
4.问题
websocket连接失败常见问题,参考下面链接3;我遇到的问题如下
4.1 内层未配置头信息导致404
- 
浏览器console报错"wss://www.abc.com/websocket/xxx" 404,仔细看1中配置,监听443端口,其中有几项配置 nginxproxy_set_header Host $host; proxy_set_header X-real-ip $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;我在外层和/websocket都有配置 
- 
nginx配置生效为就近原则,如果路径配置/websocket那么,响应的/websocket下面配置生效;如果没匹配上,外层的就生效 
- 
当我把/websocket下面这几项配置去掉后,报错404,也就是说这几项配置放在外层没生效,现在我也没搞明白是啥原因? 
结语
❓QQ:806797785
⭐️仓库地址:https://gitee.com/gaogzhen
⭐️仓库地址:https://github.com/gaogzhen
1\][websocket多级nginx代理](https://blog.csdn.net/zhangnero/article/details/137225820)\[CP/OL\]. \[2\][解决 This request has been blocked; this endpoint must be available over WSS.](https://blog.csdn.net/weixin_47316183/article/details/126450623)\[CP/OL\]. \[3\][WebSocket 连接失败的根本原因及解决方法](http://www.connygpt.com/post/6216.html)\[CP/OL\]. \[4\][nginx转发WebSocket](https://juejin.cn/post/7035802428469411853)\[CP/OL\].