欢送拜访我的GitHub
https://github.com/zq2599/blog_demos
内容:所有原创文章分类汇总及配套源码,波及Java、Docker、Kubernetes、DevOPS等;
本篇概览
- 本文是《Kurento实战》的第四篇,后面的文章中,咱们先部署KMS再启动官网demo,还把Kurento的重要概念都分类学习过,接下来要开始利用开发了;
- 本文的次要内容是剖析官网的<font color="blue">kurento-hello-world</font>我的项目,理解Kurento利用开发的根本流程和知识点,本文应用的代码是官网公布的6.15.0版本,地址:https://github.com/Kurento/ku...
- 浏览代码时,如果能从整体上将划分分明功能模块,再有针对性的一一攻破细节,将会更高效的学习和了解源码,接下来咱们就依照Kurento官网的规范套路去拆分并一一攻破;
如何划分功能模块
依照不同的职责划分,整个代码被拆分为三局部:
- WebSocket相干:WebSocket相干的通用解决,例如连贯建设、敞开、异样的回调,业务逻辑的散发等;
- WebRTC信令相干:ICE、SDP相干的解决;
- 业务逻辑:如果说1和2代表的是WebRTC的通用解决,那么剩下的就是如何应用Kurento来实现业务需要了,这部分的次要内容是业务利用应用Kurento官网client和KMS交互,管制KMS为端侧提供服务,交互方式如下图:
- 依照上述形式将代码做好拆分,划定边界,不论是浏览官网demo还是本人开发利用,都能条理清晰的应答,接下来一起学习官网的hello-world源码,看看一个残缺的Kurento利用是如何开发进去的
WebSocket相干
最简略的逻辑应该是通用的WebSocket解决了,咱们先看这部分,简单的稍后再说,Handler类中和WebSockert相干的逻辑如下:
- 继承自TextWebSocketHandler(只解决text类型的数据,对于二进制数据间接敞开会话);
- 重写afterConnectionEstablished:WebSocket连贯建设的回调,只打了一行日志;
- 重写handleTransportError:WebSocket产生异样时候的回调,仅敞开WebSocketSession;
- 重写afterConnectionClosed:不管WebSocket是失常敞开还是产生异样,此办法都会执行,逻辑也很简略,就是调用stop办法,这个办法是用来开释KMS资源的,有好几处都会调用,咱们留到稍后和其余解决KMS的中央一起讲;
- WebSockert局部最重要的代码是handleTextMessage办法,外面是收到前端数据时的解决逻辑:先把数据转为JsonObject对象,此对象的messageId字段有四种值,每一种id及其对应的解决办法如下表格所示:
messageId | 解决办法 | 阐明 |
---|---|---|
PROCESS_SDP_OFFER | handleProcessSdpOffer | 收到前端SDPOffer数据后的解决逻辑 |
ADD_ICE_CANDIDATE | handleAddIceCandidate | 收到前端ICE数据后的解决逻辑 |
STOP | handleStop | HashMap删除用户数据,再近程调用MediaPipeline.release |
ERROR | handleError | HashMap删除用户数据,再近程调用MediaPipeline.release |
- 并不是所有的利用都须要重写上诉全副代码,还是以理论需要登程决定是否要重写,以<font color="blue">kurento-one2one-call</font>我的项目为例,只重写了handleTextMessage和afterConnectionClosed,其余的应用父类的即可,如下图:
- 还有一个发送音讯到浏览器侧的sendMessage办法,以及发送错误信息的sendError办法;
信令相干
- <font color="blue">kurento-hello-world</font>利用的性能是和KMS实现实时音视频通信,因而WebRTC规范的信令解决是必不可少的,惋惜Kurento官网并没有对信令解决做太多封装(也可能是信令和不同的业务解决逻辑都不一样,导致不好形象),后果就是一堆信令解决的代码散落在业务代码中;
- 就算业务和信令的解决代码同时呈现在Handler类中,只有相熟WebRTC的信令解决流程,也很容易读懂代码,下图联合了WebRTC规范的信令解决流程,对前端和服务端的代码串联在一起就行剖析,右边是浏览器上执行的js代码,左边是服务端,这些代码都用红色箭头标识了处于WebRTC信令解决流程的具体位置,至此,整个流程都清晰的展示进去:
- 如果您在电脑或手机上看上图感觉含糊,请下载原始文件,用<font color="blue">draw.io</font>关上,文件所在目录是:https://github.com/zq2599/blo... ,文件名为<font color="red">helloworld-flow.drawio</font>
上图列出了信令相干的所有代码,等到看完这些,剩下的就是业务代码了,也就是图中紫色局部的<font color="blue">handleProcessSdpOffer</font>办法;
业务相干
- <font color="blue">kurento-hello-world</font>利用是把本地摄像头和麦克风数据传到KMS,再从KMS获得这些数据在页面展现,先看看官网是如何形容KMS pipeline的:
- 从上图可见pipeline逻辑非常简单:只有一个WebRtcEndpoint,把本人的Src和Sink接上就实现了,咱们来看看对应的代码,在办法handleProcessSdpOffer中:
// 创立pipeline final MediaPipeline pipeline = kurento.createMediaPipeline(); user.setMediaPipeline(pipeline); // 创立webRtcEndpoint final WebRtcEndpoint webRtcEp = new WebRtcEndpoint.Builder(pipeline).build(); user.setWebRtcEndpoint(webRtcEp); // 本人的sink连贯上本人的src webRtcEp.connect(webRtcEp); // ---- Endpoint configuration String sdpOffer = jsonMessage.get("sdpOffer").getAsString(); // 注册各类监听,例如媒体资源状态变动、ICE变动等 // 通过websocket回复SDP Offer initWebRtcEndpoint(session, webRtcEp, sdpOffer); log.info("[Handler::handleStart] New WebRtcEndpoint: {}", webRtcEp.getName()); // ---- Endpoint startup // 获得ICE信息 startWebRtcEndpoint(webRtcEp);
- 再来看看进行WebRtc的stop办法,其实就是向KMS发送了release指令:
private void stop(final WebSocketSession session) { // Remove the user session and release all resources final UserSession user = users.remove(session.getId()); if (user != null) { MediaPipeline mediaPipeline = user.getMediaPipeline(); if (mediaPipeline != null) { log.info("[Handler::stop] Release the Media Pipeline"); mediaPipeline.release(); } } }
小结
以上就是整个<font color="blue">kurento-hello-world</font>的源码剖析,整个工程的代码在拆分后再剖析时,变得异样清晰和简略:
- WebSocket和惯例的java开发无异,向规范聚拢即可;
- WebRTC相干代码占了较大比重,然而严格遵循了规范的信令流程,只有相熟WebRTC就很容易浏览和了解;
- 业务逻辑其实是和业务需要相关联的,这里须要相熟KMS提供的能力,能力充分发挥KMS的实例,而pipeline编排和各个element的应用,也会是咱们前面文章的重点,用好这些element,打磨出更弱小灵便的服务;
你不孤独,欣宸原创一路相伴
- Java系列
- Spring系列
- Docker系列
- kubernetes系列
- 数据库+中间件系列
- DevOps系列
欢送关注公众号:程序员欣宸
微信搜寻「程序员欣宸」,我是欣宸,期待与您一起畅游Java世界...
https://github.com/zq2599/blog_demos