zoukankan      html  css  js  c++  java
  • tigase服务端启动分析(一)

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

    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 );
    //启动Server
    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
    }

    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);
    }

    registr.addComponent(comp)

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

    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组件。

    1.2 MessageRouter.setProperties的初始化

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

    1、包处理关系 ServerComponent mr if (mr instanceof MessageReceiver) { //把message-router设置为他的上级服务器组件 ((MessageReceiver) mr).setParent(this); //MessageReceiver启动处理component的in和out的 ((MessageReceiver) mr).start(); 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();
    }

    c2s是怎么接收client发送过来的tcp的包和处理的

    最终会启动负责读写的socketReadThread和socketWriteThread及ResultsListener线程; 报文的接收和发送是通过nio实现;用户的socketChannel是被对象socketIO持有,再被IOService【集成了Callable】持有,再被放到selectionKey里; socketThread线程在收到报文后,selectionKey的IOService放到forCompletion的列表里, 在统一被completionService.submit(serv),调用XMPPIOService的call方法进行内部的packet处理; ResultsListener负责处理处理完毕的IOService;

    对于packet在tigase的内部处理 ,基本上都是线程+队里的处理方式。

    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)
     
    学海无涯、何时是岸
  • 相关阅读:
    R语言介绍
    mysql存储过程和函数的操作
    在SSRS自动化报表中创建共享数据源
    在python中实现数据库下group by功能
    MySQL中创建表及导入文件
    python下各种包的安装
    windows下python2.7.11的安装
    面向对象(异常)
    面向对象(内部类)
    面向对象(Object类)
  • 原文地址:https://www.cnblogs.com/veblen/p/14703581.html
Copyright © 2011-2022 走看看