看来最近这段时间我和xmpp是干上了。今天要写一点关于xmpp pubsub的一些认识。
服务器用openfire3.7.1
我们都知道XMPP pubsub的功能很强大。可以用来完成非常多的功能。正好最近在开发一些服务器端的应用用到了pubsub的功能。然后对openfire的pubsub实现有了一些了解。
我用一个例子来说明具体的流程:客户端publish它的状态信息。服务器端的应用subscribe客户端的状态信息。服务器收到publish消息后,发送notification给应用。
NodeAffiliate.java中sendPublishedNotifications方法就是整个流程中关键的入口。它调用了sendEventNotification方法。这个方法里面会根据subscriber JID作为key来构建一个hashmap。map的value是subID。
这里要说明一下:缺省情况下,openfire支持同一个JID对同一个node做多次的subscribe。这样subID就用来区分多个subscription。
hashmap构建好了之后,就遍历整个map,然后调用node.sendEventNotification--->PubSubModule.sendNotification--->PacketRouterImpl.route---->MessageRouter.route
这个中间没有什么要说的。走到MessageRouter.route方法后是最关键的地方了。
方法的开始和退出的时候两次调用了InterceptorManager.getInstance().invokeInterceptors。这是openfire plugin被调用的地方。我会下一篇里面讲我对plugin的一些了解,以及我所做的plugin。
方法的中间就是调用RoutingTableImpl.routePacket, 这就是openfire在路由traffic的地方。思路就是:
1)如果接受者的domain和服务器的domain一致,就调用routeToLocalDomain
2) 如果接受者的domain包含服务器的domain,就调用routeToComponent。这里要说明一下,大多数情况下,我们会利用external component来实现我们自己的服务器应用。这时候就需要给我们的external component定义一个sub-domain。例如:服务器的domain是ilxlf.com,我们要用external component实现一个游戏的应用,那么我们定义component的sub-domain是:game.ilxlf.com 服务器内部就这一步来判断是否要路由到我们的component。
3)最后调用 routeToRemoteDomain.
这里我说明第一步的逻辑: routeToLocalDomain
这里有一个前提知识:full JID和bare JID。这里就不讲了。我只说bare JID的情况。
当服务器发现subcriber用的是bare JID,他的流程是:
1)找到这个subscriber所对应的所有活的session。
2)从这些session里面选择优先级最高的一个session。最后调用LocalClientSession的deliver方法把消息发出去。
3)如果优先级最高的是一组session,那么再根据session的presence信息中的一些状态值排序,这里有一个最好理解的排序算法:多个session中,最后一个连接到服务器的session优先级最高。就用这个session把消息发出去。
到这里服务器就把notification包发给subscriber。
今天先写到这里。下一篇再讲pubsub的一些编程方面的总结。