随着互联网技术的发展,越来越多的企业和开发者开始寻求更高效、更稳定的通信解决方案。在这种背景下,WebSocket协议应运而生。WebSocket是一种在单个TCP连接上进行全双工通信的协议,它可以实现服务器和客户端之间的实时数据交换,提高了通信效率,降低了延迟。在金融、物联网等领域,数据的实时是非常重要的,传统的数据处理方式需要将数据打包成HTTP请求发送给服务器,然后等待服务器返回结果。这种方式效率低下,无法满足实时数据分析处理的需求。而WebSocket协议可以实现服务器和客户端之间的实时数据交换,使得数据服务请求响应更加高效。
WebSocket是一种在单个TCP连接上进行全双工通信的网络协议。经过一次TCP握手就可以直接创建持久性连接,进而可实现服务端和客户端双向数据传输。Websocket建立一次连接后可以保持长时间的通信会话,链路复用,减少握手次数,从而能够满足业务上需要实时性和即时更新的功能。
拿到一个问题,评估考虑是否使用WebSocket的技术方法很简单,总结起来,主要为以下两点:
(1)应用需要提供多个用户相互交流吗?
(2)应用需要动态实时展示服务器端经常变动的数据吗?
如果符合上面的场景,就可以尝试考虑使用WebSocket来进行解决。当前Websocket的主要场景有以下几个。
(1)基于熟悉的 TCP 协议之上,服务端可实现方式多样丰富
(2)能与 HTTP 协议良好的兼容。默认端口也是80和443,握手采用 HTTP 协议,通过协议提升交互实现连接建立
(3)数据报文格式轻量,性能好,通信交互高效。
(4)即支持文本,也可以发送二进制流。
(5)协议标识符:ws,同比与http,https, ws加密后的协议标识是wss。
(1)当前开发技术栈主要是开发restful接口服务,整个开发组都是都习惯于restful服务的接口开发,对Websocket 协议不熟,落地到应用,有很多未知风险及问题。
(2)对安全性考虑,新的协议模式,存在认知盲区。对于习惯的restful接口开发,我们比较熟悉的而且一直在使用的就是OPENAPI统一接入规范,OAUTH进行鉴权。采用WebSocket新的协议来开发接口实现业务需求,怎么保证安全性缺乏先验经验。
(3)在现代多媒体应用中,音视频处理是一个重要的组成部分,音视频处理领域相对独立且较为小众,并非每个开发者都会关注到这个知识点。开发人员在处理音视频这块知识储备不够,经验不足。领域独立小众的特点,并不是每个开发者都会去关注的知识点。
(4)弱网下如何保证消息及时发送成功送达,用户在网络通畅的情况下没问题,一到弱网服务传输就变慢,卡顿。很多场景,用户处于弱网环境下,极易导致消息堵塞,如何保证服务正常是一大难点。
搭建基础框架,首先,我们后台服务基于内部开发脚手架SDK, 采用基于java 原生+spring boot混合的方式实现了WebSocket服务基座,提供音视频接收处理服务。整个后台服务同时支持HTTP接口类的服务和Websocket 长连接。HTTP接口服务,主要服务于传统业务交易流程,Websocket连接主要服务需要进行长连接传输的业务场景。
WebSockets协议交互过程的每个步骤的详细说明如下:
粉丝福利, 免费领取C++音视频学习资料包+学习路线大纲、技术视频/代码,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,编解码,推拉流,srs),有需要的可以进企鹅裙927239107领取哦~
(1)Client向Server发送Handshake Request(握手请求):Client发送一个HTTP请求,其中包含特定的头部信息,以表明希望升级到WebSocket协议。
(2)Server返回Handshake Response(握手响应):Server接收到握手请求后,会返回一个HTTP响应,其中包含与WebSocket相关的头部信息,以表示握手成功,并升级到WebSocket协议。这个响应通常称为”握手确认”。
(3)Data Transfer(数据传输):一旦握手成功,双方之间建立了持久连接,可以进行全双工的数据传输。Client和Server可以通过该连接发送和接收数据。
(4)WebSocket Frames(WebSocket帧):在WebSocket连接上进行数据传输时,数据被分割成小块,每个小块被封装在WebSocket帧中。WebSocket帧有不同的类型和标志,用于指示消息的开始、结束、类型等信息。
(5)Connection(连接):持久连接保持打开状态,直到任一端关闭连接或发生错误。双方可以随时发送和接收数据,实现实时的数据交换。
后台启动服务后,前端开始来进行建立连接,建立请求到达后台后,后台先进行校验合法性,合法性校验成功后,返回前端链接建立成功。此时前后端 WSS连接通道创建成功。然后前端就可以开始传送视频帧或者图片帧,这一请求俗称推流。推流可以有不同的工具实现,例如ffmpeg,OBS推流,或者前端按照频率截取摄像机图片帧,后端接收前端推的流后进行业务处理,例如保存,转码,合成,录制等服务。交易完成后,前后端开始关闭长连接。在传输视频图片帧的时候还可以进行消息通信,完成我们熟悉的http文本消息发送。
针对安全性,接口安全设计,鉴权方面,参考了现有的OPENAPI,OAUTH鉴权机制,同时针对Websocket连接的特点,增加了其他安全性校验,系统稳健性方面,系统支持当个渠道及总体wss连接数限流,避免单机连接数耗尽。同时我们也加强了对单机WSS总连接数的监控,具体实现及实施过程,想了解可以内部联系沟通讨论。
音视频处理模块,这块我们深感知识缺乏,好在我们保持一种遇到问题解决问题的心态,一步一步摸索,走出了一条在我们熟悉的java 语言下利用 ffmpeg+javacv 方式来处理音视频的道路。例如,我们可以用ffmpeg来进行视频中的音频提取,使用javacv来进行图片到视频的转码录制服务。当前已经调研并实现了绝大数音视频相关的编辑处理服务,并提供标准化接入接口,方便接入及使用。此外在分辨率提升方面也积累了相关经验。
在系统架构的设计上,我们采取了一种策略性的拆分方法,将系统的各个功能模块进行了细致的拆分和分类。特别是对于那些计算密集,IO密集型的模块,我们将其独立出来,形成了一个独立的子系统,专门负责处理图片、视频帧以及音频等相关的计算任务。这个子系统就是我们的”媒体服务”模块。通过这样的拆分,我们成功地将媒体服务模块与其他的业务交易系统分离开来,这样不仅可以避免两个系统之间的相互干扰,还可以更有效地进行系统的维护和升级。这种拆分方法为系统的稳定运行提供了有力的保障。
在当今高度数字化的世界,确保信息在弱网环境下的及时发送和成功送达已经成为了一个重要的挑战。许多用户在日常生活中的许多场景中都可能遇到网络不稳定的情况,如在家中的无线网络覆盖范围边缘、地铁隧道中或山区等。这些问题可能导致消息堵塞,影响用户体验。为了解决这个问题,我们可以采取一系列的策略和技术手段。在报文传输优化方面,最开始我们采用的是request +reponse 的方式,后来在使用过程中,我们发现如果每一帧都回复响应,会导致客户端消息拥塞。当整个链路同时在进行音视频帧传输,文本消息发送过程中,表现更为明显。针对此问题,我们进行了两个方面的优化,首先减少每次交互的报文大小及字段,对端缓存相关业务参数字段,只进行最少次数的传输,只传输必须要的字段。其次我们减少了确认帧报文的发送,从每帧都回复确认帧,改为后台服务每隔一定时间才返回对应帧响应(设计并实现一套合并确认的算法机制),减轻了整个通道消息量,减少前端因对响应报文帧的处理而导致系统卡顿。以上两点优化,一定程度上优化了用户在弱网下的服务体验。
在网络连接的管理策略中,我们设计定义了一套探活机制,该机制能够实时监测前后端服务的状态。一旦发现连接在一定时间内没有响应,我们会立即对其进行剔除,关闭连接,以防止连接数的过度积累,从而确保系统的稳定运行。此外,我们还对系统单机连接总数做了专门监控。持久连接都会在创建后及时进行关闭。连接的创建关闭机制以及监控机制,为系统的高效运行奠定了坚实的基础。
(1)积累技术,沉淀技术,多做分享总结
一回生二回熟,越深入了解就越熟悉,就会越得心应手。产出相关文档,相互学习借鉴,减少未知知识壁垒障碍。在调研提升Websocket服务tps时,我们进行对比不同Web容器(tomcat,jetty,netty)性能的分析,得到了不同容器适合的场景;
在websocket下如何保证安全性,我们进行深入分析调研,这些都为未来其他类似业务的开展提供数据及经验以参考,Websocket 服务搭建及应用,也体现了我们脚手架SDK 的灵活性,能够在不同场景切换自如。
(2)稳定为首
如果涉及已有服务改造,为了保证稳定,切换时应该要考虑服务异常降级,考虑支持多协议间降级切换。确保Websocket服务异常的时候能切换到备份服务,如http服务或使用其他服务来承载该服务功能。
(3)敢做敢想慎行
做的时候,就担心图片合成视频可能会是性能瓶颈,就感觉到实施起来比较困难。面对未知时,唯一做的,大胆尝试,小心求证。最后经过多次优化,图片合成视频耗时降低到ms级别,相比业务总体总耗时,这点时间已经不是主要问题,而且我们的服务做到图片视频分辨率可控调整,按需提升。
随着当前业务请求Websocket模式调用量上涨,结合当前业务开展遇到的问题,以及客户提出的述求,当前和未来规划如下。