smack+openfire自定义协议获取当前用户加入的群

openfire服务端采用http://blog.csdn.net/yangzl2008/article/details/16991175#t4提到的方法解决会议室中人员持久化问题。

smack端,首先获取服务器所有会议服务:

        /**
         * 初始化会议室列表

         * 该列表数据为会议服务列表,一个会议服务包含N个会议室
         */  
        public List getHostRooms() {  
            if (getConnection() == null)  
                return null;  
            Collection hostrooms = null;  
            List roominfos = new ArrayList();  
            try {
                ServiceDiscoveryManager.getInstanceFor(getConnection());
                hostrooms = MultiUserChat.getHostedRooms(getConnection(),  
                        getConnection().getServiceName());  
                for (HostedRoom entry : hostrooms) {  
                    roominfos.add(entry);  
                    Log.i("room",   "name:" + entry.getName() + " - ID:" + entry.getJid()); 
                }  
                Log.i("room", "服务会议数量:" + roominfos.size());  
            } catch (XMPPException e) {  
                e.printStackTrace();  
            }  
            return roominfos;  
        }

然后根据选定的会议服务jid,发送自定义请求来获取该会议服务下当前用户所在的群组:

public List getMyRoomItems(){
            //构建自定义协议,查询我加入的房间
            MyJoinedRoomRequestIQ iq = new MyJoinedRoomRequestIQ(getConferenceHostRooms().getJid());
            // Create a packet collector to listen for a response.
            PacketCollector collector =
                getXmppConnection().createPacketCollector(new PacketIDFilter(iq.getPacketID()));
            getXmppConnection().sendPacket(iq);
            // Wait up to 5 seconds for a result.
            MyJoinedRoomIQ result = (MyJoinedRoomIQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
            // Stop queuing results
            collector.cancel();
            /*
             *
             *     
             *         1
             *         新群3
             *         8
             *         libai
             *         [email protected]
             *     

             *

             *
*/
            return (result==null?new ArrayList(0):result.getRooms());
        }


自定义请求类MyJoinedRoomRequestIQ如下:

public class MyJoinedRoomRequestIQ extends IQ{

    public MyJoinedRoomRequestIQ(String toJID) {
        super();
        setTo(toJID);
        setType(IQ.Type.GET);
        setPacketID(Packet.nextID());
    }
    
    @Override
    public String getChildElementXML() {
        return "";
    }

}


接收服务端响应类MyJoinedRoomIQ如下:

public class MyJoinedRoomIQ extends IQ {
    public static final String elementName="rooms";
    public static final String nameSpace="myjoinedroom";
    
    private final List rooms = new CopyOnWriteArrayList();

    @Override
    public String getChildElementXML() {
        StringBuilder buf = new StringBuilder();
        buf.append("");
        synchronized (rooms) {
            for (Room r:rooms) {
                buf.append(r.toXml());
            }
        }
        buf.append("
");
        return buf.toString();
    }

    public static class Room implements Serializable{
        private static final long serialVersionUID = 2488520282455672273L;
        String serviceId;
        String name;
        String roomid;
        String nickName;
        String memberJID;

        public String toXml() {
            StringBuilder buf = new StringBuilder();
            buf.append("")
            .append("").append(serviceId==null?"":StringUtils.escapeForXML(serviceId)).append("")
            .append("").append(name==null?"":StringUtils.escapeForXML(name)).append("")
            .append("").append(roomid==null?"":StringUtils.escapeForXML(roomid)).append("")
            .append("").append(nickName==null?"":StringUtils.escapeForXML(nickName)).append("")
            .append("").append(memberJID==null?"":StringUtils.escapeForXML(memberJID)).append("")
            .append("
");
            
            return buf.toString();
        }

        public String getServiceId() {
            return serviceId;
        }

        public void setServiceId(String serviceId) {
            this.serviceId = serviceId;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getRoomid() {
            return roomid;
        }

        public void setRoomid(String roomid) {
            this.roomid = roomid;
        }

        public String getNickName() {
            return nickName;
        }

        public void setNickName(String nickName) {
            this.nickName = nickName;
        }

        public String getMemberJID() {
            return memberJID;
        }

        public void setMemberJID(String memberJID) {
            this.memberJID = memberJID;
        }
    }

    public List getRooms() {
        return rooms;
    }
    
    public void addRooms(List rooms){
        rooms.addAll(rooms);
    }
    
    public void addRoom(Room room){
        rooms.add(room);
    }

}

在smack的连接配置中,必须配置以下Provider
ProviderManager.getInstance().addIQProvider(MyJoinedRoomIQ.elementName, MyJoinedRoomIQ.nameSpace, new MyJoinedRoomProvider());

MyJoinedRoomProvider的定义如下:

public class MyJoinedRoomProvider implements IQProvider{

    public IQ parseIQ(XmlPullParser parser) throws Exception {
        MyJoinedRoomIQ rooms = new MyJoinedRoomIQ();
        boolean done = false;
        MyJoinedRoomIQ.Room room=null;
        String serviceId="",name="",roomid="",nickName="",memberJID="";
        while (!done) {
            int eventType = parser.next();
            switch (eventType) {
            case XmlPullParser.START_TAG:
                if(parser.getName().equals("serviceId")){
                    serviceId=parser.nextText();
                }
                if(parser.getName().equals("name")){
                    name=parser.nextText();
                }
                if(parser.getName().equals("roomid")){
                    roomid=parser.nextText();
                }
                if(parser.getName().equals("nickName")){
                    nickName=parser.nextText();
                }
                if(parser.getName().equals("memberJID")){
                    memberJID=parser.nextText();
                }
                break;
            case XmlPullParser.END_TAG:
                if("room".equals(parser.getName())){
                    room = new MyJoinedRoomIQ.Room();
                    room.setServiceId(serviceId);
                    room.setName(name);
                    room.setNickName(nickName);
                    room.setRoomid(roomid);
                    room.setMemberJID(memberJID);
                    rooms.addRoom(room);
                }else if("rooms".equals(parser.getName())){
                    done=true;
                }
                break;
            }
        }
        return rooms;
    }
}


客户端配置完毕。

服务端需要插件来对接收到的请求做处理并响应给客户端,插件如下:


public class MUCExpand implements Plugin,PacketInterceptor{
    private static final Logger log = LoggerFactory.getLogger(MUCExpand.class);
    
    private XMPPServer server;
    
    @Override
    public void initializePlugin(PluginManager manager, File pluginDirectory) {
        InterceptorManager.getInstance().addInterceptor(this);
        server = XMPPServer.getInstance();
    }

  
    @Override
    public void interceptPacket(Packet packet, Session session,
            boolean incoming, boolean processed) throws PacketRejectedException {
        if (incoming && processed && packet instanceof IQ) {
            JID fromJID = packet.getFrom();
            if (fromJID == null)return;
            JID jid=null;
            if((jid=packet.getTo())==null)return;
            if(jid.getDomain()==null || !jid.getDomain().startsWith("conference"))return;
            IQ iq = (IQ) packet;
            if(!iq.getType().equals(org.xmpp.packet.IQ.Type.get))return;
            Element iqele = iq.getElement();
            Iterator iter = iqele.nodeIterator();
            boolean flag = false;
            while(iter.hasNext()){
                Node node = iter.next();
                flag = node.asXML().contains("                 if(flag)break;
            }
            if(!flag)return;
            //获取该用户的所有群组返回
            /*
             
                  
                    1
                    [email protected]

                    ........

                 
             
            
            */
            IQ responseIQ = new IQ(org.xmpp.packet.IQ.Type.result,iq.getID());
            responseIQ.setTo(fromJID);
            Element queryEle = responseIQ.setChildElement("rooms", "myjoinedroom");
            List> mucs = getMUCInfo(fromJID.toBareJID());
            if(mucs!=null && mucs.size()>0){
                Element itemEle = null;
                for (Map map : mucs) {
                    itemEle=queryEle.addElement("room");
                    itemEle.addElement("serviceId").setText(map.get("serviceId"));
                    itemEle.addElement("name").setText(map.get("roomName"));
                    itemEle.addElement("roomid").setText( map.get("roomid"));
                    itemEle.addElement("nickName").setText( map.get("nickName"));
                    itemEle.addElement("memberJID").setText( map.get("memberJID"));
                }
            }
            
            server.getRoutingTable().routePacket(fromJID, responseIQ, true);
            System.out.println("响应给["+fromJID.toString()+"]群组:"+responseIQ.toXML());
        }        
    }
    
    public List> getMUCInfo(String jid) {  
        List> list = new ArrayList>();  
        String sql = "select ofmucroom.serviceID, ofmucroom.name, ofmucroom.roomid ,ofmucmember.nickname,ofmucmember.jid from ofmucroom join ofmucmember on ofmucroom.roomID = ofmucmember.roomID and ofmucmember.jid = ?";  
        Connection connection = null;  
        PreparedStatement statement = null;  
        ResultSet resultSet = null;  
        Map map = null;  
        try {  
            connection = DbConnectionManager.getConnection();  
            statement = connection.prepareStatement(sql);  
            statement.setString(1, jid);  
            resultSet = statement.executeQuery();  
            while (resultSet.next()) {
                map = new HashMap();
                map.put("serviceId", resultSet.getString(1)==null?"":resultSet.getString(1));  
                map.put("roomName", resultSet.getString(2)==null?"":resultSet.getString(2));  
                map.put("roomid", resultSet.getString(3)==null?"":resultSet.getString(3));  
                map.put("nickName", resultSet.getString(4)==null?"":resultSet.getString(4));  
                map.put("memberJID", resultSet.getString(5)==null?"":resultSet.getString(5));  
                list.add(map);  
            }  
        } catch (Exception e1) {  
            e1.printStackTrace();
            log.error(e1.getMessage());
        } finally {  
            DbConnectionManager.closeConnection(resultSet, statement,  
                    connection);  
        }  
        return list;  
    }

    @Override
    public void destroyPlugin() {
        // TODO Auto-generated method stub
        
    }  
}

至此,smack通过自定义协议获取当前用户的群代码完毕。


你可能感兴趣的:(SMACK,XMPP,JAVA,OPENFIRE,JAVA,SMACK,XMPP,OPENFIRE,自定义xmpp协议)