OpenRTMFP/Cumulus Primer(21)经由服务器的发布/订阅流程的关键点

  • 作者:柳大·Poechant(钟超 Michael)
  • 博客:Blog.csdn.net/poechant
  • 邮箱:zhongchao.ustc@gmail.com
  • 日期:July 23th, 2012

整个流程概括如下:

Flash 客户端通过 NetConnection 与 Cumulus 建立连接,然后通过 NetStream 使用 RTMFP 发布 Audio/Video/Data(下面简称为 A/V/D) 给服务器,这个 Flash Player 就作为一个发布者(Publisher)。RTMFP 服务器接收到后给所有的订阅者(Subscribers)发送 Audio/Video/Data。

1 客户端发布(Publishing on client side)

通过 NetConnection 连接 RTMFP 服务器 Cumulus,可以参考《OpenRTMFP/Cumulus Primer(2)用Lua编写HelloWorld应用扩展CumulusServer》一文。关键的一个语句如下,其中 nc 是一个 NetConnection 对象(不是“脑残”的意思 - -|||):

nc.connect("rtmfp://localhost:1935");

在连接成功后通过 NetStream 发布 Audio/Video,如下所示,其中 ns1 是一个 NetStream 对象。

ns1.publish("poechant_media_flow", "live");

根据音视频不同的需求,播放相应内容。如果是发布 Data,则使用NetStream.send()来实现。这样就完成了客户端的 A/V/D 发布

2 服务器端(Server-side)

Cumulus 通过 RTMFPReceiving 这个 RTMFP 协议数据接收引擎完成一些连接建立的相关动作,以及接收数据包:

void RTMFPServer::receive(RTMFPReceiving& rtmfpReceiving);

该函数会在收到客户端发来请求时响应,如果是仍未建立连接的请求,则由此创建 Session(RTMFP 的核心概念之一),并取出其中的数据包。这其中有多个过程,我这里就不详述,以后会发布文章来解释。

继续我们的话题,在RTMFPServer::receive 函数中如果是建立连接阶段,则会调用 Handshake 类的 receive 来做接下来的处理,这个我就不去详细分析了,因为与本文主题无关。与本文有关的是,如果是已经创建了 Session 的,则会调用:

void ServerSession::packetHandler(PacketReader& packet);

这是一个相对复杂的函数,会从 packet 中取出很多有用的信息。此外,比较重要的是,在我们上述情况下,会调用 Flow 类的:

void Flow::fragmentSortedHandler(UInt64 stage,PacketReader& fragment,UInt8 flags);

该函数中会对 Audio/Video/Data 分别响应不同的处理机制:

switch(type) {case Message::AMF_WITH_HANDLER:case Message::AMF:messageHandler(name,amf);break;case Message::AUDIO:audioHandler(*pMessage);break;case Message::VIDEO:videoHandler(*pMessage);break;default:rawHandler(type,*pMessage);
}

接下来在 Publication 中完成对所有订阅了该发布者的 Flash Players 发送信息,核心的代码为:

for(it=_listeners.begin();it!=_listeners.end();++it) {it->second->pushAudioPacket(time,packet);packet.reset(pos);
}for(it=_listeners.begin();it!=_listeners.end();++it) {it->second->pushVideoPacket(time,packet);packet.reset(pos);
}for(it=_listeners.begin();it!=_listeners.end();++it) {it->second->pushDataPacket(name,packet);packet.reset(pos);
}

其中的 _listeners 就是该 Publication 中的所有订阅者。订阅者的添加/删除是通过:

Listener& addListener(Peer& peer,Poco::UInt32 id,FlowWriter& writer,bool unbuffered);void removeListener(Peer& peer,Poco::UInt32 id);

这两个函数来实现的。

要注意的是,在 Publication 中已经完成了向订阅者发布信息,之后虽然会响应到 Peer 及 RTMFPServer 的onAudioPacketonVideoPacketonDataPacket,但此时都与订阅者接收信息无关了。Cumulus 正是在RTMFPServer::onAudioPacketRTMFPServer::onVideoPacketRTMFPServer::onDataPacket中调用用户定制的服务(Lua 脚本实现),完成一些自定义的需求。我是在此通过直接的 C++ 功能扩展,来添加业务需求的,没有使用 Lua 脚本及 Cumulus 中的 Lua 脚本引擎,主要原因是为了提高效率。

3 客户端订阅(Subscribing on client side)

订阅很简单,在play的时候传入正确的发布者名称即可。

ns2.play("poechant_media_flow");

测试代码可以参考 Reference-1,其中的例子是关于NetStream::send(…)的,用于发送 Data,Audio 和 Video 的程序可以参考该例修改。

客户端订阅后,这些信息并不会直接从发布者那里通过 P2P 的方式接收。如果想使用发布者与接受者直接连接的方式,则需要在 NetStream 初始化的时候,传入NetStream.DIRECT_CONNECTIONS参数,默认的NetStream.CONNECT_TO_FMS是将数据上行到服务器再下行给所有订阅者(Subscribers)的。根据不同的应用场景,可以使用不同的方式。

4 Reference

  1. http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#send()

-

转载请注明来自柳大的CSDN博客:Blog.csdn.net/poechant

-

OpenRTMFP/Cumulus Primer(21)经由服务器的发布/订阅流程的关键点相关推荐

  1. OpenRTMFP/Cumulus Primer(20)Cumulus的一个线程启动 Bug

    OpenRTMFP/Cumulus Primer(20)Cumulus的一个线程启动 Bug 作者:柳大·Poechant(钟超) 邮箱:zhongchao.ustc#gmail.com(# -> ...

  2. zeromq不需要消息服务器,ZeroMQ发布订阅TCP丢弃消息订阅服务器失败

    我已经按照github页面上的说明在我的Manjaro Linux机器上从源代码构建了ZeroMQ.所有测试都通过了.在 基本上./autogen ./configure ./make ./make ...

  3. Redis中使用Java代码的方式实现发布订阅流程

    场景 Redis中的发布与订阅的概念与以命令行的方式实现发布订阅举例: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/105042 ...

  4. Ubuntu 12.04 64bit或者CentOS 6.3 64bit上搭建OpenRTMFP/Cumulus服务器

    Ubuntu 12.04 64bit或者CentOS 6.3 64bit上搭建OpenRTMFP/Cumulus服务器 2013-12-25 1.从官网下载源码包 cd ~/progrom_devel ...

  5. csol什么时间服务器维护,01月21日服务器例行维护公告发布时间:2020-01-20

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 01月21日服务器例行维护公告 发布时间:2020-01-20 亲爱的战友: 我们将于01月21日08:00~13:00对所有服务器进行例行维护,在此期间 ...

  6. Nginx 外的另一选择,轻量级开源 Web 服务器 Tengine 发布新版本

    2019独角兽企业重金招聘Python工程师标准>>> 新版发布 近日,轻量级开源 Web 服务器 Tengine 发布了2.3.0版本,新增如下特性: ngx_http_proxy ...

  7. Linux上部署web服务器并发布web项目

    近在学习如何在linux上搭建web服务器来发布web项目,由于本人是linux新手,所以中间入了不少坑,搞了好久才搞出点成果. 以下是具体的详细步骤以及我对此做的一些总结和个人的一些见解,希望对跟我 ...

  8. 联系随笔2---在tomcat服务器上发布servlet应用程序

    问题二:在tomcat服务器上发布servlet应用程序 1,new->Dynamic Web Project写工程名字->next->next在Generate web.xml文件 ...

  9. 游戏服务器架构-设计模式之观察者模式和发布订阅模式真的一样吗?

    前面我给大家分享了观察者模式和发布订阅模式,有人私信给我说这俩不是一样嘛,大体没什么区别,我猜测大多数认为这两者是一样的可以继续阅读这两篇文章,如果还不能解答你的问题,我相信这篇文章对比两者的关系会让 ...

最新文章

  1. MLPerf基准测试再发榜,浪潮AI服务器刷新18项纪录
  2. 金山员工被离职后拿到高薪工作:感谢公司辞退我,还给我赔偿金
  3. 使用克隆配置任务配置边缘传输服务器角色
  4. Heartbeats
  5. 各种花里胡哨的管理系统介绍
  6. SRAM(静态随机存储器)
  7. .NET 云原生架构师训练营(模块二 基础巩固 日志)--学习笔记
  8. mysql linux导入csv主键,MySQL导入csv文件内容到Table及数据库的自增主键设置
  9. SVN的trunk branch tag
  10. 设计干货素材|UI设计中的插画模板,便于应用的好素材!
  11. Oracle 数据库管理脚本 命名规范
  12. PostgreSQL 递归查询 (转)
  13. 多种嵌入式文件系统移植集合
  14. java遍历键值对_map集合中的键值对对象遍历
  15. A Frustratingly Easy Approach for Joint Entity and Relation Extraction(陈丹琦2020)
  16. dede 表单必填_dede自定义表单“必填项”设置方法
  17. 几何平均数和调和平均数是什么?有什么作用?详细资料讨论
  18. 微信大会有哪些看点?
  19. Python多线程爬虫,主播信息资料爬取采集
  20. 【Acwing提高】DP·背包

热门文章

  1. Unity Shader·屏幕抖音效果
  2. 使用nvm下载node和npm
  3. C++编程一级二级三级四级五级题库260题及参考答案第六版
  4. 使用Arduino开发ESP32(16):DeepSleep和RTC Memory的使用
  5. iphone模拟器截图方法
  6. 汇编 nasm 打字板
  7. Linux- 系统随你玩之--玩出花活的命令浏览器下
  8. python execl表格数据查询
  9. dsr-uu-0.2在linux2.6.32上编译问…
  10. 设计必备的矢量插画素材,这几个网站超齐全。