openfire服务端采用http://blog.csdn.net/yangzl2008/article/details/16991175#t4提到的方法解决会议室中人员持久化问题。
smack端,首先获取服务器所有会议服务:
/**
* 初始化会议室列表
* 该列表数据为会议服务列表,一个会议服务包含N个会议室
*/
public List
if (getConnection() == null)
return null;
Collection
List
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
//构建自定义协议,查询我加入的房间
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();
/*
*
*
*
*
*
*
*
*
*
*
return (result==null?new ArrayList
}
自定义请求类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
@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("
.append("
.append("
.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
return rooms;
}
public void addRooms(List
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
boolean flag = false;
while(iter.hasNext()){
Node node = iter.next();
flag = node.asXML().contains("
}
if(!flag)return;
//获取该用户的所有群组返回
/*
........
*/
IQ responseIQ = new IQ(org.xmpp.packet.IQ.Type.result,iq.getID());
responseIQ.setTo(fromJID);
Element queryEle = responseIQ.setChildElement("rooms", "myjoinedroom");
List
至此,smack通过自定义协议获取当前用户的群代码完毕。