前言在疫情期间 , 上班族开启了远程办公 , 体验了各种远程办公软件 。老师做起了主播 , 学生们感受到了被钉钉支配的恐惧 , 歌手们开启了在线演唱会 , 许多综艺节目也变成了在线直播 。在这全民互动直播的时期 , 我们来聊聊互动直播中的即时通讯技术在前端中的使用 。
即时通讯技术即时通讯(Instant Messaging , 简称IM)是一个实时通信系统 , 允许两人或多人使用网络实时的传递文字消息、文件、语音与视频交流 。如何来实现呢 , 通常我们会使用服务器推送技术来实现 。常见的有以下几种实现方式 。
轮询(polling)这是一种我们几乎都用到过的的技术实现方案 。客户端和服务器之间会一直进行连接 , 每隔一段时间就询问一次 。前端通常采取setInterval或者setTimeout去不断的请求服务器数据 。
缺点:轮询时间通常是死的 , 太长就不是很实时 , 太短增加服务器端的负担 。不断的去请求没有意义的更新的数据也是一种浪费服务器资源的做法 。
长轮询(long-polling)客户端发送一个请求到服务端 , 如果服务端没有新的数据 , 就保持住这个连接直到有数据 。一旦服务端有了数据(消息)给客户端 , 它就使用这个连接发送数据给客户端 。接着连接关闭 。
缺点:占较多的内存资源与请求数 。
iframe流iframe流就是在浏览器中动态载入一个iframe, 让它的地址指向请求的服务器的指定地址(就是向服务器发送了一个http请求) , 然后在浏览器端创建一个处理数据的函数 , 在服务端通过iframe与浏览器的长连接定时输出数据给客户端 , iframe页面接收到这个数据就会将它解析成代码并传数据给父页面从而达到即时通讯的目的 。
缺点:兼容性与用户体验不好 。服务器维护一个长连接会增加开销 。一些浏览器的的地址栏图标会一直转菊花 。
Server-sent Events(sse)sse与长轮询机制类似 , 区别是每个连接不只发送一个消息 。客户端发送一个请求 , 服务端保持这个连接直到有新消息发送回客户端 , 仍然保持着连接 , 这样连接就可以消息的再次发送 , 由服务器单向发送给客户端 。
缺点:兼容性不好(IE , Edge不支持);服务器只能单向推送数据到客户端 。
WebSockethtml5 WebSocket规范定义了一种API , 使Web页面能够使用WebSocket协议与远程主机进行双向通信 。与轮询和长轮询相比 , 巨大减少了不必要的网络流量和等待时间 。
WebSocket属于应用层协议 。它基于TCP传输协议 , 并复用HTTP的握手通道 。但不是基于HTTP协议的 , 只是在建立连接之前要借助一下HTTP , 然后在第一次握手是升级协议为ws或者wss 。
文章插图
缺点:开发成本高 , 需要额外做重连保活 。
在互动直播场景下 , 由于本身的实时性要求高 , 服务端与客户端需要频繁双向通信 , 因此与它十分契合 。
搭建自己的IM系统上面简单的概述了下即时通讯的实现技术 , 接下来我们就聊聊如何实现自己的IM系统 。
从零开始搭建IM系统还是一件比较复杂与繁琐的事情 。自己搭建推荐基于 socket.io 来实现 。socket.io对即时通讯的封装已经很不错了 , 是一个比较成熟的库 , 对不同浏览器做了兼容 , 提供了各端的方案包括服务端 , 我们不用关心底层是用那种技术实现进行数据的通信 , 当然在现代浏览器种基本上是基于WebSocket来实现的 。市面上也有不少IM云服务平台 , 比如 云信 , 借助第三方的服务也可以快速集成 。下面就介绍下前端怎么基于socket.io集成开发 。
基础的搭建服务端集成socket.io(有JAVA版本的) , 服务端即成可以参考下 这里 , 客户端使用socket.io-client集成 。
参考socket.io官方api , 订阅生命周期与事件 , 通过订阅的方式或来实现基础功能 。在回调函数执行解析包装等逻辑 , 最终抛给上层业务使用 。
import io from 'socket.io-client';import EventEmitter from 'EventEmitter';class Ws extends EventEmitter {constructor (options) {super();//...this.init();}init () {const socket= this.link = io('wss://x.x.x.x');socket.on('connect', this.onConnect.bind(this));socket.on('message', this.onMessage.bind(this));socket.on('disconnect', this.onDisconnect.bind.(this);socket.on('someEvent', this.onSomeEvent.bind(this));}onMessage(msg) {const data = https://www.isolves.com/it/wl/js/2020-06-16/this.parseData(msg);// ...this.$emit('message', data);}}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 茶叶在旅行中的作用,白茶的保健功效介绍
- 刘涛|41岁的刘涛直播倒立,灵活度不输年轻人,娱乐圈明星健身有多厉害
- 敦煌月牙泉其中的水,辨证茶疗与疾病的关系
- 个人如何搭建Rtmp服务结合uni-app开发直播APP
- 人的身材在一天中的什么时候最高?
- 一款强大的本地文件内容搜索软件,可搜索文件中的文字
- 图解 Go 微服务中的熔断器和重试
- 血缘关系在中国文化中的作用
- Netty 中的内存分配浅析
- 茶艺中的弄茶手法,中国传统茶艺介绍