WebSocket 协议是一个网络协议,允许两个相连的端点在一个单一的tcp连接上进行全双工通信。类似两个人通过手机进行通话。
WebSocket 的数据传输以帧的形式传输,将一条消息分为几个帧,按先后顺序传输出去。
这样做的好处是:
网络上的两个端点通过一个双向链路进行连接通信,这个双向链路的一端称为一个 Socket。一个 Socket 对应一个 IP 地址和端口号,应用程序通常通过 Socket 向网络发出或应答网络请求。
Socket 并不是协议,是针对 TCP/IP 协议层抽象出来的 API。
WebSocket 跟 HTTP 协议一样也是应用层协议。为了兼容 HTTP 协议,它通过 HTTP 协议进行一次握手(这里的握手指应用协议层,不是TCP层,握手时,TCP连接已建立),握手后数据就可以直接从 TCP 层传输,与 HTTP 协议再无关系。
即 HTTP请求里带有 WebSocket 的请求头,服务端回复也带有 websocket 的响应头。
来看一个通过HTTP升级的 WebSocket 连接:
毕竟三次握手还是很耗时的,在 HTTP/1.0 刚出现的时候,开发者就意识到 HTTP 持久连接的重要性,所以后续实现都采用了 Keep-Alive 来表示这个请求支持连接持久化。
使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive 避免了重新建立连接,达到连接复用。
缺点:
对于提供静态内容的网站来说,这个功能通常很有用。但是对于负担较重的网站来说,虽然为客户保留打开的连 接有一定的好处,但它同样影响了性能,因为在处理暂停期间,本来可以释放的资源却仍旧被占用。
解决办法:
比如 Keep-Alive: timeout=5, max=100
timeout:过期时间5秒(对应 tomcat 中 httpd.conf 里的参数是:KeepAliveTimeout)
max:最多100次请求,强制断掉连接。就是在 timeout 时间内又有新的连接过来,同时max会自动减1,直到为0,强制断掉。
Connection 头部一般会表示哪些头部是属于逐跳头部(hop-by-hop header),用来描述当前浏览器与直连服务器(比如Nginx反向代理)的连接信息。
比如 Keep-Alive 头部,仅仅表示浏览器尝试与 Nginx 连接持久化,而不管 Nginx 和后端服务器之间的连接,不应当被 Nginx 代理原样地传递给后端服务器。
默认的逐跳头部如下:
其他的头部都是 端到端头部(end-to-end header),用来描述浏览器和最终处理请求的服务器之间的信息,比如Accept 头部,表示客户端想从后端服务器得到的数据类型,而和中间的 Nginx 代理无关,Nginx 不能修改这些头部。
Connection 头部和 Upgrade 头部有不同的语义和使用场景:
RFC 规定如果只有Upgrade: websocket,说明proxy不支持WebSocket升级,应该视为普通 HTTP 请求。
RFC(Request For Comments)文档是目前关于某项技术官方维护的最全面、最权威的文档,是学习技术最重要的来源,享有网络知识圣经之美誉。
RFC的最初目的是为了把互联网研究者所完成的工作形成一个方便有用的文档以利于交流。最终,RFC文档成为了互联网的设计、架构、技术标准等内容的官方文档。
参考:
https://robberphex.com/why-is-connection-upgrade-necessary/
https://bbs.huaweicloud.com/blogs/351314?utm_source=csdn&utm_medium=bbs-ex&utm_campaign=other&utm_content=content