Openfire S2S 连接建立与消息发送

来源:互联网 发布:钢琴教学视频 知乎 编辑:程序博客网 时间:2024/04/30 18:40

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

public void routePacket(JID jid,......){  boolean routed = false;  if(serverName.equals(jid.getDomain())){     routed = routeToLocalDomain(jid,packet,fromServer);  }  else if(jid.getDomain().contains(serverName)){     routed = routeToComponent(jid,packet,routed);  }  else{     routed = routeToRemoteDomain(jid,packet,routed);  }}......

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

private boolean routeToRomoteDomain(JID jid,Packet packet,boolean routed){     byte[] nodeID = serverCache.get(jid.getDomain);     if(nodeID!=null){        ......     }     else{        OutgoingSessionPromise.getInstance().process(packet);        routed = true;     }     return routed; }
          在OutgoingSessionPromise 中保有一个线程池和一个独立线程。

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

final Packet packet = packets.take();boolean newProcessor = false;PacketsProcessor packetsProcessor;String domain = packet.getTo().getDomain();synchronized (domain.intern()){    packetsProcessor = packetsProcessors.get(domain);    if(packetsProcessor == null){       packetsProcessor = new PacketsProcessor(OutgoingSessionPromise.this,domain);       packetsProcessors.put(domain,packetsProcessor);       newProcessor = true;    }    packetsProcessor.addPacket(packet);}if(newProcessor){   threadPool.execute(packetsProcessor);}
    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 两个文件。