从 0 到 1 的 websocket -- 概念篇

2,013 阅读5分钟

技术篇 :Java 项目中的 WebSocket 实现

传统方式的消息推送

轮询

客户端定时向服务器发送 ajax 请求,服务器收到请求后马上返回消息并关闭连接。

优点 :简单粗暴,易于后端程序的编写。

缺点 :轮询需要频繁向服务器端发送请求,询问是否有资源需要更新,而这些请求大半是无用请求;此外,这种方式需要不断建立 Http 连接,从而造成服务器端与客户端的资源浪费。

长轮询

客户端向服务器发送请求,服务器收到请求后先按住不回复,直到有新消息时再返回响应并关闭连接;客户端处理完响应信息后再像服务器发送新的请求。

优点 :减少了很多不必要的 Http 请求次数,相比之下节约了资源。

缺点 :服务器长时间保持连接会消耗资源,需要同时维护多个线程。而服务器能承载的 TCP 连接数量是有限制的,这种轮询很容易使连接数耗尽。

长连接

在页面嵌入一个隐藏的 iframe,将这个隐藏 iframe 的 src 属性设置为对一个长连接的请求或是采用 xhr(XMLHttpRequest 对象简称 XHR,通过其发送的请求即 AJAX 请求)请求,服务端就能源源不断地往客户端输入数据。

优点 :消息即时到达,不需要发送无用的请求。

缺点 :和长轮询一样,服务器维护一个长连接会增加开销,且需要处理高并发问题。

Flash Socket

在页面嵌入一个使用了 Socket 类的 Flash 程序,JavaScript 通过调用此程序提供的 Socket 连接与服务器端的 Socket 接口进行通信,JavaScript 在收到服务端传送的信息后控制页面的显示。

优点 :与上述方式的伪随机不同,这种方式能够实现真正的即时通信。

缺点 :客户端必须安装 Flash 插件;该方式采用的并非 Http 协议,无法自动穿越防火墙。

真正的全双工 -- WebSocket

websocket是什么?

WebSocket 是 HTML5 开始提供的一种浏览器与服务器进行全双工通讯的网络技术,用以取代轮询与长连接,使客户端浏览器具备像 C/S 框架下桌面系统的即使通讯能力。

如何建立websocket连接?

1 . 首先由客户端发送握手请求,告诉服务器将协议升级为 Websocket

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

这一段用来告诉服务器自己发起的是 Websocket 协议

Upgrade: websocket
Connection: Upgrade

这一段用来对服务器进行验证,它由浏览器自主随机生成

Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==

这一段用来告诉服务器自己要的具体是什么服务。其中,Sec-WebSocket-Protocol 是一个用户定义的字符串,用来区分同 URL 下,不同的服务所需要的协议

Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

2 . 然后服务器会返回一个这样的东西,表示已经收到请求,成功切换成 websocket 啦

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

这一段用来告诉客户端协议已经切换成功了

Upgrade: websocket
Connection: Upgrade

这一段是经过服务器确认,并且加密后的 Sec-WebSocket-Key,用来对验证做出回应

Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=

这一段表示最终使用的协议

Sec-WebSocket-Protocol: chat

websocket的优势是?

对于轮询与长轮询来说,客户端都只能不断地建立 Http 连接,然后被动等待服务器的回应。这种被动性使得服务器端无法主动联系客户端,即无法实现消息的主动推送。

另一方面,不断发起请求的轮询要求服务器有很快的处理速度与资源,而保持连接不放的长轮询则需要服务器拥有足够高的并发能力,来对多个客户端进行同时接待。当消息发生并不很频繁时,这两种方式都将造成巨大的资源浪费。

由此,websocket 出现了。再让我们看一遍这个图!

相比于传统 Http 每次请求-应答需要每次重新建立连接的模式,WebSocket 是类似 Socket 的 TCP 长连接的通讯模式。一旦 WebSocket 连接建立之后,后续数据都以帧序列的形式传输。在客户端断开 WebSocket 连接或 Service 端中断连接前,不需要客户端和服务器重新发起连接请求。在海量并发及客户端与服务器交互负载流量较大的情况下,极大地节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接收消息是在同一个持久连接上发起的,实时性效果明显

而与同样能够实现实时推送的 Http 长连接相比,WebSocket 主要拥有以下优势 :

  • WebSocket 是真正的全双工方式,建立连接后客户端与服务器端是完全平等的,可以相互主动请求;而 Http 长连接基于 Http,是传统的客户端对服务器发起请求的模式。
  • 在 Http 长连接中,每次数据交换除了真正的数据部分外,服务器和客户端还需要交换大量的 Http Header,信息交换效率很低;而 WebSocket 协议一旦通过第一个 request 与服务器建立了 TCP 连接,之后的数据交换均不需要再次发送 Http header,从而提高了信息交换效率

虽然如此,WebSocket 依然存在一点局限性。除了少数浏览器可能不支持该种协议外,基于多线程或多进程的服务器同样无法适用于 WebSocket,因为它旨在打开连接,尽可能快地处理请求,然后关闭连接。任何实际的 WebSocket 服务器端都需要一个异步的实现。