如何实现android和服务器长连接

如何实现android和服务器长连接,第1张

前言:现在的大多数移动端应用都有实时得到消息的能力,简单来说,有发送消息的主动权和接受消息的被动权。例如:微信,QQ,天气预报等等,相信好处和用户体验相信大家都知道吧。

提出问题:这种功能必须涉及client(客户端)和server(服务器),所以到底client如何和server实现实时连接通讯?

分析问题:这种功能实际上就是数据同步,同时要考虑手机本身、电量、网络流量等等限制因素,所以通常在移动端上有一下两个解决方案:

1.一种是定时去server查询数据,通常是使用HTTP协议来访问web服务器,称Polling(轮询);

2.还有一种是移动端和服务器建立长连接,使用XMPP长连接,称Push(推送)。

从耗费的电量、流量和数据延迟性各方面来说,Push有明显的优势。但是使用Push的缺点是:

对于客户端:实现和维护相对成本高,在移动无线网络下维护长连接,相对有一些技术上的开发难度。

对于服务器:如何实现多核并发,cpu作业调度,数量庞大的长连接并发维护等技术,仍存在开发难点。转载,仅供参考。

服务器跟客户端走的什么协议。

tcp的话就是普通的socket通信就可以了,弄几个长连接连到服务器上就行。

http的话,有sse,跟websocket。这两个都需要服务器支持。现在比较流行的是websocket。

原理也还是长连接。发消息即可。

Http 长连接 和 短连接:

早期的 HTTP协议,如HTTP0.9之前也被称为是“无连接”的协议。不会与服务器保持长期的连接状态,所以也称为短连接,短连接每一次的请求都需要重新建立TCP连接,有10个请求就需要建立10次TCP连接,这个效率,可想而知是非常低的

到Http1.0就出现了长连接的通信方式,解决了短连接多次建立TCP连接的痛点,现在Http1.1基本都是默认开启Connection: keep-alive 长连接的, TCP连接只要建立一次,后续的请求都复用该通道,不用再重新建立TCP通道,效率大大提升

需要注意的是:不管是http短连接还是长连接,它们的请求和响应都有有序的,都是等上一次请求响应后,才接着下一个请求的,那能不能不等第一次请求回来,我就开始发第二次请求呢?这就引出http管道化了

http的管道化和非管道化:

在长连接的基础上,HTTP1.1进一步地支持在持久连接上使用管道化(pipelining)特性,这是相对于keep-alive连接的又一性能优化。在相应到达之前,可以将多条请求放入队列,当第一条请求发往服务器的时候,第二第三条请求也可以开始发送了,不用等到第一条请求响应回来,在高延时网络条件下,这样做可以降低网络的环回时间,提高性能。

非管道化与管道化的区别示意:

http队首阻塞:

简单理解就是需要排队,队首的事情没有处理完的时候,后面的人都要等着。

队头阻塞”与短连接和长连接无关,而是由 HTTP 基本的“请求 - 应答”机制所导致的。因为 HTTP 规定报文必须是“一发一收”,这就形成了一个先进先出的“串行”队列。

而http的队首阻塞,在管道化和非管道化下,表现是不同的

http1.0的队首阻塞 ( 非管道化下 ) :

可见,http1.0的队首组塞发生在客户端。

http1.1的队首阻塞 ( 管道化下 )

下图演示的是,第一个响应延迟后,后续响应跟着延迟

可见,应用管道化技术后,http1.1的队首阻塞发生在服务器端。

HTTP队头阻塞 的解决方法

并发TCP连接:

我们知道对于一个域名而言,是允许分配多个长连接的,那么可以理解成增加了任务队列,也就是说不会导致一个任务阻塞了该任务队列的其他任务,在RFC规范中规定客户端最多并发2个连接,不过实际情况就是要比这个还要多,Chrome中是6个,说明浏览器一个域名采用6个TCP连接,并发HTTP请求

域名分片

顾名思义,我们可以在一个域名下分出多个二级域名出来,而它们最终指向的还是同一个服务器,这样子的话就可以并发处理的任务队列更多,也更好的解决了队头阻塞的问题。

举个例子,比如baidu.com,可以分出很多二级域名,比如zhidao.baidu.com,xxx.baidu.com 这样子就可以有效解决队头阻塞问题。

利用HTTP2的多路复用解决:

对于HTTP1.1中管道化导致的请求/响应级别的队头阻塞,可以使用HTTP2的多路复用解决。

http2中将多个请求复用同一个tcp通道中,通过二进制分帧并且给每个帧打上流的 ID 去避免依次响应的问题,对方接收到帧之后根据 ID 拼接出流,这样就可以做到乱序响应从而避免请求时的队首阻塞问题,

当然,即使使用HTTP2,如果HTTP2底层使用的是TCP协议,仍可能出现TCP队头阻塞。

下图为http2多路复用,解决服务器响应时http队首阻塞演示

总结:

HTTP队头阻塞

对于每一个HTTP请求,会被放入一个任务队列中串行执行,一旦队首任务请求太慢时,就会阻塞后面的请求处理

有非管道化和管道化,两种阻塞方式:

非管道化:完全串行执行,请求->响应->请求->响应…,后一个请求必须在前一个响应之后发送,发生在客户端,http请求阻塞

管道化:请求可以并行发出,但是响应必须串行返回。后一个响应必须在前一个响应之后。原因是,没有序号标明顺序,只能串行接收,发生在服务端,http响应阻塞

管道化请求的致命弱点:

会造成队头阻塞,前一个响应未及时返回,后面的响应被阻塞

请求必须是幂等请求,也就是只有GET和HEAD请求才能管道化,不能修改资源。因为,意外中断时候,客户端需要把未收到响应的请求重发,非幂等请求,会造成资源破坏。

由于这个原因,目前大部分浏览器和Web服务器,都关闭了管道化,采用非管道化模式。

无论是非管道化还是管道化,都会造成队头阻塞(请求,响应阻塞)。

解决http队头阻塞的方法:

额外的:

http2中的多路复用和http1.1中的keep-alive有什么区别?

共同点: 都可以复用同一条TCP通道

区别:

https多路复用:并发请求,非阻塞的

详细描述:

keep-alive虽然可以复用同一条TCP通道,但必须等到服务端响应了前一次请求,才能发起第二次请求 ->阻塞。 按顺序发送请求,按顺序接收请求,这样接收端才不会乱掉。从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接,Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间

http2 的多路复用可以在一条TCP通道同时发送多个请求,不一定要按照顺序,非阻塞的,先响应先回来,响应式时也不用等上一个请求先响应,这些请求都有唯一标识,所以可以无序。


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/368372.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-12
下一篇2023-05-12

发表评论

登录后才能评论

评论列表(0条)

    保存