XMPP-选择合适的时机注册Presence处理函数

来源:互联网 发布:勒石燕然 知乎 编辑:程序博客网 时间:2024/05/02 08:17

版权所有,转载请注明出处:http://guangboo.org/2013/05/15/xmpp-presence-register-handler

在使用XMPP开发即时通讯应用时,需要注册Presence处理函数,用于接收用户状态的更新。通常用户状态发生变化时,我们需要更新用户界面的显示,即更新UI界面,然而如果presence处理函数注册的时机不对的话,可能会出现意想不到的问题。

现在我在开发的一款应用中,就遇到了相当怪异的现象,更加可恨的是这个现象不是一直出现,没有任何规律。查看系统日志,有一条错误日志“Application Hanging.”,然而仅根据这样的信息还不足以找到问题所在,今天终于找到问题出在哪了。在次记录下来,以便查阅,也给遇到同样问题的乡亲们提供参考。

通常注册Presence处理函数的目的就是订阅用户的状态更新,以便即时更新用户界面。这里我是先注册了Presence处理函数,然后从服务器上加载Roster,并将用户一个一个的添加到界面的树节点上,同时向各用户发送Presence消息,用于Subscribe用户状态。问题就出现在Presence处理函数的注册、用户列表的加载、用户状态的订阅和更新的顺序上。

因为我首先注册了Presence处理函数,就意味着一旦用户的状态发生变化,处理函数就会找到界面中对于的树节点,然后更新节点的显示。而后面做的从服务器加载Roster,并将用户添加到用户树节点,并且添加节点过程中立即就订阅了用户的状态更新,就有可能在添加节点的过程中,就接收到用户状态更新的Presense消息,就会调用Presence处理函数更新界面,然而这时UI线程正忙于初始化用户列表呢,这样就造成了冲突,就导致UI线程的挂起,即“Application Hanging.”。

另外要注意的时,Presence处理函数所在的线程是非UI线程,但是要更新UI界面必须用UI线程更新,在wxPython中可以采用wx.CallAfter方法实现非UI线程更新UI界面。

找到问题所在,那么问题也就容易解决了:Presense处理函数的注册要放在用户列表初始化完成后,并且在订阅用户状态更新之前,那么创建用户列表界面时,就不能立即发送订阅请求,因为如果这时发生了,可能Presence处理函数还没有注册就已经收到Presence消息了。因此在初始化完用户界面后,再注册Presence处理函数,然后在给每一个用户发送订阅请求。

原创粉丝点击