openfire 的 component
时间:2010-09-25 来源:chouy
我们的消息交换系统要有一个向 OPENFIRE 发送数据的接口,做为我们系统消息传入软交换系统的入口。看了不少源码,总结出有三个解决方案:
1、增加一个 module,启动一个 WEBSERVICE 接口,然后向 internal component 里增加一个子域名,实现一个 component 接口的消息处理类,用于答复自有消息。当自有消息发过来时,把发送人设置为此子域名,然后把消息交给 RoutingTable 去处理;消息回复时就可以直接发回到 component 里了。
2、自己在 JETTY 中启动一个 WEBSERVICE 接口,接收我们系统,在 WEB 容器中调用 RoutingTable 发送数据。这种方式当回复消息时只能在 RoutingTable 中硬编码,把特定消息交给一个特殊程序去处理。
3、我们系统以外部 component 方式连接到 component 上,在 RoutingTable 中注册一个子域,以 component 协议给 openfire 系统发消息。消息回复是 RoutingTable 会自动发给这个 component。
以上三种方中,第2种对系统改造大,对原系统的侵入也大,不予采用。第一种方式和第二种差不多,都是以模块方式接入,但第一种需要另外开发 webservice 接口。第二种需要写一个 component。开发量差不多。
再经过我们查找资料发现,在 openfire 源码库有已经写好的外部 component 的示例程序,名字叫 tinder,在openfire 的 SVN 中就可以下载到。
再根据我们的需求比较1和3方案。我们的系统有40多台机器做为消息来源,这些机器是对等的,也就是它们必须为同一子域。消息有两种类型,IQ 和 message,IQ 必须哪台机器发的请求,答复还要再回到这台机器上去。Message 的请求可以回复到任意一台机器。
于是查看两个方案是否能满足此需求,改造量有多大。读代码和测试中发现,方案1不能原生实现此功能,必须自己实现这种特殊的需求,比如给40多台消息来源机每台起一个名字,在消息回复时根据名字发到不同的机器;方案3本来以为连接必须注册为一个唯一域名,后来读代码发现,在 component 登录时就可以指定是否支持多连接,也就是多个 component 共用一个域名,openfire 在有消息发给此子域时,会自动选择不同的 componet 发送。这样的话 IQ 的回复那不胡乱找个机器回复了!?
经过测试发现,OPENFIRE 的 IQ 回复没有乱回,而是会回到发送IQ的那台机器。很是奇怪。读代码发现,原来它在收到 IQ 消息时会把 IQ 的消息 ID 保存一个列表,当有 IQ 回复时,会根据 ID 查找是哪个连接发的请求,回复消息再发还给它。真不错。那我们的需求就全部解决了。
方案3成了我们的正式解决方案。