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,可以强制抛错执行垃圾回收