Smack实现添加好友(二):监听处理好友申请

要实现这一功能有些复杂。

概述

先来理解一些名词或概念吧:

roster:翻译为名册,我想就是好友的意思吧

Subscription:翻译为订阅,在深入了解samck的机制之前,可以理解为添加好友,就是“订阅一个好友”,或者“订阅一个名册”,收到好友申请,可以理解为“收到一个订阅请求”...

presence:用于两个目的:一是通知服务器用户的当前订阅状态,二是对于名册进行订阅和取消订阅

Stanza:翻译为“节”,基于XMPP Stanzas,XMPP Stanzas有Message, IQ and Presence。在这我先理解为Presence也是节的一种吧。

处理订阅消息流程

设置订阅模式->设置对于Presence包的监听(请求添加好友是通过发送Presence包实现的,所以一旦有好友申请,就能接收到Presence包;所以只要设置对Presence包的监听就好了)

①设置订阅处理模式

roster.setSubscriptionMode​(Roster.SubscriptionMode subscriptionMode)

默认模式为 Roster.SubscriptionMode.reject_all,表示自动拒绝所有订阅请求。
还可以设置为Roster.SubscriptionMode.accept_all,表示自动接收所有订阅和取消订阅请求。
也可以设置为Roster.SubscriptionMode.manual,则订阅请求被忽略,从而需要手工处理订阅请求。这意味着需要手动注册一个对于presence包(presence packets)的监听器,然后找到所有的类型为Presence.Type.SUBSCRIBE或Presence.Type.UNSUBSCRIBE的presence请求(presence requests)。

在这里,我们需要把处理模式设置为Roster.SubscriptionMode.manual

②添加对presence包的监听

在老版本中大概使用addPacketListener(PacketListener listener, PacketFilter filter)来监听包,在新版本中addPacketListener方法和PacketListener类已被弃用

 

 

 

 取而代之的是addAsyncStanzaListener​(StanzaListener packetListener, StanzaFilter packetFilter),针对连接,建立一个异步的stanza监听器

conn!!.addSyncStanzaListener(object:StanzaListener{
            override fun processStanza(packet: Stanza?) {
                //判断是Presence包的情况
                if(packet is Presence){
                    var presence:Presence=packet
                    if(presence.type==Presence.Type.subscribe){
                        println("收到来自${presence.from}的好友申请消息")
                    }else if(presence.type==Presence.Type.available){
                        println("收到${presence.from}上线消息")
                    }else if(presence.type==Presence.Type.unavailable){
                        println("收到${presence.from}下线消息")
                    }

                }
            }

        }, object:StanzaFilter{
            override fun accept(stanza: Stanza?): Boolean {
                //在这里可以设置对接收到的包进行过滤
                //如 return stanza is Presence,只返回Presence包
                //直接return true表示接收所有的包
                return true
            }

        })

presence.type是枚举常量,具体参考下图

 

 运行

需要两个模拟器吧。或者一个模拟器也行,因为登录的用户A也可以申请添加自己为好友,并且也能监听到presence消息。

如果是两个模拟器的话,就是一个模拟器登录用户A,另一个登录用户B。A请求添加B为好友。这样不可避免要做登录界面了...

 

posted @ 2021-01-02 15:06  vocus  阅读(509)  评论(0编辑  收藏  举报