• Openfire S2S 连接建立与消息发送


    原文地址:http://yjl49.iteye.com/blog/1452569

    发送给其它服务器的消息由@domain 部分区分,在进入到服务器路由后在RoutingTableImpl.routePacket(Packet packet) 中与发送给本地服务器的消息分离。

    Java代码 
    1. public void routePacket(JID jid,......){  
    2.   boolean routed = false;  
    3.   if(serverName.equals(jid.getDomain())){  
    4.      routed = routeToLocalDomain(jid,packet,fromServer);  
    5.   }  
    6.   else if(jid.getDomain().contains(serverName)){  
    7.      routed = routeToComponent(jid,packet,routed);  
    8.   }  
    9.   else{  
    10.      routed = routeToRemoteDomain(jid,packet,routed);  
    11.   }  
    12. }  
    13. ......  

    在初次发送消息给外部服务器时两台服务器的连接还没有建立,这种情况下会将包交由一个OutgoingSessionPromise 对象来处理,将消息加入它的队列。

    Java代码 
    1. private boolean routeToRomoteDomain(JID jid,Packet packet,boolean routed){  
    2.      byte[] nodeID = serverCache.get(jid.getDomain);  
    3.      if(nodeID!=null){  
    4.         ......  
    5.      }  
    6.      else{  
    7.         OutgoingSessionPromise.getInstance().process(packet);  
    8.         routed = true;  
    9.      }  
    10.      return routed;  
    11. }  

    在OutgoingSessionPromise 中保有一个线程池和一个独立线程。

    独立线程不断从消息队列中读取要处理的packet,并针对每个domain建立一个PacketsProcessor线程,将消息交给这个线程,然后把此线程放入线程池中运行。

    Java代码 
    1. final Packet packet = packets.take();  
    2. boolean newProcessor = false;  
    3. PacketsProcessor packetsProcessor;  
    4. String domain = packet.getTo().getDomain();  
    5. synchronized (domain.intern()){  
    6.     packetsProcessor = packetsProcessors.get(domain);  
    7.     if(packetsProcessor == null){  
    8.        packetsProcessor = new PacketsProcessor(OutgoingSessionPromise.this,domain);  
    9.        packetsProcessors.put(domain,packetsProcessor);  
    10.        newProcessor = true;  
    11.     }  
    12.     packetsProcessor.addPacket(packet);  
    13. }  
    14. if(newProcessor){  
    15.    threadPool.execute(packetsProcessor);  
    16. }  

    PacketsProcessor在发送消息包时会判断到外部服务器的连接是否已经建立。未建立的情况下会调用LocalOutgoingDServerSession.authenticateDomain() 方法建立连接。

    具体的Socket连接建立是在authenticateDomain() 方法中经过一系列的验证和鉴权后调用createOutgoingSession(domain,hostname,port)来完成。

    建立好连接后则重新调用routingTable.routePacket() 再进行一次路由。

    ------------------------------------------------------注意----------------------------------------------------

    Openfire 中S2S 之间的链接有TLS 和 Dialback 两种加密验证方式。

    如果使用TLS 方式则需要双方都有可信任的根证书,否则会出现General SSLEngine problem 异常。

    Dialback则提供一种弱身份验证的方式,要使用这种方式可以将Openfire数据库中ofproperty 表中“xmpp.server.tls.enabled” 设置为false,并将“xmpp.server.dialback.enabled”设置为true。

    另:Openfire 3.7.0 中的Dialback 方式有bug 会导致连接失败,已经在3.7.1中进行了修复。具体需要参照3.7.1中的代码修改LocalIncomingServerSession.java 和ServerDialback.java 两个文件。

  • 相关阅读:
    tensorflow学习笔记五----------逻辑回归
    tensorflow学习笔记四----------构造线性回归模型
    tensorflow学习笔记三----------基本操作
    tensorflow学习笔记二----------变量
    tensorflow学习笔记一----------tensorflow安装
    大屏某区域滚动效果循环
    echarts轨迹图,各个城市线路图轨迹如何取值
    react组件,样式添加的方法
    微信小程序中hidden属性不生效
    react组件渲染编程html不成功
  • 原文地址:https://www.cnblogs.com/ilahsa/p/2680090.html
Copyright © 2020-2023  润新知