Red5二次开发实现用户自定义逻辑
上一篇文章介绍了Red5服务器的搭建是使用,这一篇文章将介绍如何在Red5中实现自己的逻辑。本文章是以第一篇为基础,默认已搭建好Red5服务器,不再介绍Red5服务器的搭建与使用。
准备工作
开发工具:Eclipse
Red5 Server:Red5 Server 1.0.9 https://github.com/Red5/red5-server
red5-eclipse-plugin:https://github.com/Red5/red5-eclipse-plugin
开发工具使用的Eclipse,因为需要使用Red5插件,而Red5插件仅支持Eclipse所以只能选择Eclipse
安装Eclipse插件
根据上面提供的链接下载Red5-eclipse-plugin插件,压缩包解压之后将发现目录中存在一个screenshots文件夹,里面为插件安装步骤的截图,Github中的Readme中也有插件安装的讲解,这里就不再演示插件的具体安装步骤。
注意:在使用之前需要对插件进行简单的修改,否则在配置Red5-server的时候会出现无法进行下一步的问题,以Windows为例,打开org.leagueplanet.server.glassfish目录,找到red5.serverdef并编辑,将文件中的所有.sh结尾的配置全部替换为.bat结尾。Linux系统同理,将.bat修改为.sh
安装完成后重启eclipse,window->show view->servers->new server.出现Red5 Server Runtime选项,说明安装成功。
创建Web项目
新建项目选择Dynamic Web project,第一次配置需要配置一下三处
首先Target runtime可能是空的,这时我们就需要选择New Runtime进行配置运行时环境,如下图所示,选择Infrared5中的Red5 Server RunTime,点击下一步
接下来还需要配置JRE和Red5 Server的路径,Runtime Directory就是选择我们解压的Red5 Server的目录
配置完成后可能下图所示的错误,这是因为我们下载的Red5 Server中相关jar包的命名包含版本信息,例如red5-io-1.8.0-Realease.jar,这时候就要将其修改为red5-io.jar
继续下一步,配置Red5的启动关闭文件以及相关端口号
现在我们回到了创建项目的页面,这是还需要对Configuration进行修改,点击Modify,按照下图进行勾选
现在项目就创建完成了,生成服务端同时还生成了客户端
测试运行
Run Server选择Red5 Server Runtime
使用浏览器打开http://127.0.0.1:5080/demos/publisher.html,发布直播收看直播正常
实现自己的逻辑
在实现这些功能之前我们需要先了解一下Red5响应请求的具体流程
- Red5在启动时会调用RTMPMinaTransport的start()方法,该方法会开启rmtp的socket监听端口(默认是1935),然后使用Mina 的api 将RTMPMinaIoHandler 绑定到该端口。
- RTMPMinaIoHandler 上定义了messageReceived()、messageSent()、sessionOpened()和sessionClosed()等方法,当有socket请求时,相应的方法会被调用。这时RTMPMinaIoHandler 会使用当前的socket连接来创建一个(或者使用之前创建好的)RTMPMinaConnection,并将其作为参数传递给定义于RTMPHandler类上的相应的messageReceived()、messageSent()、connectionOpened()和connectionClosed()方法
- RTMPHandler会调用Server类的lookupGlobal()方法获得当前的GlobalScope,然后再利用GlobalScope找到当前socket请求应该使用的WebScope(这个WebScope 由开发者在WEB-INF\red5-web.xml中定义)。最后,RTMPHandler会调用RTMPMinaConnection 的connect ()方法连接到相应的WebScope。
- 通常来说,WebScope又会将请求转移给ApplicationAdapter,由它来最终响应请求,而项目中通过重载ApplicationAdapter的方法来实现自己的逻辑。至此,控制流进入了开发者的项目中。一般在具体使用中多会使用ApplicationAdapter的父类MultiThreadedApplicationAdapter,因为它是Red5应用程序的基础类,并且支持多线程,性能上要优于Application(未验证)。它提供了操作SharedObjects 和 streams的方法,还有连接和服务列表,是一个应用程序基本的Iscope。它实现了IstreamAwareScopeHandler接口,提供了在应用程序种控制流的方法。它还提供了一个很有用的事件控制器,可以拦截流、授权用户访问等。可以在其子类中添加各种方法,还可在客户端上通过NetConnection.call()方法调用服务器端的方法。
ApplicationAdapter核心方法
- public boolean appStart(IScope app);Red5应用程序启动时自动执行此方法,可以再这里执行一些初始化操作。
- public void appStop(IScope arg0);Red5应用程序停止时自动执行此方法。
- public boolean appConnect(IConnection arg0, Object[] arg1);当客户端连接本应用程序时自执行此方法。
- public boolean appDisconnect(Iconnection conn);当客户端断开连接时自动执行此方法。(如关闭浏览器、关闭FLASH PLAYER等特殊情况,均会触发该方法)。
- public boolean join(IClient arg0, IScope arg1);当有新的连接加入进来时自动调用。
- public void leave(IClient arg0, IScope arg1);连接断开
- public void streamPublishStart(IBroadcastStream stream);开始发布直播
- public void streamSubscriberStart(ISubscriberStream stream);开始播放流
- public void streamBroadcastClose(IBroadcastStream arg0);流结束
- public void streamSubscriberStart(ISubscriberStream stream);用户播放流
- public void streamSubscriberClose(ISubscriberStream arg0) ;用户断开播放
主要API简介
- IConnection:连接对象。每个连接都有一个关联的客户端和域。连接可能是持续型、轮询型、或短暂型。建立此接口的目的,是为了给不同的子类,如 RTMPConnection,RemotingConnection,AJAXConnection, HttpConnection 等,提供基础通用的方法。它提供getClient()方法来获取客服端对象。
- IScope :每个Red5应用程序至少有一个域,用来搭建处理器、环景、服务器之间的连接。域可以构成树形结构,所有客户端都可以作为其节点共享域内的对象(比如流和数据)。所有的客服端(client)通过连接(connection)连接到域中。对于单一域,每个连接对应一个客服端,每个客服端对应一个id,简单的应用,操作就针对一个id和一个连接进行。
- IServiceCapableConnection :获取有效连接。代码中先获取到连接实例,然后判断是否是有效连接并强制类型转换,之后调取客户端相应函数。
- IClient :客户端对象代表某单一客户端。一个客户端可以和同一主机下不同的域分别建立连接。客户端对象和HTTP session 很相像。可以使用IClientRegistry.newClient(Object[])方法来创建IClient对象。
- ApplicationAdapter:ApplicationAdapter是应用层级的IScope。若要处理流进程,需实现 IStreamAwareScopeHandler接口中的相应处理方法。ApplicationAdapter还提供了有效的事件处理机制,来进行截取流、确认用户等操作。同时,其子类中引入的方法均可在客户端通过 NetConnection 调取。在Aodbe 的FMS 中必须在服务器端维护客户端对象,与之相较,Red5 为您的远程请求提供了更加方便快捷的操作方法。
了解了实现流程和主要方法API后下面就开始
检查修改red5-web.xml文件,检查路径是否正确
<bean id="web.handler" class="org.red5.core.Application" />
检查修改red5-web.properties文件,这个文件是配置contextPath和Host,根据自己的需要设置,我的设置如下
webapp.contextPath=/red5-live
webapp.virtualHosts=*
然后就是创建Application类集成ApplicationAdapter类,重写相关方法,是先自定义逻辑
package org.red5.examples.springm