Nginx 配置 WebSocket
2016-06-14 by dongnan
WebSocket是什么?
WebSocket
是一种在客户端与服务器端之间保持TCP长连接的网络协议,这样它们就可以随时进行信息交换。
通过 WebSocket
,服务器可以直接向客户端发送数据,而无须客户端周期性的请求服务器,以动态更新数据内容。
为了建立一个 WebSocket
连接,客户端浏览器首先要向服务器端发起一个 HTTP
请求,这个请求稍有些不同,它包含了一些附加头信息,
其中附加头信息Upgrade: WebSocket
表明这是一个申请协议升级的 HTTP
请求。
服务器端解析这些附加的头信息,然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket
连接就建立起来了,
双方就可以通过这个连接通道自由的传递信息,并且这个链接会持续存在直到客户端或者服务器端的某一方主动的关闭链接。
客户端发送的内容
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Upgrade: WebSocket
表示这是一个特殊的 HTTP请求,客户端和服务器端的通讯协议从 HTTP协议升级到 WebSocket协议。Sec-WebSocket-Key:
是一个Base64 encode的值,这个是浏览器随机生成,验证是否能和服务器端进行 WebSocket通信。Sec_WebSocket-Protocol:
是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议。Sec-WebSocket-Version:
告诉服务器所使用的协议版本。
服务器端返回的内容
HTTP/1.1 101 Switching Protocols
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Accept:
表示经过服务器确认,并且加密过后的 Sec-WebSocket-Key
。用来证明客户端和服务器之间能进行通信了。
WebSocket解决了什么问题?
这里简单了解下 web的发展史,在2005年(ajax
还没诞生)以前,我们如果想要在一个页面显示显示不同的内容,或者说页面内跳转,只能是通过点击然后路由跳转,在ajax
诞生之后网页开始变得动态了。
但是所有的 HTTP通信还都是由客户端控制的,这就要需要"定期轮询"与服务器端进行通信。
ajax轮询
: 浏览器在特定的时间给服务器发送请求,查看服务器是否有信息数据,类似下图:
但是 ajax
轮询 这种方式增加了网络开销与服务器端资源消耗,是一种低效的实时交互方案。还有一点就是客户端总是主动的,服务器端总是被动的接收请求并响应数据。
WebSocket 解决的问题
持久性连接
JavaScript调用浏览器的API发出一个 WebSocket请求至服务器,经过三次握手后与服务器建立了TCP连接。 为什么要建立持久性连接(非http keep-alive)呢?这是因为HTTP协议是无状态的(连接断开之后就不知道刚才的客户端是谁了)。 WebSocket 解决了HTTP的无状态特性,在你关闭链接之前,服务器端会一直知道你的信息。
双向通信
当使用 WebSocket
时,服务端就能够主动推送数据给客户端啦。
配置WebSocket
配置文件
cat /etc/nginx/conf.d/default.conf
server {
# 省略...
location /wsapp/ {
proxy_pass http://wsbackend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
重启nginx
nginx -t && nginx reload
验证
访问服务器, 浏览器请求信息与服务器端响应信息如下图。
小结
最后来总结下文章中的知识点
- WebSocket 是一种在客户端与服务器端之间保持TCP长连接的网络协议。
- WebSocket 解决了客户端与服务器端双向通信问题。
- WebSocket 适用的应用场景,需要提供多个用户相互交流的功能,或者需要展示经常变动的数据,例如: 社交类应用、股票类应用、在线教育类应用,等应用场景。