原文:http://www.rubyfleebie.com/im-integration-with-xmpp4r-part-2/
第一部分我们更多的是讨论XMPP,这次我们主要讨论XMPP4r。
现在我们知道XMPP消息就是在通过TCP建立连接的客户端和服务器之间传送信息的XML片段。我们现在可以理解XMPP4r的目的了。
XMPP4r就是一个ruby库,扮演了XMPP客户端的角色。通过这种方式来理解你就不会困惑XMPP4r应该用来干什么。就像其他jabber客户端(google talk,pidgin)一样,Xmpp4r发送、接收和管理叫做节(stanzas)的XML消息。
某种意义上来说,XMPP4r就像没有GUI的GoogleTalk(当然你要自己设计客户端的行为)。在GoogleTalk中,你会通过按下连接按钮连接到一个Jabber服务器。用XMPP4r,你需要这么写:
第一行建立了一个Client类的实例,代表用户自己。第二行试着在用户和Jabber服务器之间建立一条连接。第三行用下列机制来验证用户:
SAL DIGEST-MD5
SASL PLAIN
Non-SASL digest
第四行我们发送一个presence节给服务器。我们这么做是想让服务器知道我们已经在那里了。这样我们的好友列表里的人就可以知道我们已经在线,可以聊天了。
现在你已经在线了,但是怎么和别人交换消息呢?很简单:
注意:必须把message的类型设为“chat”,因为一些客户端会根据message的类型做出不同的回应。一个Gajim用户会反感你如果你用"normal"类型的消息发送给他,因为Gajim会为每一条接收到的"normal"消息弹出一个新的窗口,但是用同一个窗口来显示来自相同用户的"chat"类型的消息。
现在我们知道怎么给别人发送消息了,但是如果某些人不在我们的好友列表里会发生什么?什么都不会发生。XMPP不允许我们这么做,我们也同意这是一件好事。谁喜欢被垃圾信息打扰呢?
如果我们希望把[email protected]加为我们的好友,我们这样做:
我们已经发出了邀请,回应会是什么呢?上面的行并不会等待回应。你可以想象,它可能等待很久。毕竟我们不能控制在另一头的人的回答。这引出了xmpp4r的一个关键特性:回调(calllbacks)。
让我们回到之前对John发出的订阅请求。因为我们说过我们的代码不会等待回应,所以我们需要一些其他的方式来获取之后到来的回应。(这就是回调所代表的内容,是么?)
因为我们送出的是一个订阅请求,所以一旦另一方的用户回应,"add_update_callback"回调将会被调用。如果你想要被通知,就注册这个回调:
Xmpp4r为很多目的提供回调。如果我想收到别人发给我消息的提醒,该怎么做?答案是add_message_callback:
还有一个很有用的回调让你知道你好友的状态改变:
注意在xmpp4r中的各种回调都运行自己的线程中。
这就是第二部分的全部了。下一部分应该会包含Roster辅助方法,我还会批评一下Xmpp4r的稳定性和文档的缺乏。
Don Park和Nilu在这个教程中碰到了问题,可能因为我忘了讨论最基本的部分:订阅(subscription)。为了从他人接收信息,你必须首先接受他们的订阅请求。下面是方法:
现在应该就没问题了。
在评论中的留言使我的文章得到一个正确的更新:
Nilu,
我确信你已经找到答案了,但是让我解释一下“在他们自己线程中运行”的意义:
回调在"parser thread"的环境中被调用,实际上是它在监听XML stream。当某些事情在parser thread中发生时(例如message stanza接收到),回调就会从那里被调用。所以你在各种回调中写的代码在parser thread环境中被有效执行。
就像Leonardo说的,你必须在你的主线程中写Thread.stop来保持当前的线程活动。Thread.stop将简单地使当前线程进入休眠状态并且把调度时间分给其他的线程(在我们的例子中是parser thread)。如果你不写Thread.stop,当主线程没有事情可以做的时候整个程序就退出了。