`

red5源代码分析

阅读更多

Red5如何响应rmpt的请求,中间涉及哪些关键类?

响应请求的流程如下:

1.Red5在启动时会调用RTMPMinaTransport的start()方法,该方法会开启rmtp的socket监听端口(默认是1935),然后使用mina(apache的io操作类库)的api将RTMPMinaIoHandler绑定到该端口。

2.RTMPMinaIoHandler 上定义了messageReceived、messageSent、sessionOpened和sessionClosed等方法,当有socket请求时,相应的方法会被调用,这时RTMPMinaIoHandler会使用当前的socket连接来创建一个RTMPMinaConnection(或者使用一个之前创建好的RTMPMinaConnection),并将其作为参数传递给定义于RTMPHandler类上的相应的 messageReceived、messageSent、connectionOpened和connectionClosed方法。

3.RTMPHandler 会调用Server类的lookupGlobal获得当前的GlobalScope,然后再利用GlobalScope找到当前socket请求应该使用的WebScope(这个WebScope就是我们在自己的项目的WEB-INF/red5-web.xml中定义的啦)。最后,RTMPHandler 会调用RTMPMinaConnection的connect方法连接到相应的WebScope。

4.至此,控制流进入了我们自己项目中了,通常来说,WebScope又会将请求转移给ApplicationAdapter,由它来最终响应请求,而我们的项目通过重载ApplicationAdapter的方法来实现自己的逻辑。

简单的流程图:

  1. RTMPMinaIoHandler
  2. |--[delegatemethodcallandpassRTMPMinaConnectionto]-->RTMPHandler
  3. |--[calllookupGlobalmethod]-->Server
  4. |--[useglobalScopetolookupwebScope]-->GlobalScope
  5. |--[callconnectmethodandpassWebScopeto]-->RTMPMinaConnection

Red5如何启动?在它的启动过程中如何初始化这些关键类?

这里探讨的是Red5 standalone的启动过程(也就是我们执行red5.bat),关于Red5如何在tomcat中启动,目前仍在研究中。

Red5启动过程如下:

1.编辑red5.bat,找到关键的一行:

  1. C:/ProgramFiles/Java/jre1.5.0_15/bin/java"
  2. -Djava.security.manager
  3. -Djava.security.policy=conf/red5.policy
  4. -cpred5.jar;conf;binorg.red5.server.Standalone

可以看到它是调用org.red5.server.Standalone作为程序启动的入口,这也是为什么使用eclipse在debug模式下启动 Standalone就可以调试Red5代码。需要注意的是,如果你要调试Red5,记得除了源代码(src)之外,把conf和webapps两个文件夹都拷入项目中,并把conf加入classpath。


2.观察Standalone的main方法,你会看到它使用spring的ContextSingletonBeanFactoryLocator来载入classpath下面的red5.xml,注意ContextSingletonBeanFactoryLocator还会在下面的步骤中被使用,由于它是singleton的,所以保证了我们自己的项目中定义的bean可以引用red5.xml中定义的bean,这个下面会有介绍。

  1. try{
  2. ContextSingletonBeanFactoryLocator.getInstance(red5Config).useBeanFactory("red5.common");
  3. }catch(Exceptione){
  4. //Dontraisewrappedexceptionsastheirstacktracesmayconfusepeople...
  5. raiseOriginalException(e);
  6. }

3. 查看red5.xml,这个文件首先定义了指向classpath:/red5-common.xml的名字为“red5.common”的 BeanFactory,注意它会是整个BeanFactory层次中的根节点,所以在red5-common.xml中定义的bean可以被其他地方所引用。

  1. <beanid="red5.common"
    class="org.springframework.context.support.FileSystemXmlApplicationContext">
  2. <constructor-arg><list><value>classpath:/red5-common.xml</value></list></constructor-arg>
  3. </bean>
  4. 这里我们主要留意red5-common.xml中定义的类型为org.red5.server.Server的“red5.server”,它会在接下来很多地方被用到。

    1. <beanid="red5.server"class="org.red5.server.Server"/>

    4.回到red5.xml,接着定义指向classpath:/red5-core.xml的名字为“red5.core”的BeanFactory,注意“red5.core”是以“red5.common”为parent context。

    1. <beanid="red5.core"class="org.springframework.context.support.FileSystemXmlApplicationContext">
    2. <constructor-arg><list><value>classpath:/red5-core.xml</value></list></constructor-arg>
    3. <constructor-arg><refbean="red5.common"/></constructor-arg>
    4. </bean>

    查看red5-core.xml,这个文件主要定义了之前说过的RTMPMinaTransport,RMTPMinaIoHandler和 RTMPHandler这些类的Bean。对于RTMPMinaTransport,注意init-method="start"这段代码,这说明 RTMPMinaTransport的start方法会在该Bean初始化时调用,正如上面提到的,该方法会做开启1935端口,绑定 RTMPMinaIoHandler到该端口等等的操作。对于RTMPHandler,注意它的server属性通过“red5.server”引用了定义在parent context(red5-common.xml)上面的Server,通过它RTMPHandler能够找到GlobalScope,进而找到 WebScope。

    1. <!--RTMPHandler-->
    2. <beanid="rtmpHandler"
    3. class="org.red5.server.net.rtmp.RTMPHandler">
    4. <propertyname="server"ref="red5.server"/>
    5. <propertyname="statusObjectService"ref="statusObjectService"/>
  5. </bean>
  6. <!--RTMPMinaIOHandler-->
  7. <beanid="rtmpMinaIoHandler"
  8. class="org.red5.server.net.rtmp.RTMPMinaIoHandler">
  9. <propertyname="handler"ref="rtmpHandler"/>
  10. <propertyname="codecFactory"ref="rtmpCodecFactory"/>
  11. <propertyname="rtmpConnManager"ref="rtmpMinaConnManager"/>
  12. </bean>
  13. <!--RTMPMinaTransport-->
  14. <beanid="rtmpTransport"class="org.red5.server.net.rtmp.RTMPMinaTransport"init-method="start"destroy-method="stop">
  15. <propertyname="ioHandler"ref="rtmpMinaIoHandler"/>
  16. <propertyname="address"value="${rtmp.host}"/>
  17. <propertyname="port"value="${rtmp.port}"/>
  18. <propertyname="receiveBufferSize"value="${rtmp.receive_buffer_size}"/>
  19. <propertyname="sendBufferSize"value="${rtmp.send_buffer_size}"/>
  20. <propertyname="eventThreadsCore"value="${rtmp.event_threads_core}"/>
  21. <propertyname="eventThreadsMax"value="${rtmp.event_threads_max}"/>
  22. <
    propertyname="eventThreadsQueue"value="${rtmp.event_threads_queue}"/>
  23. <propertyname="eventThreadsKeepalive"value="${rtmp.event_threads_keepalive}"/>
  24. <!--Thisistheintervalatwhichthesessionsarepolledforstats.Ifminamonitoringisnotenabled,pollingwillnotoccur.-->
  25. <propertyname="jmxPollInterval"value="1000"/>
  26. <propertyname="tcpNoDelay"value="${rtmp.tcp_nodelay}"/>
  27. </bean>
  28. 5.再次回到red5.xml,接下来定义类型为org.red5.server.ContextLoader的bean,并在初始化后调用它的init方法。

    1. <beanid="context.loader"class="org.red5.server.ContextLoader"init-method="init">
    2. <propertyname="parentContext"ref="red5.common"/>
    3. <propertyname="contextsConfig"value="red5.globals"/>
    4. </bean>

    查看该方法的源代码,可以看到它会读取在classPath下面的red5.globals文件,对于每一行初始化一个以“red5.common”为 parent context的BeanFactory,具体来说,现在red5.globals中只有一行 default.context=${red5.root}/webapps/red5-default.xml,那么会创建一个名字为 “default.context”的指向webapps/red5-default.xml的Bean Factory,它以“red5.common”为parent context。

    1. protectedvoidloadContext(Stringname,Stringconfig){
    2. log.debug("Loadcontext-name:"+name+"config:"+config);
    3. ApplicationContextcontext=newFileSystemXmlApplicationContext(
    4. newString[]{config},parentContext);
    5. contextMap.put(name,context);
    6. //addthecontexttotheparent,thiswillbered5.xml
    7. ConfigurableBeanFactoryfactory=((ConfigurableApplicationContext)applicationContext)
    8. .getBeanFactory();
    9. //Registercontextinparentbeanfactory
    10. factory.registerSingleton(name,context);
    11. }

    查看red5-default.xml,发现它主要是定义了GlobalScope的bean,然后把它注册到“red5.server”上。

    9. 最后查看webapps/oflaDemo/WEB-INF/red5-web.xml,它定义了类型为 org.red5.server.WebScope的bean,初始化了它的server(指向“red5.server”),parent(指向 “global.scope”)等属性,最后调用它的register方法初始化,查看该方法源代码,发现它会把自己注册到GlobalScope上面,至此所有的关键类的初始化完毕。

    8.查看webapps下的项目,这里以oflaDemo为例,查看WEB-INF下面的web.xml,发现有以下三个参数 contextConfigLocation,locatorFactorySelector和parentContextKey,同时还有一个 org.springframework.web.context.ContextLoaderListener。

    1. <beanid="global.scope"class="org.red5.server.GlobalScope"init-method="register">
    2. <propertyname="server"ref="red5.server"/>
    3. <propertyname="name"value="default"/>
    4. <propertyname="context"ref="global.context"/>
    5. <propertyname="handler"ref="global.handler"/>
    6. <propertyname="persistenceClass">
    7. <value>org.red5.server.persistence.FilePersistence</value>
    8. </property>
    9. </bean>

    6.继续看red5.xml,最后定义类型为org.red5.server.jetty.JettyLoader的bean,并且在初始化后调用它的init方法,查看该方法源代码,很明显它是初始化并且启动jetty这个web server。

    1. <beanid="web.scope"class="org.red5.server.WebScope"init-method="register">
    2. <propertyname="server"ref="red5.server"/>
    3. <propertyname="parent"ref="global.scope"/>
    4. <propertyname="context"ref="web.context"/>
    5. <propertyname="handler"ref="web.handler"/>
    6. <property
  29. name="contextPath"value="${webapp.contextPath}"/>

  30. <propertyname="virtualHosts"value="${webapp.virtualHosts}"/>
  31. </bean>
  32. Spring beanFactory 的层次图

    1. conf/red5-common.xml->webapps/red5-default.xml->webapps/oflaDemo/WEB-INF/red5-web.xml

    这就使得red5-web.xml可以使用red5-common.xml和red5-default.xml中定义的bean。

    1. conf/red5-common.xml
    2. |--conf/red5-core.xml
    3. |--webapps/red5-default.xml
    4. |--webapps/root/WEB-INF/red5-web.xml
    5. |--webapps/SOSample/WEB-INF/red5-web.xml
    6. |--webapps/oflaDemo/WEB-INF/red5-web.xml

    看清了Red5 Standalone的启动过程,感觉为了实现自定义项目集成到Red5的核心服务上,Red5 Standalone非常依赖于spring的多个Bean Factory之间的复杂层次关系,之所以Red5能建立这样一种层次关系,是因为它能够控制jetty这样一个嵌入式的web server。问题在于,一旦Red5需要作为一个web app运行在类似Tomcat这样的独立的web server上面,那么整个过程就很不一样了,所以后很多东西都要改,我想这也是为什么Red5 0.8 RC1为什么只有安装版但还没有war版的原因。

    1. <context-param>
    2. <param-name>contextConfigLocation</param-name>
    3. <param-value>/WEB-INF/red5-*.xml</param-value>
    4. </context-param>
    5. <context-param>
    6. <param-name>locatorFactorySelector</param-name>
    7. <param-value>red5.xml</param-value>
    8. </context-param>
    9. <context-param>
    10. <param-name>parentContextKey</param-name>
    11. <param-value>default.context</param-value>
    12. </context-param>
    13. <listener>
    14. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    15. </listener>

      查看这个listener的javadoc,其实这个listener会在web app(就是我们自己的项目)启动时,创建一个指向contextConfigLocation(其实就是WEB-INF/red5-web.xml)的 Bean Factory,同时为它设置parent context。这个parent context实际上是使用locatorFactorySelector找到ContextSingletonBeanFactoryLocator,进而使用parentContextKey找到定义在这个locator里面的Bean Fanctory,由于ContextSingletonBeanFactoryLocator是singleton的,所以这个 ContextSingletonBeanFactoryLocator对象跟我们在第2步中拿到的对象是一样的,而由于 parentContextKey被设置成“default.context”,这就意味着该parent context是第5步中定义的名为“default.context”的Bean Factory。基于以上的参数,我们得到这样一个Bean Factory的链条,由上至下分别是

      1. <beanid="jetty6.server"class="org.red5.server.jetty.JettyLoader"init-method="init"autowire="byType"depends-on="context.loader">
      2. <propertyname="webappFolder"value="${red5.root}/webapps"/>
      3. </bean>

      7. 到了这里似乎所有的初始化和启动都完毕了,但是问题就来了,这里仅仅定义了RTMPMinaIoHandler,RTMPHandler,Server和 GlobalScope,但是在我们之前提到过的Red5响应rmpt的请求的过程中,还需要有WebScope来最终处理 RTMPMinaConnection,这个WebScope又是怎么配置并且加进来的呢?

      最后,如果哪位成功在Tomcat上配置过Red5 0.7的war版本,还请告诉我一声,我试了0.6的war可以,不知道0.7为什么老不行。。。

分享到:
评论

相关推荐

    red5 流媒体 源代码

    Red5的源代码是用Java语言编写的,这使得它具有良好的跨平台性,可以在多种操作系统上运行,包括Windows、Linux和Mac OS。 Red5的核心功能包括: 1. **实时流传输(RTMP)**:RTMP是一种广泛使用的协议,用于将...

    red5 java源码

    在本压缩包中,你将获得Red5 6.0版本的Java源代码,这对于开发者来说是一个宝贵的资源,可以深入理解Red5的工作原理,进行二次开发或者定制化服务。 Red5的核心特性包括: 1. **RTMP协议支持**:Red5实现了Adobe的...

    RED5 1.0.6源码

    RED5是一款开源的流媒体服务器,它支持实时传输...通过深入分析RED5 1.0.6源码,开发者不仅可以提升Java和流媒体技术的专业能力,还能掌握服务器端软件的设计和实现,为未来开发自定义的流媒体解决方案打下坚实基础。

    RED5直播包括Flex和Java全部源代码

    在"RED5直播包括Flex和Java全部源代码"这个项目中,我们可以深入理解如何利用RED5搭建直播平台,并通过Flex进行客户端的交互。 首先,让我们来了解一下Flex。Flex是一种基于ActionScript 3的开发框架,主要用于构建...

    red5 server 1.0.10-M7 源码

    源码分析对于开发者来说非常有价值,可以深入理解Red5 Server的工作原理,自定义功能或者优化性能。1.0.10-M7版本的源码可能包含了bug修复、性能优化以及新的特性和功能。开发者可以研究代码,了解如何处理连接、...

    RED5多人会议源码

    RED5多人会议源码主要涉及以下知识点: 1. **RED5架构**:RED5由服务器端和客户端两部分组成。服务器端处理流媒体的发布、播放、录制和存储,而客户端则负责音视频数据的采集、编码、解码和显示。RED5支持多种流...

    Red5 Java 端聊天室代码

    在这个名为"Red5 Java 端聊天室代码"的压缩包中,包含的是一个使用Red5服务器构建的聊天室应用的源代码。下面我们将深入探讨Red5服务器、Java编程以及聊天室应用的相关知识点。 1. **Red5服务器** - Red5是一个...

    red5-server

    这个"red5-server"项目包含的就是Red5的源代码,对于开发者来说,它是理解流媒体服务工作原理和自定义功能的一个宝贵资源。下面我们将深入探讨Red5 Server的相关知识点。 1. **Red5 Server介绍** Red5 Server是由...

    RED5 入门资料

    标签 "源码" 表明RED5作为一个开源项目,其源代码是公开的,允许开发者进行深入研究、定制或扩展功能。这对于技术爱好者和有特定需求的企业来说是非常有价值的,他们可以修改源代码以适应自己的业务需求。 "工具" ...

    red5入门教程(pdf)

    1. **Red5简介**:Red5是由Java编写的一个开放源代码流媒体服务器,支持RTMP(Real Time Messaging Protocol)、HLS(HTTP Live Streaming)和RTSP(Real Time Streaming Protocol)等多种协议,能够处理音频、视频...

    Red5 Pro---Android demo

    1. **源码文件**:包含Android应用的Java或Kotlin源代码,展示了如何在Android应用中实现与Red5 Pro服务器的交互。 2. **资源文件**:如布局XML文件、图片资源、音频文件等,用于构建应用的用户界面。 3. **Gradle...

    red5-live项目

    Red5 Live项目是一个...具体的功能和实现细节需要查看项目的源代码和文档来详细了解。如果你打算使用或贡献这个项目,你需要具备一定的Java编程和Red5服务器操作经验,了解相关流媒体技术以及可能涉及到的网络协议。

    red5视频插件

    其开源性质意味着开发者可以深入源代码,进行定制化开发。 6. **跨平台**:由于基于Java,Red5可以在任何支持Java的平台上运行,包括Windows、Linux、Mac OS X等。 关于“red5视频插件”,虽然具体功能未知,但...

    Eclipse的red5插件

    2. **源代码编辑**:Eclipse作为强大的Java IDE,其代码编辑功能在Red5插件的支持下,可以提供智能提示、语法高亮、错误检查等,提升编码效率。 3. **调试支持**:插件提供了Red5应用程序的调试功能,可以在Eclipse...

    在eclipse中使用tomcat开发RED5项目

    RED5是一个基于Java语言的开放源代码流媒体服务器,能够处理RTMP、HLS、RTSP等协议,广泛应用于在线视频、直播等领域。 描述中提到的“NULL”表示没有具体的项目细节,但我们可以通过常规的步骤来阐述如何在Eclipse...

    red-server-1.0.10-M9.tar.gz

    解压后,进入目录,可以看到"red5-server"子目录,其中包含Red5的源代码和相关配置文件。接着,我们需要Java开发环境,因为Red5是用Java语言编写的。确保系统已安装Java JDK,并且版本至少为1.6,因为Red5对Java版本...

    red 5 配置解读(一)

    应用目录结构应符合Red5的要求,以便正确解析。 **四、Red5流存储** 1. **本地存储**:Red5支持将流数据存储在本地文件系统,这在`red5.properties`中配置,如`stream.storageFactory=org.red5.server.storage....

    Red5边源服务器集群部署

    下载并解压Red5的源代码,进行编译和安装。 2. **配置集群**:在Red5的`conf/server.properties`文件中,你需要配置集群的相关参数,如`cluster.enabled=true`来启用集群模式,以及设置`cluster.nodes`为集群中的...

    【red5】实现点播-直播功能

    6. 源码分析 Red5是开源的,因此你可以深入研究其源码,了解其工作原理,甚至可以根据需要进行定制开发。这为开发者提供了更大的灵活性和可扩展性。 总结,Red5提供了一套完整的解决方案来实现点播和直播功能,...

    red5聊天室、视频、用户列表的源代码

    通过以上分析可以看出,该项目通过Red5服务器端的应用编程接口(API)实现了基本的多人视频聊天室功能。客户端采用Flash ActionScript进行开发,实现了用户界面设计和事件响应等功能。整个项目涵盖了视频传输、用户...

Global site tag (gtag.js) - Google Analytics