Transcript Red5 介绍

Web IM
宋晓东
57575777.com
Red5 介绍






Java开发开源的Flash流媒体服务器
Jetty6(servlet engine)
Mina (networking) 省下处理底层I/O和线程
并发等复杂工作
整合Spring框架
视频/音频直播、录制、在线聊天、小型网
游等
使用RTMP协议,建立在TCP协议或者轮询
HTTP协议之上
Red5请求响应流程







Red5在启动时会调用RTMPMinaTransport的start()方法,该方法会开启rmtp的socket监
听端口(默认是 1935),然后使用mina的api将RTMPMinaIoHandler绑定到该端口。
RTMPMinaIoHandler上定义了messageReceived、messageSent、sessionOpened和
sessionClosed等方法,当有socket请求时,相应的方法会被调用,这时
RTMPMinaIoHandler会使用当前的socket连接来创建一个RTMPMinaConnection,并将
其作为参数传递给定义于 RTMPHandler类上的相应的messageReceived、messageSent
、connectionOpened和 connectionClosed方法。
RTMPMinaIoHandler
|--[delegate method call and pass RTMPMinaConnection to]-->RTMPHandler
|--[call lookupGlobal method]-->Server
|--[use globalScope to lookup webScope]-->GlobalScope
|--[call connect method and pass WebScope to]-->RTMPMinaConnection
至此Red5启动完成,WebScope又会将请求转移给ApplicationAdapter,
由它来最终响应请求,而WebIM通过重载ApplicationAdapter的方法来实
现自己的逻辑。
Red5 主要配置文件



red5-core.xml
web.xml
webim-web.xml
red5-core.xml
<!-- RTMP Mina Transport -->
<bean id="rtmpTransport"
class="org.red5.server.net.rtmp.RTMPMinaTransport" initmethod="start" destroy-method="stop">
<property name="ioHandler" ref="rtmpMinaIoHandler" />
<property name="address" value="0.0.0.0" />
<property name="port" value="1935" />
<property name="receiveBufferSize" value="65536" />
<property name="sendBufferSize" value="271360" />
<property name="eventThreadsCore" value="4" />
<property name="eventThreadsMax" value="8" />
<property name="eventThreadsKeepalive" value="60" />
<property name="tcpNoDelay" value="true" />
</bean>
<!-- RTMP Mina Connection -->
<bean id="rtmpMinaConnection" scope="prototype"
class="org.red5.server.net.rtmp.RTMPMinaConnection">
<!– 每隔多少秒ping一次clien. -->
<property name="pingInterval" value="5000" />
<!– 多少秒未响应断开. -->
<property name="maxInactivity" value="60000" />
<!– 等待握手成功最长时间. -->
<property name="maxHandshakeTimeout" value="5000" />
</bean>
<!-- RTMPHandler -->
<bean id="rtmpHandler"
class="org.red5.server.net.rtmp.RTMPHandler">
<property name="server" ref="red5.server" />
<property name="statusObjectService"
ref="statusObjectService" />
</bean>
<bean id="rtmpMinaConnManager"
class="org.red5.server.net.rtmp.RTMPConnManager">
</bean>
<!-- RTMPMinaIOHandler -<bean id="rtmpMinaIoHandler"
class="org.red5.server.net.rtmp.RTMPMinaIoHandler">
<property name="handler" ref="rtmpHandler" />
<property name="codecFactory" ref="rtmpCodecFactory" />
<property name="rtmpConnManager"
ref="rtmpMinaConnManager" />
</bean>
web.xml






















<context-param>
<param-name>globalScope</param-name>
<param-value>default</param-value>
</context-param>
<context-param>
<param-name>parentContextKey</param-name>
<param-value>default.context</param-value>
</context-param>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>/</param-value>
--- 多个项目用“/” 单个项目直接用项目scope名
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/classes/*-web.xml
---加载所有red5配置文件
</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
webim-web.xml
















<bean id="web.context.webim" class="org.red5.server.Context“ autowire="byType" />
<bean id="web.scope.webim" class="org.red5.server.WebScope“ init-method="register">
<property name=“server” ref=“red5.server” />
----设置全局的服务器域
<property name="parent" ref="global.scope" />
----设置父域
<property name="context" ref="web.context.webim" /> ----指当前域
<property name="handler" ref="web.handler.webim" /> ----当前域的控制器
<property name="contextPath" value="/webim" />
----连接当前域的路径
<property name="virtualHosts“ value="chat.57575777.com, 127.0.0.1" />
---用逗号分割开当然域(scope)运行的一组主机名或者IP地址
</bean>
<bean id="web.handler.webim" class="com.fg114.im.red5Server.Application"
singleton=“true”>
---第一个客户端连接这个域(Scope)时触发
<property name="connectService" ref="connectService" />
<property name="chatLogService" ref="chatLogService" />
<property name="userSatisfactionService" ref="userSatisfactionService" />
</bean>
Application模式



red5里面,每个应用对应一个域(scope),所有的客户端(client)通过连接
(connection)连接到域当中。
ApplicationAdapter类是是所有应用的基础。它提供了使用共享对象和流的方法,以及
连接和排序的服务。
ApplicationAdapter运行时候里面包含几个事件处理:

public boolean appStart(IScope app) 应用开始的时候触发,app为此域
public boolean appConnect(IConnection conn, Object[] params) 客户端连接到域的时候
触发,也就是flex前端 nc.connect的时候触发,conn为当前连接
public void appDisconnect(IConnection conn) 客户端断开时触发,conn为客户端
public boolean appJoin(IClient client, IScope app) 也是连接到应用时触发,这个是在
appConnect完成后触发主要初始化工作这个方法里面完成
public void appLeave(IClient client, IScope app) 客户端断开或者服务器直接断开前会
触发该方法,用来做一些收尾工作
Room模式





public boolean roomStart(IScope room)
public void roomStop(IScope room)
public boolean roomConnect(IConnection conn, Object[] params)
public boolean roomJoin(IClient client, IScope room)
public void roomLeave(IClient client, IScope room)
与Application的区别在于,Application模式全在同一个域里面,room模式会开很多子域,每个房间对
应一个子域,在资源利用上开销相对较大
代码说明
ShareObject



顾名思义共享对象,而通常意义上的共享
Local Share Object(本地共享对象)类似于
cookie,
Remote Share Object(远程共享对象) 类似
Jsp中的Application
代码说明
客户端框架



Cairngorm 是官方推出的最早的Flex ,AIR框架. 使用Cairngorm框架能
快速地创建RIA应用,适用于开发大中型RIA应用程序. (IM 内外部客户
端)
PureMVC是一个ActionScript 3框架,可以用于开发基于ActionScript 3
的任何程序,学习起来相对于Cairngorm要难一些.同样适用于大中型应
用. (ET)
Mate 框架的目的是简化事件驱动的Flex应用开发,比较适合小型应用.
(IM后台管理)
Mate
Mate是一个基于标签的,事件驱动的框架。基于标签意味着它可以完全实现在
MXML中。该框架的目的是让事件响应者的声明变得简便。比较适合小型项目
Flex – Red5通信



Flex 与 Red5 通信有点类似远程方法调用(RMI)
一般以数组里面存放对象来传参(red5对多参数传递支持比较弱)
代码示例
RTMP带宽测试
服务器带宽消耗比较
2M ADSL 客户端
IN
OUT
HTTP 方式播放10M以上视频
4.8 KB/s
250 KB/s
RTMP 方式播放10M以上视频
6.5 KB/s
23 KB/s
HTTP 方式播放,如果服务器端不限速,客户端的带宽越大,服务器消耗的带
宽也越大,但限速又会影响用户体验;
RTMP 流媒体方式播放,只要客户端达到最低带宽要求,不管客户端的带宽
如何,服务器消耗的带宽都一样。
纯文字聊天,带宽上不会出现问题
Flex开发经验小结










1. 从外部加载媒体(图片,swf,xml等)
2. 在嵌入式字体中限制字符集(一般只会嵌入英文字体)
3. 缓存框架 RSLS (主要是内置框架缓存在FlashPlayer中swf文件大小 减少200k左
右)
4. 考虑模块化 (大系统中使用,缩短loding时间,分布式开发)
5. 推迟实例化 (一般很少用,效果不明显,可缩短数据下载到到显示的时间)
6. AIR后台运行降低帧频,设为1比较合适
内存释放优化原则:
1.移除对象一定置空,并且移除所有引用,移除所有子对象
2.事件不用时要移除掉,否则影响正常的垃圾回收机制
3. 流文件要unload()后再置空再移除,否则有内存泄漏情况


















1. release时去掉所有trace信息和logger信息,否则影响性能
2. 如果报无法访问本地文件或swf 在compile里面写 -use-network=false
3. 实现component真正隐藏除了设置visible=false外还需要设includeInLayout = false
4. 设手型有时出来设buttonMode="true" useHandCursor="true" 还要设mouseChildren="false"
5. for循环时要用
var len:int = array.length;
for(var i:int = 0; i<len; i++) { //i 不要用number, len变量}
6. IE中FLASH链接区域鼠标闪 , 在FLASH的属性参数中加上以下两句中任意一句都可以解决
<param name="wmode" value="opaque">
<param name="wmode" value="transparent">
7. 用i>>1 替代 i/2
8. 创建Object 用 var obj:Object = {} 代替 var obj:Object = new Object(); 速度提升1.5倍
创建 Array 用 var arr:Array = [] 代替 var arr:Array = new Array();
速度提升3.5倍
ArrayCollection 的创建非常的慢,耗时大概是var arr:Array = []的100倍
9. 循环中,常量要提出来,例如:
var constant:String= MouseEvent.CLICK
for(var i:Number=0; i<100000; i++) { tmpVar = constant; }
10. flex加载完module后,module里面的东西如果是用flash的组件,有时会出现flash组件不显示,需要调用
validateNow()
11. air工程中,自定义alert跟flex工程不一样,flex可以 Application.application.addChild(alert),air在开多窗体
时要 Window.getWindow(obj).addChild(alert), obj是传进来的当前对象
12. 外部读取文本要考虑转义字符的问题(比如 换行\n会变成\\n 要替换下)
13. Container的borderStyle属性设为solid,cornerRadius才会有效果了。
14. .actionScriptProperties 这个文件用来配置编译的属性,出现莫名其妙的问题的话 不妨看看这个文件
15. Red5使用objectMap一定放数组中传参否则不能识别
16. 销毁场景时需把对象置空,如果是流要unload,可以强制抛错执行垃圾回收