一、WebSocket概述
1、简介
现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
WebSocket一种在单个 TCP 连接上进行全双工通讯的协议。使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
以上信息摘自维基百科(https://zh.wikipedia.org/wiki/WebSocket)
简单点说,WebSocket 就是减小客户端与服务器端建立连接的次数,减小系统资源开销,只需要一次 HTTP 握手,整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的非状态性,服务端会一直与客户端保持连接,直到你关闭请求,同时由原本的客户端主动询问,转换为服务器有信息的时候推送。当然,它还能做实时通信、更好的二进制支持、支持扩展、更好的压缩效果等这些优点。
推荐一个知乎上叫 Ovear 的网友关于 WebSocket 原理的回答,嘻哈风格科普文,简直不要更赞了!地址:https://www.zhihu.com/question/20215561/answer/40316953
2、ws 和 wss
Websocket使用 ws
或 wss
的统一资源标志符,类似于 HTTP
或 HTTPS
,其中 wss
表示在 TLS 之上的 Websocket ,相当于 HTTPS 了。如:
ws://example.com/chat wss://example.com/chat
默认情况下,Websocket 的 ws 协议使用 80 端口;运行在TLS之上时,wss 协议默认使用 443 端口。其实说白了,wss 就是 ws 基于 SSL 的安全传输,与 HTTPS 一样样的道理。
如果你的网站是 HTTPS 协议的,那你就不能使用 ws://
了,浏览器会 block 掉连接,和 HTTPS 下不允许 HTTP 请求一样,如下图:
二、nginx配置WebSocket
根据网上的配置:
location /websocket { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
但是结果报404错误
经过亲自反复的测试,还需要加上 proxy_set_header Host $host,具体原因还不清楚,但是根据Host解释(通过Host头得知用户访问的真正的域名),从而判断是由于nginx多域名造成的。
最后配置为:
location /websocket { proxy_pass http://backend; 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 "upgrade"; }
Nginx 自从 1.3 版本就开始支持 WebSocket 了,并且可以为 WebSocket 应用程序做反向代理和负载均衡。
WebSocket 和 HTTP 协议不同,但是 WebSocket 中的握手和 HTTP 中的握手兼容,它使用 HTTP 中的 Upgrade 协议头将连接从 HTTP 升级到 WebSocket,当客户端发过来一个 Connection: Upgrade
请求头时,Nginx 是不知道的,所以,当 Nginx 代理服务器拦截到一个客户端发来的 Upgrade
请求时,需要显式来设置Connection
、Upgrade
头信息,并使用 101(交换协议)返回响应,在客户端和代理服务器、后端服务器之间建立隧道来支持 WebSocket。
当然,还需要注意一下,WebSockets 仍然受到 Nginx 缺省为60秒的 proxy_read_timeout 的影响。这意味着,如果你有一个程序使用了 WebSockets,但又可能超过60秒不发送任何数据的话,那你要么需要增加超时时间,要么实现一个 ping 的消息以保持联系。使用 ping 的解决方法有额外的好处,可以发现连接是否被意外关闭。
更具体文档详见 Nginx 官方文档:http://nginx.org/en/docs/http/websocket.html
三、nginx-ingress-controller支持websocket访问
在 nginx-ingress-controller 中默认已经支持websocket访问
官方文档中说明websocket不需要特别的配置,但需要在注解中配置以下三项
nginx.ingress.kubernetes.io/proxy-http-version: "1.1" nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
参考链接:
https://blog.csdn.net/qq_33314107/article/details/81127666
https://blog.csdn.net/qq_35808136/article/details/89677749
https://blog.csdn.net/weixin_39669147/article/details/111282088