nginx设置webscoket代理方法以及注意事项

为啥要写这篇文章呢?

最近在做websocket的项目,踩到的坑做一个总结。

1.ws和wss问题

2.代理设置问题

3.域名开启DNS后在使用代理出现的问题

1.配置Nginx支持WSS(WebSocket)

简单了解一下 WebSocket

  WebSocket一种在单个 TCP 连接上进行全双工通讯的协议。使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

以上信息摘自维基百科( https://zh.wikipedia.org/wiki/WebSocket )

简单点说,WebSocket 就是减小客户端与服务器端建立连接的次数,减小系统资源开销,只需要一次 HTTP 握手,整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的非状态性,服务端会一直与客户端保持连接,直到你关闭请求,同时由原本的客户端主动询问,转换为服务器有信息的时候推送。当然,它还能做实时通信、更好的二进制支持、支持扩展、更好的压缩效果等这些优点。

推荐一个知乎上叫 Ovear 的网友关于 WebSocket 原理的回答,嘻哈风格科普文,简直不要更赞了!地址: https://www.zhihu.com/question/20215561/answer/40316953

ws和wss是什么鬼?

Websocket使用 ws 或 wss 的统一资源标志符,类似于 HTTP 或 HTTPS ,其中 wss 表示在 TLS 之上的 Websocket ,相当于 HTTPS 了。如

ws://example.com/websocket

wss://example.com/websocket

默认情况下,Websocket 的 ws 协议使用 80 端口;运行在TLS之上时,wss 协议默认使用 443 端口。其实说白了,wss 就是 ws 基于 SSL 的安全传输,与 HTTPS 一样样的道理。

如果网站是https协议的话就不能使用ws://,会报协议错误,那怎么办呢?

Nginx 配置域名支持 WSS

不用废话,直接在配置 HTTPS 域名位置加入如下配置:

location /websocket {

    proxy_pass http://backend;

    proxy_http_version 1.1;

    proxy_set_header Upgrade $http_upgrade;

    proxy_set_header Connection "upgrade";

}

接着拿域名再次连接试一下,不出意外会看 101 状态码,链接成功

2.Nginx实战之反向代理WebSocket的配置实例

NGINX侦听端口8020,并向后端WebSocket服务器发送代理请求。该proxy_set_header指令使NGINX妥善处理WebSocket协议。

ws.conf文件内容如下:

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 $connection_upgrade;

    }

}

WebSocket集群

在实际的生产环境中,要求多个WebSocket服务器必须具有高性能和高可用,那么WebSocket协议就需要一个负载均衡层,NGINX从1.3开始支持WebSocket,其可以作为一个反向代理和为WebSocket程序做负载均衡。

Nginx配置

注:看官方文档说 Nginx 在 1.3 以后的版本才支持 websocket 反向代理,所以要想使用支持 websocket 的功能,必须升级到 1.3 以后的版本

NGINX通过允许一个在客户端和后端服务器之间建立的隧道来支持WebSocket。为了NGINX发送来至于客户端Upgrade请求到后端服务器,Upgrade和Connection头部必须被设置明确。

upstream wsbackend {

  server 127.0.0.1:8080;

  server 127.0.0.1:8081;

}

server {

  listen  80;

  server_name ws.52itstyle.com;

  location / {

  proxy_pass http://wsbackend;  proxy_http_version 1.1;

  proxy_set_header Upgrade $http_upgrade;

  proxy_set_header Connection "upgrade";

  }

}

前端配置:

$(function(){

socket.init();

});//Nginx反向代理实现websocketvar basePath = "ws://ws.52itstyle.com//acts_competition/";

socket = {

webSocket : "",

init : function() {

  if ('WebSocket' in window) {

  webSocket = new WebSocket(basePath+'webSocketServer');

  }

  else if ('MozWebSocket' in window) {

  webSocket = new MozWebSocket(basePath+"webSocketServer");

  }

  else {

  webSocket = new SockJS(basePath+"sockjs/webSocketServer");

  }

  webSocket.onerror = function(event) {

  //alert("websockt连接发生错误,请刷新页面重试!")  };

  webSocket.onopen = function(event) {

  };

  webSocket.onmessage = function(event) {

    };

},

sendData : function(data) {

  webSocket.send(data);

},

}

最后,重启下Nginx即可。

反向代理服务器在支持WebSocket时面临的挑战

WebSocket是端对端的,所以当一个代理服务器从客户端拦截一个Upgrade请求,它需要去发送它自己的Upgrade请求到后端服务器,也包括合适的头。

因为WebSocket是一个长连接,不像HTTP那样是典型的短连接,所以反向代理服务器需要允许连接保持着打开,而不是在它们看起来空闲时就将它们关闭。

3.使用CDN加速后,websocket对象无法访问

很简单的原因,CDN加速的是静态资源。

目前CDN还不支持websocket,建议将这类动态内容用一个单独的域名拆出来单独访问,不使用CDN访问。

使用阿里云的全站加速

你可能感兴趣的:(nginx设置webscoket代理方法以及注意事项)