1. WebSocket协议

WebSocket 协议提供了一种创建支持客户端和服务端实时双向通信Web应用程序的方法。作为HTML5规范的一部分,WebSockets简化了开发Web实时通信程序的难度。目前主流的浏览器都支持WebSockets,包括火狐、IE、Chrome、Safari以及Opera等,而且,越来越多的服务器应用框架也开始支持WebSockets。

要在企业产品中使用WebSockets,为满足高性能和高可用性,需要多个WebSocket服务器。负载均衡层需要支持WebSocket协议。Nginx从1.3版起就开始支持WebSocket协议,而且可以担当WebSocket应用程序的反向代理以及实现负载均衡。

WebSocket协议和HTTP协议不同,但是WebSocket协议的握手和HTTP是兼容的,它使用HTTP的Upgrade协议头将连接从HTTP连接升级到WebSocket连接。这个特性使得WebSocket应用程序可以很容易地应用到现有的基础设施。例如,WebSocket应用可以使用标准的80和443 HTTP端口,因此可以通过现有的防火墙设施。

WebSockets应用程序会在客户端和服务器之间建立一个长连接,使得开发实时应用很容易。HTTP的Upgrade协议头机制用于将连接从HTTP连接升级到WebSocket连接,Upgrade机制使用了Upgrade协议头和Connection协议头。反向代理服务器在支持WebSocket协议方面面临着一些挑战。挑战之一是WebSocket是一个逐段转发(hop-by-hop)协议,因此当代理服务器拦截到来自客户端的Upgrade请求时,代理服务器需要将自己的Upgrade请求发送给后端服务器,包括适合的请求头。而且,由于WebSocket连接是长连接,与传统的HTTP端连接截然不同,故反向代理服务器还需要允许这些连接处于打开(Open)状态,而不能因为其空闲就关闭了连接。

NGINX支持WebSocket。对于NGINX将升级请求从客户端发送到后台服务器,必须明确设置Upgrade和Connection标题。

2. Nginx配置

Nginx通过在客户端和后端服务器之间建立隧道来支持WebSockets通信。为了让Nginx可以将来自客户端的Upgrade请求发送到后端服务器,Upgrade和Connection的头信息必须被显式的设置。

1)编辑nginx.conf,在http区域内一定要添加下面配置:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
} map指令的作用:
该作用主要是根据客户端请求中$http_upgrade 的值,来构造改变$connection_upgrade的值,即根据变量$http_upgrade的值创建新的变量$connection_upgrade,
创建的规则就是{}里面的东西。其中的规则没有做匹配,因此使用默认的,即 $connection_upgrade 的值会一直是 upgrade。然后如果 $http_upgrade为空字符串的话,
那值会是 close。 2)编辑vhosts下虚拟主机的配置文件,在location匹配配置中添加如下内容:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade"; 示例如下:
upstream socket.kevin.com {
hash $remote_addr consistent;
server 10.0.12.108:9000;
server 10.0.12.109:9000;
} location / {
proxy_pass http://socket.kevin.com/;
proxy_set_header Host $host:$server_port;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
} 3)可能会出现跨域问题,server区块填写以下跨域配置即可

add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}

一旦我们完成以上设置,Nginx就可以处理WebSocket连接了

proxy_http_version 1.1;,为什么使用http1.1协议?(https://blog.csdn.net/moxiaomomo/article/details/74734565)

设置代理使用的HTTP协议版本。默认使用的版本是1.0,而1.1版本则推荐在使用keepalive连接时一起使用。

因为http1.0不支持keepalive特性,当没有使用http1.1的时候,后端服务会返回101错误,然后断开连接。

map的作用

1.map的作用主要是根据客户端请求中 $http_upgrade 的值,来构造改变 $connection_upgrade 的值,即根据变量 $http_upgrade 的值创建新的变量 $connection_upgrade,创建的规则就是 {} 里面的东西,上图代码中(第一个标记点)的规则没有做匹配,因此使用默认的,即 $connection_upgrade 的值会一直是 upgrade。然后如果 $http_upgrade为空字符串的话,那值会是 close。

HTTP的Upgrade协议头

HTTP的Upgrade协议头机制用于将连接从HTTP连接升级到WebSocket连接,Upgrade机制使用了Upgrade协议头和Connection协议头;为了让Nginx可以将来自客户端的Upgrade请求发送到后端服务器,Upgrade和Connection的头信息必须被显式的设置。

3. Nginx代理WebSocket保持长连接的方案

现象描述:用nginx反代代理某个业务,发现平均1分钟左右,就会出现webSocket连接中断,然后查看了一下,是nginx出现的问题。
产生原因:nginx等待第一次通讯和第二次通讯的时间差,超过了它设定的最大等待时间,简单来说就是超时!

解决方法1
其实只要配置nginx.conf的对应localhost里面的这几个参数就好
proxy_connect_timeout;
proxy_read_timeout;
proxy_send_timeout;

解决方法2
发心跳包,原理就是在有效地再读时间内进行通讯,重新刷新再读时间

http {
server {
location / {
root html;
index index.html index.htm;
proxy_pass http://webscoket;
proxy_http_version 1.1;
proxy_connect_timeout 4s; #配置点1
proxy_read_timeout 60s; #配置点2,如果没效,可以考虑这个时间配置长一点
proxy_send_timeout 12s; #配置点3
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
}

关于上面配置2的解释
这个是服务器对你等待最大的时间,也就是说当你webSocket使用nginx转发的时候,用上面的配置2来说,如果60秒内没有通讯,依然是会断开的,所以,你可以按照你的需求来设定。比如说,我设置了10分钟,那么如果我10分钟内有通讯,或者10分钟内有做心跳的话,是可以保持连接不中断的,详细看个人需求

WebSocket与Socket的关系
- Socket其实并不是一个协议,而是为了方便使用TCP或UDP而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。当两台主机通信时,必须通过Socket连接,Socket则利用TCP/IP协议建立TCP连接。TCP连接则更依靠于底层的IP协议,IP协议的连接则依赖于链路层等更低层次。
- WebSocket就像HTTP一样,则是一个典型的应用层协议。
总的来说:Socket是传输控制层接口,WebSocket是应用层协议。

参考:

https://www.cnblogs.com/kevingrace/p/9512287.html

https://yq.aliyun.com/articles/73865

https://www.cnblogs.com/piperck/p/7066286.html

http://www.ttlsa.com/nginx/using-nginx-map-method/

https://blog.csdn.net/chszs/article/details/26369257

Nginx反向代理WebSocket(WSS)的更多相关文章

  1. Nginx反向代理websocket配置实例

    最近有一个需求,就是需要使用 nginx 反向代理 websocket,经过查找一番资料,目前已经测试通过,本文只做一个记录 复制代码 代码如下: 注: 看官方文档说 Nginx 在 1.3 以后的版 ...

  2. NGINX: 反向代理 websocket

    参考: [ Using multiple nodes ] [ Nginx 官网 WebSocket proxying ] 关于 websocket 的介绍可以看阮大大的这篇 [ WebSocket 教 ...

  3. 配置 Nginx 反向代理 WebSocket

    用Nginx给网站做反向代理和负载均衡是广泛使用的一种Web服务器部署技术.不仅能够保证后端服务器的隐蔽性,还可以提高网站部署灵活性. 今天我们来讲一下,如何用Nginx给WebSocket服务器实现 ...

  4. 配置Nginx反向代理WebSocket,以代理noVNC为例

    什么是Nginx Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器. Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮 ...

  5. Nginx反向代理websocket配置实例(官网)

    https://www.nginx.com/blog/websocket-nginx/ Blog Tech Rick Nelson of NGINX, Inc.   May 16, 2014   NG ...

  6. Nginx反向代理WebSocket

    http { upstream websocket { server 192.168.1.1:8010; } server { listen 8020; location / { proxy_pass ...

  7. 【Linux】采用nginx反向代理让websocket 支持 wss

    背景:玩swoole 服务 使用Nginx反向代理解决wss问题. 即客户端通过wss协议连接 Nginx 然后 Nginx 通过ws协议和server通讯. 也就是说Nginx负责通讯加解密,Ngi ...

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

    http://www.jb51.net/article/112183.htm 最近在工作中遇到一个需求,需要使用 nginx 反向代理websocket,经过查找一番资料,目前已经测试通过,所以这篇文 ...

  9. EMQ配置通过nginx反向代理wss和ws

    参考:https://www.cnblogs.com/succour/p/6305574.html EMQ官方文档:https://docs.emqx.io/broker/v3/cn/ 一,系统环境及 ...

随机推荐

  1. iOS开发-植入广告(iAd, Admob实例)

    应用中植入广告是一种非常好的盈利手段. 以下介绍主流的两种方法.iAd, Admob 先mark一个非常具体的pdf.   http://pan.baidu.com/share/link?sharei ...

  2. 跨平台C、C++代码注意的事项

    在我们的开发中,跨平台的需求越来越强烈,怎样保持C/C++代码能在多个平台上编译,是一个比較值得研究的问题.关于跨平台的文章网上非常多,跨平台的库网上也非常多.那么我从自己的跨平台开发经验谈一谈自己的 ...

  3. Linux下查看history里的某种命令

    Linux下,直接键入history命令,会将当前账户此前所有的命令都显示出来,未免太多了些.如果我只想查找某种命令,怎么办? 比如说,我只想查找我之前运行过的 "git" 命令 ...

  4. ios16--自定义控件1

    k控制器: // // XMGViewController.h #import <UIKit/UIKit.h> @interface XMGViewController : UIViewC ...

  5. OTA升级包制作工具处理过程分析

    http://blog.csdn.net/ly890700/article/details/56048815 Android Recovery(30)  1.概述  OTA升级包制作工具是一个用pyt ...

  6. 【POI 2010】 Antisymmetry

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2084 [算法] manacher [代码] #include<bits/std ...

  7. 关于pycharm中pip版本10.0无法使用的解决办法

    背景: 近期在利用 pycharm 安装第三方库时会提示 pip 不是最新版本, 因此对 pip 进行更新,但是生成最新版本之后, pip 中由于缺少 main 函数,导致在 pycharm 中无法自 ...

  8. [Swift通天遁地]九、拔剑吧-(16)搭建卡片页面:Card Peek/Pop动态切换界面

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  9. idea git项目修改后无法提交 颜色都是灰色

    现象: idea git项目修改后无法提交   修改后的文件提交时不显示  颜色都是灰色 分析问题出现的原因: git未识别idea下项目. 排查: 发现是因为这个项目之前是基于svn的,然后直接导入 ...

  10. Bitmap与String之间的转换

    /** * 将bitmap转换成base64字符串 * * @param bitmap * @return base64 字符串 */ public String bitmaptoString(Bit ...