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

2 篇文章 0 订阅
1 篇文章 0 订阅

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

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

        /**
         * 初始化会议室列表 <br>
         * 该列表数据为会议服务列表,一个会议服务包含N个会议室
         */  
        public List<HostedRoom> getHostRooms() {  
            if (getConnection() == null)  
                return null;  
            Collection<HostedRoom> hostrooms = null;  
            List<HostedRoom> roominfos = new ArrayList<HostedRoom>();  
            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<MyJoinedRoomIQ.Room> 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();
            /*<iq type="result" id="41V6J-7" to="libai@127.0.0.1/Smack">
             * <rooms xmlns="myjoinedroom">
             *     <room>
             *         <serviceId>1</serviceId>
             *         <name>新群3</name>
             *         <roomid>8</roomid>
             *         <nickName>libai</nickName>
             *         <memberJID>huaqiang@127.0.0.1</memberJID>
             *     </room>
             * </rooms>
             *</iq>*/
            return (result==null?new ArrayList<MyJoinedRoomIQ.Room>(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 "<query xmlns=\""+MyJoinedRoomIQ.nameSpace+"\" />";
    }

}


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

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

    @Override
    public String getChildElementXML() {
        StringBuilder buf = new StringBuilder();
        buf.append("<room xmlns=\"").append(MyJoinedRoomIQ.nameSpace).append("\"").append(">");
        synchronized (rooms) {
            for (Room r:rooms) {
                buf.append(r.toXml());
            }
        }
        buf.append("</room>");
        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("<room>")
            .append("<serviceId>").append(serviceId==null?"":StringUtils.escapeForXML(serviceId)).append("</serviceId>")
            .append("<name>").append(name==null?"":StringUtils.escapeForXML(name)).append("</name>")
            .append("<roomid>").append(roomid==null?"":StringUtils.escapeForXML(roomid)).append("</roomid>")
            .append("<nickName>").append(nickName==null?"":StringUtils.escapeForXML(nickName)).append("</nickName>")
            .append("<memberJID>").append(memberJID==null?"":StringUtils.escapeForXML(memberJID)).append("</memberJID>")
            .append("</room>");
            
            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<Room> getRooms() {
        return rooms;
    }
    
    public void addRooms(List<Room> 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<Node> iter = iqele.nodeIterator();
            boolean flag = false;
            while(iter.hasNext()){
                Node node = iter.next();
                flag = node.asXML().contains("<query xmlns=\"myjoinedroom\"");
                if(flag)break;
            }
            if(!flag)return;
            //获取该用户的所有群组返回
            /*<iq from='macbeth.shakespeare.lit' id='disco2' to='hag66@shakespeare.lit/pda' type='result'>
              <rooms xmlns='myjoinedroom'>
                  <room>
                    <jid>1</jid>
                    <name>sadfsad@sdf.sdf</name>

                    ........

                  </room>
              </rooms>
            </iq>
            */
            IQ responseIQ = new IQ(org.xmpp.packet.IQ.Type.result,iq.getID());
            responseIQ.setTo(fromJID);
            Element queryEle = responseIQ.setChildElement("rooms", "myjoinedroom");
            List<Map<String, String>> mucs = getMUCInfo(fromJID.toBareJID());
            if(mucs!=null && mucs.size()>0){
                Element itemEle = null;
                for (Map<String, String> 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<Map<String, String>> getMUCInfo(String jid) {  
        List<Map<String, String>> list = new ArrayList<Map<String, String>>();  
        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<String, String> map = null;  
        try {  
            connection = DbConnectionManager.getConnection();  
            statement = connection.prepareStatement(sql);  
            statement.setString(1, jid);  
            resultSet = statement.executeQuery();  
            while (resultSet.next()) {
                map = new HashMap<String, String>();
                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通过自定义协议获取当前用户的群代码完毕。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值