180 likes | 429 Views
Web IM. 宋 晓 东 57575777.com. Red5 介绍. Java 开发开源的 Flash 流媒体服务器 Jetty6(servlet engine) Mina (networking) 省下处理底层 I/O 和线程并发等复杂工作 整合 Spring 框架
E N D
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" init-method="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带宽测试 服务器带宽消耗比较 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,可以强制抛错执行垃圾回收