ApplicationEventMap.mxml
mate框架的
下面的处理的事件有下面几类,在
PortTestEvent - 触发测试RTMP端口,端口测试成功,端口测试失败。对应的类为ModuleProxy,可以参考对应的as文件。
LogoutEvent - 用户logout调用UserService.logoutUser()和ModulesProxy.handleLogout(),测试连接断开调用UserService.disconnectTest()
UserServicesEvent - 启动服务,也是调用UserService.startService()方法
UsersConnectionEvent - 连接成功,也是调用UserService.userLoggedIn()方法
SuccessfulLoginEvent - 成功登录,调用ModulesProxy.loadAllModules()
RaiseHandEvent - 举手发言,调用UserService.raiseHand()
LowerHandEvent - 放弃发言,调用UserService.lowerHand()
BroadcastStartedEvent - 流广播开始事件(具体是什么流还不太清楚),调用UserService.addStream()
BroadcastStoppedEvent - 流广播结束事件,调用UserService.removeStream()
KickUserEvent - 踢人事件, 调用UserService.kickUser()
ConfigEvent - 配置读取后触发,依次调用ConfigManager.setConfig(),SkinningService.loadSkins()。
下面紧接的两个HTTPService好像没什么用,并没有调用。
需要重点分析的是model目录下的文件。
BigBlueButtonPreloader - 下载进度条,这里主要是flash的下载和初始化进度,之前也看到过LoadingBar.mxml,那个主要是显示模块的加载进度,模块加载后面再分析。
ConferenceParameters - 存放会议的相关信息,没什么逻辑,就是一个结构体。包括会议名称,当前的用户名,用户的角色(协调者或者普通参与者),room id,语音会议bridge的地址(asterisk或者freeswitch),语音会议bridge的外部地址(这里不太确定),欢迎提示,会议id,外部用户id(不清楚),logout地址,connection(不清楚是什么连接,和red5的?),内部用户id(不清楚),是否录制会议。
ConfigParameters - 加载conf/conf.xml配置文件,这里会构造ModuleDescriptors,后面可以再仔细分析。
LayoutOptions - 控制一些UI上的显示。
PortTest - 用来测试多种flash支持的网络协议的联通性
PortTestProxy - 对PortTest做了个包装,PortTest看代码应该是第三方的。
User - 也是一个结构体
model下面还有一个User子目录,按理来说是和用户关联比较紧密的:
Status - key,value状态信息。
StatusCollection - 存储和管理Status信息。
BBBUser - 这里维护用户的状态,包括:当前的presenter是谁,是否有媒体流,是否举手了。
Conference - 维护会议的用户,包括自己和其他人的信息,从[bindable]可以看到这里是为了显示用的。
JoinService - 发起加会请求,成功后保存会议信息。
NetConnectionDelegate - 网络连接和重连
UserSOService - 举手,踢人,连接流媒体,连接服务器
UserService - 包装 JoinService和UserSOService。
接下来分析一下modules目录,整个客户端的框架基本上就分析完了。
bigbluebutton采用模块化的方式来组织,在common目录下面,可以看到有三个接口,一个是IBbbModuleWindow,这个是模块的窗口,通过这个接口来获取窗口位置来布局,IBigBlueButtonModule,这个用来设置模块的属性,这些属性都是从config.xml中读取的,并通过事件传递过来的。
在modules目录下面,是模块相关的代码,在src目录下面,有很多*Module.mxml,这些都是继承了IBigBlueButtonModule,而且基本上每个模块都定义了自己的EventMap,mate可以定义多个EventMap,这些都会挂接到一个总的event bus上去,每个模块会定义自己的event和对应的event映射和处理函数,也可以处理全局的一些事件。
初始化流程
1. BigBlueButton.mxml的preloader第一步被执行:org.bigbluebutton.main.model.BigBlueButtonPreloader,会下载BigBlueButton.swf文件。
2. 建立ApplicationEventMap,设置事件处理表,在FlexEvent.PREINITIALIZE中,还会创建一些全局对象,包括ModulesProxy,UserService,ConfigManager,在ModulesProxy中会依次创建ModulesDispatcher, PortTestProxy和ModuleManager,ModulesDispatcher用来发送模块相关的一些事件,PortTestProxy用来测试rtmp和rtmpt端口是否是通的,ModuleManager用来管理模块的(加载,删除,传递配置信息);UserService用来加会的。ConfigManager作为一部全局的对象来存储配置信息。ModuleManager的构造函数中创建了ConfigParameters,在ConfigParameters的构造函数中,回去获取conf/config.xml,这是个异步的过程。
3. BigBlueButton.mxml的最下面的MainApplicationShell会创建一个初始化的布局,也就是打开页面后看到的进度条还有下面的一些调试窗口按钮等。ResourceUtil 初始化会加载conf/locale.xml,并且会根据默认的语言来加载对应的swf资源。
4. 配置加载成功回调到ConfigParameters::handleComplete,会将模块配置信息放到ModuleDescriptor中,并回调ModuleManager::handleComplete,在这中间会先触发PortTestEvent.TEST_RTMP,然后检查模块依赖,看所需要的模块是否都在配置列表中,最后触发ConfigEvent.CONFIG_EVENT事件。
5.ConfigEvent.CONFIG_EVENT事件有几个响应的地方,一个是在ApplicationEventMap中,会调用ConfigManager::setConfig存储配置,会调用SkinningService::loadSkins更换皮肤。第二个是在MainApplicationShell.mxml中,设置LOG窗口可见性,不过这里好像屏蔽掉了,是通过另外一个事件configLoadedEvent来触发,设置多个窗口的可见性。第三个是在MainToolbar.mxml中,设置语言选择栏可见性和帮助的URL链接。
6.PortTestEvent.TEST_RTMP事件有几个响应的地方,一个是ApplicationEventMap中,会调用ModuleProxy::testRTMP测试端口,另外一个是在LoadingBar.mxml中,这里只是用来显示。这里连的uri是在config.xml中指定的
7. startService中会调用joinService.load来加载配置中的
8. ConferenceCreatedEvent.CONFERENCE_CREATED_EVENT的处理也有两个地方,一个是在viewsWindow.mxml中,这里是视图上的显示,另外一个是APIEventMap,这里只是将meeting信息存储在UserManager中。
9. 第6步中的连接创建成功后,会触发UsersConnectionEvent.CONNECTION_SUCCESS,这个事件也有两个处理的地方,一个是ConnectionLostWindow.mxml中,这里会关掉连接断开的窗口,并重新刷新页面;另一个地方是ApplicationEventMap.mxml,会调用UserService.userLoggedIn(),在这里会调用UsersSOService.join(),会获取当前与会的人员信息,并触发ParticipantJoinEvent.PARTICIPANT_JOINED_EVENT。随后会触发SuccessfulLoginEvent.USER_LOGGED_IN。
10. SuccessfulLoginEvent.USER_LOGGED_IN事件的处理,一个是UI上的显示toolbar,另一个是ModulesProxy.loadAllModules(),从这一步开始起,就依次从配置中给定的模块的uri加载模块了。在模块加载过程中,会依次收到MODULE_LOAD_PROGRESS事件通知,这个会更新UI的进度条显示,当所有的模块都加载完成后,然后会检查locale的版本信息,(这里好像遗漏了locale资源的加载步骤,后面再看吧),然后调用module的start()方法,最后触发ALL_MODULES_LOADED,这个事件的响应处理在ui上就是移除掉进度条。而模块的窗口显示和其他UI按钮的显示,则由模块自己来触发,比如OpenWindowEvent,这个事件触发后会由MainCanvas.mxml处理,调用模块窗口的getPrefferedPosition()获取窗口位置来布局。
至此,bigbluebutton客户端的框架加载流程已经分析完,其中具体模块的加载和具体的应用有关系,下周打算分析其中的语音模块,接下来会分析presenter模块和video模块,并且打算尝试修复presenter的BUG(好像0.8版本并没有改进)。
没有评论:
发表评论