tigase内部处理(1):启动

1.启动

参考:http://my.oschina.net/greki/blog/209928

入口:XMPPServer.start(),关键源码如下:

router = (MessageRouterIfc) Class.forName( mr_class_name ).newInstance();
router.setName( serverName );
router.setConfig( config );//初始化配置
router.start();//启动

1.1.MessageRouter.setConfig(config)

主要任务就是初始化组件,把组件按名字和对绑定到相关的变量里,为后面xmpp packet路由做准备;

components.put(getName(), this);//将自己添加到自己的components成员变量
this.config = config;//将config赋值给自己的成员变量
config.addRegistrator(config);//config注册到自己的成员变量registrators 

--->addRegistrator()

registrators.put(registr.getName(),registr);//1.registr注册到MessageRouter的registrators
addComponent(registr);//2.registr注册到MessageRouter的components和components_byId
for (ServerComponent comp : components.values()) {
  registr.addComponent(comp);//3
} 
--------->2:addComponent(registr)
for (ComponentRegistrator registr : registrators.values()) {
	if (registr != component) {
		registr.addComponent(component);
	}
}      
components.put(component.getName(), component);
components_byId.put(component.getComponentId(), component);
if (component instanceof XMPPService) {
      xmppServices.put(component.getName(), (XMPPService) component);
}

--------------->3:registr.addComponent(comp)

if (isCorrectType(component)) {
	components.put(component.getName(), (E) component);
	componentAdded((E) component);
	return true;
} else {
	return false;
}

----------------------->4:componentAdded((E) component);调用setup方法

1.getDefConfigParams()

        通过[BasicComponent和ConfigaratorAbstract].getDefaults 获取初始化默认参数列表 ,添加感兴趣的属性。 MessageRouter与registr在执行getDefaults不同的是,他还有获取AbstractMessageReceive的成员变量信息。添加了队列的相关信息。

    在通过 MessageRouterConfig.getDefaults(defs, params, getName())设置MessageRouter配置信息。

2.component.setProperties

    BasicComponent和ConfigaratorAbstract的setProperties方法,设置组件成员变量:如:compId、defHostname、admins、commandsACL等,并loadScripts。此过程主要是通过加载、过滤参数列表,初始化话registr组件。

     每个component的初始化方法就是component.setProperties

1.2.MessageRouter.setProperties的初始化

这里可以帮助我理解packet在组件中是怎么处理的,packet有个from和to属性,包在组件间的路由主要根据TO属性来判断有谁来处理这个packet

1.这里有2个对后面包处理关系比较的

ServerComponent mr
if (mr instanceof MessageReceiver) {
  ((MessageReceiver) mr).setParent(this);//把message-router设置为他的上级服务器组件
   ((MessageReceiver) mr).start();  //MessageReceiver启动处理component的in和out的QueueListener处理线程,监听AbstractMessageReceiver的in和out的packet_queue

2.如果是messagerReceiver添加到组件的路由

if (mr instanceof MessageReceiver) {
	addRouter((MessageReceiver) mr);
} else {
	addComponent(mr);
}

3.组件初始化完毕处理

for (ServerComponent comp : components.values()) {
	comp.initializationCompleted();
}

4.特别说明下clientConnectionManager.initializationCompleted()处理;

追踪了下,c2s是怎么接收client发送过来的tcp的包和处理的;

tigase内部处理(1):启动_第1张图片

最终会启动负责读写的socketReadThread和socketWriteThread及ResultsListener线程;报文的接受和发送是通过nio实现;用户的socketChannel是被对象

socketIO持有,再被IOService【集成了Callable】持有,再被放到selectionKey里;

socketThread线程在收到报文后,selectionKey的IOService放到forCompletion的列表里,

在统一被completionService.submit(serv),调用XMPPIOService的call方法进行内部的packet处理;

ResultsListener负责处理处理完毕的IOService;

(对于packet在tigase的内部处理,到时候在起一篇文章整理下;基本上都是线程+队里的处理方式)

可以先看下http://my.oschina.net/greki/blog/209588

1.3.再看看router.start()启动

主要调用了AbstractMessageReceiver.startThreads();启动了router组件的in和out线程,处理由QueueListener的run来处理;

收到queue里的packet,根据packet.to属性获的来处理该packet的component,交它处理


packet=queue.take()
message_router.processPacket(packet){
compent comp = getLocalComponent(packet.getTo());
compent.processPacket(packet)


你可能感兴趣的:(tigase内部处理(1):启动)