websocket通信

什么是 websocket

WebSocket 是一种标准协议,用于在客户端和服务端之间进行双向数据传输,它是一种基于 TCP 的独立实现。

以前客户端想知道服务端的处理进度,要不停地使用 Ajax 进行轮询,让浏览器隔个几秒就向服务器发一次请求,这对服务器压力较高。另外一种轮询就是采用 long poll 的方式,这就跟打电话差不多,没收到消息就一直不挂电话,也就是说,客户端发起连接后,如果没消息,就一直不返回 Response 给客户端,连接阶段一直是阻塞的。

而 WebSocket 解决了 HTTP 的这几个难题。首先,当服务器使用 WebSocket 后,服务端可以主动推送信息给客户端,解决了轮询造成的同步延迟问题。由于 WebSocket 只需要一次 HTTP 握手,服务端就能一直与客户端保持通讯,直到关闭连接,这样就解决了服务器需要反复解析 HTTP 协议,减少了资源的开销。

使用 WebSocket 的时候,前端使用是比较规范的,js 支持 ws 协议。也就是说,想要连接服务器的 websocket 需要使用类似于 ws://localhost:8000 的 uri。


基于 websocket 通信的库

基于 webSocket 通信的库主要有 socket.ioSockJS,它们对 websocket 进行了封装。它们建立在 WebSocket 协议之上,并提供额外的保证,例如如果连接不到 websocket 会回退到 HTTP 长轮询或自动重新连接。

Socket.io/SockJS 并不是一个基本的、独立的、能够回退到其它实时协议的 WebSocket 库,它实际上是一个依赖于其它实时传输协议的自定义实时传输协议的实现。该协议的协商部分使得支持标准 WebSocket 的客户端不能直接连接到 Socket.io/SockJS 服务器,并且支持 Socket.io/SockJS 的客户端也不能与非 Socket.io/SockJS 框架的 WebSocket 服务器通信。因而,Socket.io/SockJS 要求客户端与服务器端均须使用该框架


StompJS

STOMP(Simple Text-Orientated Messaging Protocol) 面向消息的简单文本协议,它提供了一个可互操作的连接格式,允许 STOMP 客户端与任意 STOMP 消息代理(Broker)进行交互。STOMP 协议由于设计简单,易于开发客户端,因此在多种语言和多种平台上得到广泛地应用。

与 HTTP 不同,WebSocket 是处在 TCP 上非常薄的一层,会将字节流转化为文本/二进制消息,因此,对于实际应用来说,WebSocket 的通信形式层级过低,因此可以在 WebSocket 之上使用 STOMP 协议,来为浏览器 和 server 间的通信增加适当的消息语义。


StompJS 与 WebSocket 的关系

HTTP 协议解决了web 浏览器发起请求以及 web 服务器响应请求的细节,假设HTTP 协议不存在,只能使用 TCP 套接字来编写 web 应用,你可能认为这是一件疯狂的事情。

直接使用 WebSocket(SockJS) 就很类似于使用 TCP 套接字来编写 web 应用,因为没有高层协议,就需要我们定义应用间发送消息的语义,还需要确保连接的两端都能遵循这些语义。

同 HTTP 在 TCP 套接字上添加请求-响应模型层一样,STOMP 在 WebSocket 之上提供了一个基于帧的线路格式层,用来定义消息语义。


总结

简而言之,WebSocket 是底层协议,Socket.io/SockJS 是 WebSocket 的备选方案,也是底层协议,而 STOMP 是基于 WebSocket(SockJS)的上层协议。