websocket协议与反向代理websocket协议的一些细节。

websocket协议解决了在http/1.1的基础上实现主动推送的问题。而在此之前要想实现实时消息接收,需要AJAX设置一个定时器轮询,这样有诸多缺点:例如时间粒度太大导致消息不及时,粒度太小又存在大量资源浪费的情况。websocket区别于HTTP2协议的是不能实现多路复用,在一个连接上还是一来一回

如果我们有打开浏览器网络面板的习惯的话,可以发现websocket协议在当前使用还是非常频繁的。这里通过分析websocket协议帧格式和使用nginx反向代理websocket协议来对websocket做一个总结。

websocket帧格式

来自极客时间陶辉老师《web协议详解与抓包实战》

使用nginx反向代理websocket实现

使用nginx反向代理websocket协议,其实就是将客户端传递的请求头部使用proxy_set_header 再次传递到上游的websocket服务器。那么我们先看一下客户端的请求头部都有哪些内容。这里我使用jumpserver的web终端进行演示,在点击相应的主机之后,我们进入了网页版的终端里,打开浏览器的网络面板:

可以看到状态码是101,协议是websocket,使用的scheme是ws,如果使用TLS加密过后,scheme将是wss.

点开详情:

101状态码表示协议转换,也就是我们从http协议升级到websocket协议。
请求头部中Connection为Upgrade,Upgrade为websocket,这就是表示客户端要进行一个协议升级,升级到的协议是websocket协议。直接基于tcp协议之上的HTTP2协议h2c在进行协议升级的时候也是这样,只不过Upgrade头部传递的是h2c,单挑这两个头部进行说明的原因是nginx发起一个新的请求到上游的时候,Connection头部默认是close,而Upgrade头部在传递到上游的时候是空的。所以在配置nginx的时候需要特殊声明一下,否则在传递到上游的时候将不能正常升级到websocket协议。其次还要声明与上游之间的http协议是http/1.1。

在需要反向代理的location添加以下配置:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;

第一行就是声明http协议版本,第二行将客户端发送的Upgrade头部传递到上游,第三行将客户端发送的Connection头部传递到上游,其实这是一个通用的写法,用于升级h2c这样写也可以,如果确定是websocket协议,那么向上游传递的Connection头部写upgrade,upgrade头部写websocket也可以的,就是下面的配置方法:

proxy_http_version 1.1;
proxy_set_header Upgrade “websocket”;
proxy_set_header Connection “upgrade”;

websocket存在的问题

留下评论