当前位置:网站首页>网页端IM即时通讯开发:短轮询、长轮询、SSE、WebSocket
网页端IM即时通讯开发:短轮询、长轮询、SSE、WebSocket
2022-08-04 17:39:00 【wecloud1314】
对于IM/消息推送这类即时通讯系统而言,系统的关键就是“实时通信”能力。
从表面意思上来看,“实时通信”指的是:
1)客户端能随时主动发送数据给服务端;
2)当客户端关注的内容在发生改变时,服务器能够实时地通知客户端。
类比于传统的C/S请求模型,“实时通信”时客户端不需要主观地发送请求去获取自己关心的内容,而是由服务器端进行“推送”。

注意:上面的“推送”二字打了引号,实际上现有的几种技术实现方式中,并不是服务器端真正主动地推送,而是通过一定的手段营造了一种“实时通信”的假象。
就目前现有的几种技术而言,主要有以下几类:
1)客户端轮询:传统意义上的短轮询(Short Polling);
2)服务器端轮询:长轮询(Long Polling);
3)单向服务器推送:Server-Sent Events(SSE);
4)全双工通信:WebSocket。
理解短轮询(Short Polling)
短轮询的实现原理:
1)客户端向服务器端发送一个请求,服务器返回数据,然后客户端根据服务器端返回的数据进行处理;
2)客户端继续向服务器端发送请求,继续重复以上的步骤,如果不想给服务器端太大的压力,一般情况下会设置一个请求的时间间隔。
使用短轮询的优点:基础不需要额外的开发成本,请求数据,解析数据,作出响应,仅此而已,然后不断重复。
缺点也显而易见:
1)不断的发送和关闭请求,对服务器的压力会比较大,因为本身开启Http连接就是一件比较耗资源的事情;
2)轮询的时间间隔不好控制。如果要求的实时性比较高,显然使用短轮询会有明显的短板,如果设置interval的间隔过长,会导致消息延迟,而如果太短,会对服务器产生压力。
长轮询的基本原理:
1)客户端发送一个请求,服务器会hold住这个请求;
2)直到监听的内容有改变,才会返回数据,断开连接(或者在一定的时间内,请求还得不到返回,就会因为超时自动断开连接);
3)客户端继续发送请求,重复以上步骤。
长轮询是基于短轮询上的改进版本:主要是减少了客户端发起Http连接的开销,改成了在服务器端主动地去判断所关心的内容是否变化。
所以其实轮询的本质并没有多大变化,变化的点在于:
1)对于内容变化的轮询由客户端改成了服务器端(客户端会在连接中断之后,会再次发送请求,对比短轮询来说,大大减少了发起连接的次数);
2)客户端只会在数据改变时去作相应的改变,对比短轮询来说,并不是全盘接收。
下面是一个原生不用库的实现(这里只是介绍原理),整体的思路是:如果服务器端支持hold住请求的话,那么在一定的时间内会自轮询,然后期间通过比较key值,判断是否返回新数据。即时通讯聊天软件app开发可以加蔚可云的v:weikeyun24咨询

以下是具体思路:
1)客户端第一次会带一个空的key值,这次会立即返回,获取新内容,服务器端将计算出的contentKey返回给客户端;
2)然后客户端发送第二次请求,带上第一次返回的contentKey作为key值,然后进行下一轮的比较;
3)如果两次的key值相同,就会hold请求,进行内部轮询,如果期间有新内容或者客户端timeout,就会断开连接;
4)重复以上步骤。
基于iframe的长轮询模式
这是长轮询技术的另一个种实现方案。
该方案的具体的原理为:
1)在页面中嵌入一个iframe,地址指向轮询的服务器地址,然后在父页面中放置一个执行函数,比如execute(data);
2)当服务器有内容改变时,会向iframe发送一个脚本<script>parent.execute(JSON.stringify(data))</script>;
3)通过发送的脚本,主动执行父页面中的方法,达到推送的效果。
从纯技术的角度讲:上两节介绍的短轮询和长轮询技术,服务器端是无法主动给客户端推送消息的,都是客户端主动去请求服务器端获取最新的数据。
本节要介绍的SSE是一种可以主动从服务端推送消息的技术。
SSE的本质其实就是一个HTTP的长连接,只不过它给客户端发送的不是一次性的数据包,而是一个stream流,格式为text/event-stream。所以客户端不会关闭连接,会一直等着服务器发过来的新的数据流,视频播放就是这样的例子。
简单来说,SSE就是:
1)SSE 使用 HTTP 协议,现有的服务器软件都支持。WebSocket 是一个独立协议。
2)SSE 属于轻量级,使用简单;WebSocket 协议相对复杂。
3)SSE 默认支持断线重连,WebSocket 需要自己实现。
4)SSE 一般只用来传送文本,二进制数据需要编码后传送,WebSocket 默认支持传送二进制数据。
5)SSE 支持自定义发送的消息类型。
WebSocket诞生于2008年,在2011年成为国际标准,现在所有的浏览器都已支持。它是一种全新的应用层协议,是专门为web客户端和服务端设计的真正的全双工通信协议,可以类比HTTP协议来了解websocket协议。
它们的不同点:
1)HTTP的协议标识符是http,WebSocket的是ws;
2)HTTP请求只能由客户端发起,服务器无法主动向客户端推送消息,而WebSocket可以;
3)HTTP请求有同源限制,不同源之间通信需要跨域,而WebSocket没有同源限制。
它们的相同点:
1)都是应用层的通信协议;
2)默认端口一样,都是80或443;
3)都可以用于浏览器和服务器间的通信;
4)都基于TCP协议。
WebSocket技术特征总结下就是:
1)可双向通信,设计的目的主要是为了减少传统轮询时http连接数量的开销;
2)建立在TCP协议之上,握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器;
3)与HTTP兼容性良好,同样可以使用80和443端口;
4)没有同源限制,客户端可以与任意服务器通信;
5)可以发送文本,也可以发送二进制数据;
6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL.
边栏推荐
- NLP未来,路在何方?从学术前沿和业界热点谈起
- 【 Gazebo introductory tutorial] speak the second model library into robot modeling and visualization (editor) model
- 【LeetCode每日一题】——540.有序数组中的单一元素
- C# Sqlite database construction and use skills
- darknet source code reading notes-02-list.h and lish.c
- R语言ggplot2可视化:使用patchwork包的plot_layout函数将多个可视化图像组合起来,nrow参数指定行的个数、byrow参数指定按照列顺序排布图
- Learning to Explore - Setting the Foreground Color for Fonts
- LeetCode 每日一题——1403. 非递增顺序的最小子序列
- 嵌入式开发:使用堆栈保护提高代码完整性
- pyhon爬虫之爬取图片(亲测可用)
猜你喜欢

Thrift IDL示例文件

基于clipboard.js对复制组件的封装

小程序笔记1

Digital-intelligent supply chain management system for chemical manufacturing industry: build a smart supply system and empower enterprises to improve production efficiency

CAS:385437-57-0,DSPE-PEG-Biotin,生物活性分子磷脂-聚乙二醇-生物素

About the two architectures of ETL (ETL architecture and ELT architecture)

mysqlbinlog 超过500g自动删除,保留7个,求大深给个版本

Understand Chisel language. 32. Chisel advanced hardware generator (1) - parameterization in Chisel

如何让 JS 代码不可断点

化学制品制造业数智化供应链管理系统:打造智慧供应体系,赋能企业产效提升
随机推荐
关于ETL的两种架构(ETL架构和ELT架构)
LeetCode 899. Ordered Queues
西西成语接龙小助手
Boost library study notes (1) Installation and configuration
【LeetCode Daily Question】——374. Guess the size of the number
】 【 LeetCode daily one problem - 540. The order of a single element of the array
clickhouse online and offline table
数字化金融企业的产品体系长啥样?
(1), the sequential storage structure of linear table chain storage structure
How to make JS code unbreakable
树莓派通过API向企业微信推送图文
RecyclerView 缓存与复用机制
Boost库学习笔记(一)安装与配置
OpenInfra Days China 2022|SelectDB与你共享 Apache Doris 在互联网广告业务中的实践
动态数组底层是如何实现的
Cron表达式
dotnet remoting 抛出异常
公司自用的国产API管理神器
Flutter实战-请求封装(四)之gzip报文压缩
字节二面被问到mysql事务与锁问题,我蚌埠住了