一概述
## 在项目中有这样一个需要,app为智能心电跑步类app,在跑步时需要在网页端显示用户的跑步信息,包括跑步时长、心率、心电图等,其中心电图是需要实时更新的。当用户开始跑步时在网页上显示这些信息,跑步结束时结束实时数据显示,将最终跑步结果显示在网页时,效果图如下:在网页上的显示效果如下:
先做个大致的分析,数据要做到实时显示,需要将app产生的数据通过网络发送到服务器,然后网页从服务器获取数据,在网页上显示,如下图所示:
整个流程比较简单,但是实现起来却比较难。这里选择实现技术很重要,先按照一般思路,app像服务器发送数据,通过http协议不断的向服务器发送数据,网页端不断的通过http向服务器请求数据,这时候你会发现app要实时发送数据通过http很耗资源甚至是几乎做不到,app每个几秒要向服务器发送运动数据,还有心电图实时显示通过http是做不到的,网页也是一样,这时遇到瓶颈,这种需要应该很常用,向app上很常用的消息推送、在线下线通知,他们的实现方式也肯定不是发生http请求,这时这个全新的问题摆在自己面前,该如何解决?查资料,然后会发现一个专门针对这种场景的技术,叫websocket。下面我们先来了解websocket,然后讨论通过websocket来实现需求的大致思路,然后在app端、网页端、服务器分析实现具体的技术细节。
二、websocket原理
WebSocket用于在Web浏览器和服务器之间进行任意的双向数据传输的一种技术。WebSocket协议基于TCP协议实现,包含初始的握手过程,以及后续的多次数据帧双向传输过程。其目的是在WebSocket应用和WebSocket服务器进行频繁双向通信时,可以使服务器避免打开多个HTTP连接进行工作来节约资源,提高了工作效率和资源利用率。
注:下面这部分websocket结束有参考与博客https://segmentfault.com/a/1190000007614996
1. 什么是keep-alive
keep-alive只是客户端的一种建议
我们打开百度首页,进一步查看header。
如图,我们看到请求header中有一行:
Connection:keep-alive
keep-alive是通知服务器,在这个HTTP Request/Responset结束后,不要立即断开TCP连接(注意是TCP连接,和HTTP没有关系),后面的HTTP Request仍然可以通过这个TCP连接继续传送。
但是!这只是个建议,服务器可能不支持,也可能忽略掉这个建议。也可能因为时间太久而直接断开TCP连接
通俗点解释就是:keep-alive只是通知服务器,您先别挂,一会儿可能还有活儿,至于它挂不挂还是看它心情。
所以,keep-alive只是客户端建议的一种复用TCP连接的方式,至于服务器支持不支持,就由不得客户端了。
keep-alive只是http协议中的一部分
keep-alive是http协议中的一部分,也即客户端可以主动的发起request到服务器,服务器只能被动的response给客户端。
我要想实现服务器主动的push消息给客户端,keep-alive是无能无力的。
2. 服务器的消息如何发给客户端
long long ago~ 服务器端要想主动的push消息给客户端(比如网页聊天室消息的即时收发),这是不可能滴。
但是,我可以使用ajax轮询、long poll 技术造一个服务端给客户端主动push消息的假象。
①:什么是ajax轮询?
ajax轮询的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。
场景再现:
客户端:啦啦啦,有没有新信息(Request) 服务端:没有(Response) 客户端:啦啦啦,有没有新信息(Request)
服务端:没有。。(Response) 客户端:啦啦啦,有没有新信息(Request) 服务端:你好烦啊,没有啊。。(Response)
客户端:啦啦啦,有没有新消息(Request) 服务端:好啦好啦,有啦给你。(Response)
客户端:啦啦啦,有没有新消息(Request) 服务端:。。。。。没。。。。没。。。没有(Response) —- loop
但是这样,有没有发现,大大增加了服务端的负载,并且速度还慢。
②:什么是long poll?
long poll和ajax差不多,原理都是采用轮询的方式。只不过long poll是采取的阻塞的方式去轮询。
也即客户端发起一个请求连接,这个连接会阻塞住,直到服务端有了消息,才会response给客户端。
场景再现:
客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) 服务端:额。。 等待到有消息的时候。。来
给你(Response) 客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) -loop
long pull 虽然降低了服务器的负载,但是需要服务器有很高的并发能力才可以。
而目前处理高并发的模型基本都是异步非阻塞的模型(比如nginx)。
③:总结
ajax轮询、long poll技术虽然都能实现服务端消息的实时通知,但是各有缺点,都不是根本的解决办法。
计算机界急需一种新的技术去处理这些需求~
3. websocket来啦
既然ajax轮询、long poll都不怎么样。我们发明一种新的协议吧!