• Kurento实战之四:应用开发指南


    欢迎访问我的GitHub

    https://github.com/zq2599/blog_demos

    内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;

    本篇概览

    • 本文是《Kurento实战》的第四篇,前面的文章中,咱们先部署KMS再启动官方demo,还把Kurento的重要概念都分类学习过,接下来要开始应用开发了;
    • 本文的主要内容是分析官方的kurento-hello-world项目,了解Kurento应用开发的基本流程和知识点,本文使用的代码是官方发布的6.15.0版本,地址:https://github.com/Kurento/kurento-tutorial-java/archive/6.15.0.zip
    • 阅读代码时,如果能从整体上将划分清楚功能模块,再有针对性的逐个攻破细节,将会更高效的学习和理解源码,接下来咱们就按照Kurento官方的标准套路去拆分并逐个攻破;

    如何划分功能模块

    按照不同的职责划分,整个代码被拆分为三部分:

    1. WebSocket相关:WebSocket相关的通用处理,例如连接建立、关闭、异常的回调,业务逻辑的分发等;
    2. WebRTC信令相关:ICE、SDP相关的处理;
    3. 业务逻辑:如果说1和2代表的是WebRTC的通用处理,那么剩下的就是如何使用Kurento来实现业务需求了,这部分的主要内容是业务应用使用Kurento官方client和KMS交互,控制KMS为端侧提供服务,交互方式如下图:
      在这里插入图片描述
    • 按照上述方式将代码做好拆分,划定边界,不论是阅读官方demo还是自己开发应用,都能条理清晰的应对,接下来一起学习官方的hello-world源码,看看一个完整的Kurento应用是如何开发出来的

    WebSocket相关

    最简单的逻辑应该是通用的WebSocket处理了,咱们先看这部分,复杂的稍后再说,Handler类中和WebSockert相关的逻辑如下:

    1. 继承自TextWebSocketHandler(只处理text类型的数据,对于二进制数据直接关闭会话);
    2. 重写afterConnectionEstablished:WebSocket连接建立的回调,只打了一行日志;
    3. 重写handleTransportError:WebSocket发生异常时候的回调,仅关闭WebSocketSession;
    4. 重写afterConnectionClosed:不论WebSocket是正常关闭还是发生异常,此方法都会执行,逻辑也很简单,就是调用stop方法,这个方法是用来释放KMS资源的,有好几处都会调用,我们留到稍后和其他处理KMS的地方一起讲;
    5. 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
    1. 并不是所有的应用都需要重写上诉全部代码,还是以实际需求出发决定是否要重写,以kurento-one2one-call项目为例,只重写了handleTextMessage和afterConnectionClosed,其他的使用父类的即可,如下图:

    在这里插入图片描述
    7. 还有一个发送消息到浏览器侧的sendMessage方法,以及发送错误信息的sendError方法;

    信令相关

    • kurento-hello-world应用的功能是和KMS实现实时音视频通信,因此WebRTC标准的信令处理是必不可少的,可惜Kurento官方并没有对信令处理做太多封装(也可能是信令和不同的业务处理逻辑都不一样,导致不好抽象),结果就是一堆信令处理的代码散落在业务代码中;
    • 就算业务和信令的处理代码同时出现在Handler类中,只要熟悉WebRTC的信令处理流程,也很容易读懂代码,下图结合了WebRTC标准的信令处理流程,对前端和服务端的代码串联在一起就行分析,左边是浏览器上执行的js代码,右边是服务端,这些代码都用红色箭头标识了处于WebRTC信令处理流程的具体位置,至此,整个流程都清晰的展现出来:

    在这里插入图片描述

    • 如果您在电脑或手机上看上图觉得模糊,请下载原始文件,用draw.io打开,文件所在目录是:https://github.com/zq2599/blog_demos/tree/master/files ,文件名为helloworld-flow.drawio
    • 上图列出了信令相关的所有代码,等到看完这些,剩下的就是业务代码了,也就是图中紫色部分的handleProcessSdpOffer方法;

    业务相关

    • kurento-hello-world应用是把本地摄像头和麦克风数据传到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();
          }
        }
      }
    

    小结

    以上就是整个kurento-hello-world的源码分析,整个工程的代码在拆分后再分析时,变得异常清晰和简单:

    1. WebSocket和常规的java开发无异,向标准靠拢即可;
    2. WebRTC相关代码占了较大比重,但是严格遵循了标准的信令流程,只要熟悉WebRTC就很容易阅读和理解;
    3. 业务逻辑其实是和业务需求相关联的,这里需要熟悉KMS提供的能力,才能充分发挥KMS的实例,而pipeline编排和各个element的使用,也会是咱们后面文章的重点,用好这些element,打磨出更强大灵活的服务;

    你不孤单,欣宸原创一路相伴

    1. Java系列
    2. Spring系列
    3. Docker系列
    4. kubernetes系列
    5. 数据库+中间件系列
    6. DevOps系列

    欢迎关注公众号:程序员欣宸

    微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界...
    https://github.com/zq2599/blog_demos

  • 相关阅读:
    python爬虫实战(八)--------知乎
    python爬虫实战(七)--------伯乐在线文章(模版)
    python分布式爬虫打造搜索引擎--------scrapy实现
    VS2010与SVN
    ASP.net 自定义控件GridView
    Asp.net Ajax提供PageMethods调用
    JSON串行化
    JOSN反串行化
    WebRequestManager对象的使用
    WebRequest调用
  • 原文地址:https://www.cnblogs.com/bolingcavalry/p/15174358.html
Copyright © 2020-2023  润新知