1、打开Tiagse源码,TigaseServer启动入口 start方法:
String config_class_name = System.getProperty( CONFIGURATOR_PROP_KEY,DEF_CONFIGURATOR );
config = (ConfiguratorAbstract) Class.forName( config_class_name ).newInstance();
config.init( args );
// config = new ConfiguratorOld(config_file, args);
config.setName( "basic-conf" );
String mr_class_name = config.getMessageRouterClassName();
router = (MessageRouterIfc) Class.forName( mr_class_name ).newInstance();
router.setName( serverName );
router.setConfig( config );//初始化組件
router.start();//启动Server
说明:主要任务就是根据配置文件搜集所有的组件,构建XMPP路由服务环境;
MessageRouter.java
@Override
public void setConfig(ConfiguratorAbstract config) {
components.put(getName(), this);//将自身添加到自己的components成员变量
this.config = config;
addRegistrator(config);//将自身注册进组件列表中,注意*registrators map类型。存放所有的组件
}
public void addRegistrator(ComponentRegistrator registr) {
registrators.put(registr.getName(), registr);//将自身注册到registrators表中
addComponent(registr);//将registr注册到components中
for (ServerComponent comp : components.values()) {
registr.addComponent(comp);
}
}
A:addRegistrator();//获取所有可以连接到MesssageRouter的ServerComponent
B:addComponent(registr) ;//汇集registr中的组件
C:registr.addComponent(comp);//注册所有组件
1.2、组件的初始化
通过setProperties(Map<String, Object> props)方法完成组件的初始化。
过程:1、分离出所有的组件如果组件instances MessageReceiver(可以接收数据包)那么则添加到组件路由。
2、组件初始化完毕。调用comp.initializationCompleted();方法
2、ClientConnectionManager处理客户端发送过来的数据包的过程如下图
整个处理流程如下:
2.1.socket监听接收客户端报文
socket接收到tcp报文然后转换为xmpp packet的过程;
主处理组件:ClientConnectionManager
c2s在启动的时候创建了3类线程(创建过程参考启动篇):
socketReadThread():负责读socket的数据;
socketWriteThread():负责向socket写数据;
ResultsListener:负责componet执行结果的处理;
a.socketReadThread和socketWriteThread循环selector.select(),得到selectionKey->XMPPIOService放到队列等待完成。
b.把等待完成的XMPPIOService,通过completionService.submit(serv)提交执行,调用XMPPIOService.call();
c.XMPPIOService.call(),完成了接收的socket报文到packet,作为packet在内部处理的入口(后面介绍这些处理);
d.ResultsListener根据XMPPIOService.call()返回的XMPPIOService对象,如果对象不为空重新放回到waiting列表(用于重新注册到clientsSel(selector));
2.2.组件对packet的处理过程
a.从XMPPIOService.call();
processSocketData();
if ((receivedPackets() > 0) && (serviceListener != null)) {
/**
*serviceListener 这里是clientConnectManager;在connectionOpenTrhead里 设置
**/
serviceListener.packetsReady(this);
}
b.processSocketData()把报文转成xml element;再把element转成对应的packet;
while ((elem = elems.poll()) != null) {
//Message、Presence、IQ、其他Packet
Packet pack = Packet.packetInstance(elem);
addReceivedPacket(pack); sendAck(pack);//ack 模式,收到后发送ack
}
c.serviceListener.packetsReady()---->ClientConnectManager.packetsReady()---->processSocketData([此时设置了packet的to和from属性,在messagerouter中决定由那个组件处理])---->addOutPacket(packet)---->放到c2s的输出队列中;
d.c2s中的输出消息队列由QueueListener线程来读取处理;
if ((packet = filterPacket(packet, outgoing_filters)) != null) {
//out_filter处理
processOutPacket(packet);
}
if (parent != null) {
//parent指message_router,在初始化的时候设置
parent.addPacket(packet);//传递给clientConnectManager,把packet构建完成后,交给messageRouter 来处理,添加到它的in_queue;
} else {
// It may happen for MessageRouter and this is intentional
addPacketNB(packet);
}
f.MessageRouter对in_queue里的packet,通过QueueListener线程调用messageRouter.processPacket()轮训。
//根据to属性,查找local的component,普通聊天,一般是路由到SessionManager组件
ServerComponent comp = getLocalComponent(packet.getTo());
if (comp != null) {
if (log.isLoggable(Level.FINEST)) {
log.log(Level.FINEST, "1. Packet will be processed by: {0}, {1}", new Object[] {
comp.getComponentId(),
packet });
}
Queue<Packet> results = new ArrayDeque<Packet>();
if (comp == this) {
processPacketMR(packet, results);
} else {
comp.processPacket(packet, results);
}
if (results.size() > 0) {
for (Packet res : results) {
addOutPacketNB(res);
}
}
return;
}
String host = packet.getTo().getDomain();
ServerComponent[] comps = getComponentsForLocalDomain(host);
if (comps == null) {
comps = getServerComponentsForRegex(packet.getTo().getBareJID().toString());
}
if ((comps == null) &&!isLocalDomain(host)) {
comps = getComponentsForNonLocalDomain(host);
}
if (comps != null) {
Queue<Packet> results = new ArrayDeque<Packet>();
for (ServerComponent serverComponent : comps) {
if (log.isLoggable(Level.FINEST)) {
log.log(Level.FINEST, "2. Packet will be processed by: {0}, {1}",
new Object[] { serverComponent.getComponentId(),
packet });
}
serverComponent.processPacket(packet, results);
if (results.size() > 0) {
for (Packet res : results) {
addOutPacketNB(res);
}
}
}
} else {
if (log.isLoggable(Level.FINEST)) {
log.finest("There is no component for the packet, sending it back");
}
try {
addOutPacketNB(Authorization.SERVICE_UNAVAILABLE.getResponseMessage(packet,
"There is no service found to process your request.", true));
} catch (PacketErrorTypeException e) {
log.warning("Can't process packet to local domain, dropping..." + packet
.toStringSecure());
}
}
3、SessionManager对packet的处理,如下图,就不多说了