现在的位置: 首页 > java > spark > 正文
openfire spark smack几个源码分析,packfilter的使用方法
2012年06月07日 spark ⁄ 共 7578字 暂无评论

一些看smack时的笔记东西,和实现基本功能的源码,包括添加好友,创建群,接受邀请,聊天等,业务逻辑和UI分离

一、注册
Registration reg = new Registration();
reg.setType(IQ.Type.SET);
reg.setTo(ConnectionUtils.getConnection()
                                .getServiceName());
reg.setUsername(phoneCode.getText().toString());
reg.setPassword(passwd);
reg.addAttribute("android", "geolo_createUser_android");
PacketFilter filter = new AndFilter(new PacketIDFilter(
                                reg.getPacketID()), new PacketTypeFilter(
                                IQ.class));
PacketCollector collector = ConnectionUtils.getConnection().
createPacketCollector(filter);
ConnectionUtils.getConnection().sendPacket(reg);
result = (IQ) collector.nextResult(SmackConfiguration
                                .getPacketReplyTimeout());
                        // Stop queuing results
collector.cancel();// 停止请求results(是否成功的结果)
if (result == null) {
Toast.makeText(getApplicationContext(), "服务器没有返回结果", Toast.LENGTH_SHORT).show();
} else if (result.getType() == IQ.Type.ERROR) {
if (result.getError().toString()
                        .equalsIgnoreCase("conflict(409)")) {
    Toast.makeText(getApplicationContext(), "这个账号已经存在", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(getApplicationContext(), "注册失败",
                                        Toast.LENGTH_SHORT).show();
    }
} else if (result.getType() == IQ.Type.RESULT) {
Toast.makeText(getApplicationContext(), "恭喜你注册成功", Toast.LENGTH_SHORT).show();
}
二、登陆
// 无连接
if (!ConnectionUtils.getConnection().isConnected())
                        return false;
if (ConnectionUtils.getConnection().isAuthenticated()) {
                        return true;
} else {
// 用户登录
ConnectionUtils.getConnection().login(
util.getString("userCode", ""),util.getString("passwd", ""));
return ConnectionUtils.getConnection().isAuthenticated();
}
三、发送用户状态
Presence presence = new Presence(Presence.Type.available);
presence.setStatus("Gone fishing");
ConnectionUtils.getConnection().sendPacket(presence);

四、检索信息
Smack提供以下两种方法阅读收到的信息包:PacketListener和PacketCollector。它们都使用PacketFilter的实例来决定应该处理哪个信息包。信息包*********(packet listener)用于事件类型的设计,而信息包收集器(packet collector)有一个信息包的结果队列,你可以对其实施polling和blocking操作。所以,信息包*********在你收到任何一个信息包,且你想对其进行操作时是有用的,而信息包收集器在你想等待某个特殊的信息包时是有用的。信息包收集器和*********可以通过XMPPConnection的实例来创建。
、PacketListener
PacketFilter packetFilter = new AndFilter(new PacketIDFilter(
                    jp.getPacketID()), new PacketTypeFilter(IQ.class));
            // 监听所有的包
            con.addPacketListener(new PacketListener() {
                public void processPacket(Packet packet) {
                    if (packet instanceof MyIQ) {
                        MyIQ iq = (MyIQ) packet;
                        if (iq.getType() == IQ.Type.RESULT) {
                            System.out.println("返回内容: "
                                    + iq.toXML());
                        }
                    } else {
                        System.out.println("其他消息:"+packet.toXML());
                    }
                }
            }, packetFilter);
、PacketCollector
    PacketFilter filter = new AndFilter(new PacketIDFilter(
                                reg.getPacketID()), new PacketTypeFilter(
                                IQ.class));
    PacketCollector collector = ConnectionUtils
    .getConnection().createPacketCollector(filter);
    ConnectionUtils.getConnection().sendPacket(reg);
    result = (IQ) collector.nextResult(SmackConfiguration
                                .getPacketReplyTimeout());

 
五、添加一个好友
        /**
         * The user and subscriber have no interest in each other's presence.
         */
        none,
none:是用户和自己roster中的好友彼此不关心,既不想把自己的presence状态告诉对方,也不愿意收到对方presence更新消息

        /**
         * The user is interested in receiving presence updates from the subscriber.
         */
        to,
to:是关心roster中好友的presence状态消息,而不将自己的消息告诉对方

        /**
         * The subscriber is interested in receiving presence updates from the user.
         */
        from,
from:是只关心,接受对方的状态消息,而不将自己的消息告诉对方

        /**
         * The user and subscriber have a mutual interest in each other's presence.
         */
        both,
both:即收取对方状态更新,又将自己的更新告知对方
        /**
         * The user wishes to stop receiving presence updates from the subscriber.
         */
        remove
Remove :将对方干掉,不再关心他的任何信息。

在申请添加一个好友,当对方Roster.setDefaultSubscriptionMode(SubscriptionMode.manual)时,此时添加的好友为“挂起”状态。对方设置监听PacketFilter filter = new PacketFilter() {

            @Override
            public boolean accept(Packet packet) {
                if (packet instanceof Presence) {
                    Presence presence = (Presence) packet;
                    if (presence.getType().equals(Presence.Type.subscribe)) {
                        return true;
                    }
                }
                return false;
            }
        };
允许添加好友则回复消息Presence presence = new Presence(Presence.Type.subscribed);
            presence.setTo(packet.getFrom());
            ConnectionUtils.getConnection().sendPacket(presence);
此时邀请人的好友状态为to。而被添加的user的subscription状态为from。如果要改为both。Both users need to subscribe to each other and accept the subscription request they received.
被邀请人应当也发送一个邀请请求。
Presence subscription = new Presence(Presence.Type.subscribe);
            subscription.setTo(packet.getFrom());
            ConnectionUtils.getConnection().sendPacket(subscription);

六、设置昵称nickname
    RosterEntry entry = connection.getRoster().getEntry(user.getJID());
    entry.setName(nickname);这个方法会设置昵称自动发送给服务器,服务器修改后会发布一个update操作。

七、组添加或删除成员
    添加一个好友到组,当组存在时,添加到当前存在组,不存在时则先创建一个组,再将好友添加进去,如果从组中删除一个好友,如果当前好友是组成员最后一个,则同时删除组。
/**
     * 把一个好友添加到一个组中
     *
     * @param user
     * @param groupName
     */
    public static void addUserToGroup(final User user, final String groupName,
            final XMPPConnection connection) {
        if (groupName == null || user == null)
            return;
        // 将一个rosterEntry添加到group中是PacketCollector,会阻塞线程
        new Thread() {
            public void run() {
RosterGroup group = connection.getRoster().getGroup(groupName);
                // 这个组已经存在就添加到这个组,不存在创建一个组
                RosterEntry entry = connection.getRoster().getEntry(
                        user.getJID());
                try {
                    if (group != null) {
                        if (entry != null)
                            group.addEntry(entry);
                    } else {
                        RosterGroup newGroup = connection.getRoster()
                                .createGroup(groupName);
                        if (entry != null)
                            newGroup.addEntry(entry);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    /**
     * 把一个好友从组中删除
     *
     * @param user
     * @param groupName
     */
    public static void removeUserFromGroup(final User user,
            final String groupName, final XMPPConnection connection) {
        if (groupName == null || user == null)
            return;
        new Thread() {
            public void run() {
RosterGroup group = connection.getRoster().getGroup(groupName);
                if (group != null) {
                    try {
RosterEntry entry = connection.getRoster().getEntry(
                                user.getJID());
                        if (entry != null)
                            group.removeEntry(entry);
                    } catch (XMPPException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

八、申请创建联系人
    public void createEntry(String user, String name, String[] groups)
    发送一个Presence.Type.subscribe邀请请求。

九、删除联系人
    public void removeEntry(RosterEntry entry)

十、创建chat
    每个chat对应一个线程,所有的线程都保存在ChatManager.threadChats中。Chat在ChatManager.jidChats中以jid为key保存,在ChatManager.baseJidChats中以Jid的@前半部分保存。
    获得chat的方法:
        public Chat getThreadChat(String thread)

 

packetfilter 是个interface ,主要的实现类有AndFilter, FromContainsFilter, FromMatchesFilter, IQTypeFilter, MessageTypeFilter, NotFilter, OrFilter, PacketExtensionFilter, PacketIDFilter, PacketTypeFilter, ThreadFilter, ToContainsFilter

给我留言

您必须 [ 登录 ] 才能发表留言!

×