实时 web

如果你有跟进Web 技术的最新进展,你很可能就遇到过“实时Web”这个短语,而如果你在工程领域中有实时应用程序的实战经验,那么你可能有点怀疑这个术语到底意味着什么。

因此,让我们首先澄清,这里并不是指所谓的硬实时服务质量(QoS),硬实时服务质量是保证计算结果将在指定的时间间隔内被递交。

仅HTTP 的请求/响应模式设计就使得其很难被支持,从过去所设计的各种方案中都没有提供一种能够提供令人满意的解决方案的事实中便可见一斑。

虽然已经有了一些关于正式定义实时Web服务简而言之,虽然全面的实时Web可能并不会马上到来,但是它背后的想法却助长了对于几乎瞬时获得信息的期望。

我们将在本章中讨论的WebSocket语义的学术讨论,但是被普遍接受的定义似乎还未出现。

因此现在我们将采纳下面来自维基百科的非权威性描述:实时Web 利用技术和实践,使用户在信息的作者发布信息之后就能够立即收到信息,而不需要他们或者他们的软件周期性地检查信息源以获取更新。

WebSocket 协议便是在这个方向上迈出的坚实的一步。

WebSocket 简介

WebSocket 协议是完全重新设计的协议,旨在为Web 上的双向数据传输问题提供一个切实可行的解决方案,使得客户端和服务器之间可以在任意时刻传输消息。

因此,这也就要求它们异步地处理消息回执。(作为HTML5 客户端API 的一部分,大部分最新的浏览器都已经支持了WebSocket。)

Netty 对于 WebSocket 的支持包含了所有正在使用中的主要实现,因此在你的下一个应用程序中采用它将是简单直接的。

和往常使用Netty 一样,你可以完全使用该协议,而无需关心它内部的实现细节。

我们将通过创建一个基于 WebSocket 的实时聊天应用程序来演示这一点。

出现的背景

WebSocket是一种规范,是Html5规范的一部分,websocket解决什么问题呢?解决http协议的一些不足。

我们知道,http协议是一种无状态的,基于请求响应模式的协议。

网页聊天的程序(基于http协议的),浏览器客户端发送一个数据,服务器接收到这个浏览器数据之后,如何将数据推送给其他的浏览器客户端呢?

这就涉及到服务器的推技术。

早年为了实现这种服务器也可以像浏览器客户端推送消息的长连接需求,有很多方案,比如说最常用的采用一种轮询技术,就是客户端每隔一段时间,比如说2s或者3s向服务器发送请求,去请求服务器端是否还有信息没有响应给客户端,有就响应给客户端,当然没有响应就只是一种无用的请求。

长轮询缺点

这种长轮询技术的缺点有:

1)响应数据不是实时的,在下一次轮询请求的时候才会得到这个响应信息,只能说是准实时,而不是严格意义的实时。

2)大多数轮询请求的空轮询,造成大量的资源带宽的浪费,每次http请求携带了大量无用的头信息,而服务器端其实大多数都不关注这些头信息,而实际大多数情况下这些头信息都远远大于body信息,造成了资源的消耗。

  • 拓展

比较新的技术去做轮询的效果是Comet。

这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。

WebSocket是什么?

WebSocket一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范。

WebSocket API也被W3C定为标准。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。

在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

websocket的出现就是解决了客户端与服务端的这种长连接问题,这种长连接是真正意义上的长连接。

客户端与服务器一旦连接建立双方就是对等的实体,不再区分严格意义的客户端和服务端。

长连接只有在初次建立的时候,客户端才会向服务端发送一些请求,这些请求包括请求头和请求体,一旦建立好连接之后,客户端和服务器只会发送数据本身而不需要再去发送请求头信息,这样大量减少了网络带宽。

websocket协议本身是构建在http协议之上的升级协议,客户端首先向服务器端去建立连接,这个连接本身就是http协议只是在头信息中包含了一些websocket协议的相关信息,一旦http连接建立之后,服务器端读到这些websocket协议的相关信息就将此协议升级成websocket协议。

websocket协议也可以应用在非浏览器应用,只需要引入相关的websocket库就可以了。

HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

Websocket使用ws或wss的统一资源标志符,类似于HTTPS,其中wss表示在TLS之上的Websocket。如:

ws://example.com/wsapi
wss://secure.example.com/

优点

较少的控制开销:相对与http请求的头部信息,websocket信息明显减少。

更强的实时性:由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。

保持连接状态。于HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。

更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。

可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。

更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。

个人收获

  1. 每一种技术都有其适用的场景。

参考资料

《Netty in Action》 P185

  • other

Netty笔记之六:Netty对websocket的支持