也就是服务器端的开发,扩展的协议,需要在服务器端处理。比如送礼物的协议,需要保存用户发送礼物的记录,并且判断用户是否有足够的礼物发送。部分代码记录如下。
- 扩展IQHandler的模板
package com.xxxx.openfire.handler; import java.awt.TrayIcon.MessageType; import org.jivesoftware.openfire.IQHandlerInfo; import org.jivesoftware.openfire.PacketException; import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.auth.UnauthorizedException; import org.jivesoftware.openfire.handler.IQHandler; import org.jivesoftware.openfire.muc.ForbiddenException; import org.jivesoftware.openfire.muc.MUCRole; import org.jivesoftware.openfire.muc.MUCRoom; import org.jivesoftware.openfire.muc.MultiUserChatService; import org.jivesoftware.openfire.user.UserNotFoundException; import org.xmpp.packet.IQ; import org.xmpp.packet.IQ.Type; import org.xmpp.packet.JID; import org.xmpp.packet.Message; import org.xmpp.packet.PacketError; import org.xmpp.packet.PacketExtension; import com.rayclear.openfire.database.DataManager; import de.javawi.jstun.attribute.MessageAttributeInterface.MessageAttributeType; public class XXXXHandler extends IQHandler { private IQHandlerInfo info; private static final String MODULE_NAME = "xxx handler"; private static final String NAME_SPACE = "xxx:xxxx:gift"; public RayclearHandler(String moduleName) { super(MODULE_NAME); info = new IQHandlerInfo("query", NAME_SPACE); } @Override public IQ handleIQ(IQ packet) throws UnauthorizedException { return reply; } @Override public IQHandlerInfo getInfo() { return info; } }
- 在route里注册
注册到route链里,就可以 抓取与命名空间匹配的packet了IQHandler myHandler = new xxxxHandler("xxxx"); IQRouter iqRouter = XMPPServer.getInstance().getIQRouter(); iqRouter.addHandler(myHandler);
- 取得请求的iq节点
packet可以取得来自与请求的element元素Element groups = packet.getChildElement(); Element childElement = packet.getChildElement(); String namespace = childElement.getNamespaceURI(); Element childElementCopy = packet.getChildElement().createCopy(); final String toUser = groups.elementText("host").split("@")[0]
- 设置返回的节点
由请求方的packet生成回复的packet-IQ reply = IQ.createResultIQ(packet); reply.setType(IQ.Type.error); Element reason = DocumentHelper.createElement("reason"); reason.addNamespace("", NAME_SPACE); reason.setText("no"); reply.setChildElement(reason);
- 处理请求后,将消息发送到房间
String roomjid = "song@conference.192.168.1.126"; JID rJid = new JID(roomjid); MultiUserChatService chatService = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(rJid); MUCRoom room = chatService.getChatRoom(rJid.getNode()); //room.send(reply); org.xmpp.packet.Message message = new org.xmpp.packet.Message(); message.setTo(roomjid); message.setBody("给张飞送花了哦,数量共一朵~"); message.setType(Message.Type.groupchat); MUCRole senderRole; try { senderRole = room.getOccupant("tester001"); room.sendPublicMessage(message, senderRole); } catch (UserNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ForbiddenException e) { // TODO Auto-generated catch block e.printStackTrace(); }
MultiUserChatService : 群组聊天服务,有一系列的服务方法 MUCRoom: 房间类,有取的房间信息和向房间发送消息的方法 MUCRole: 用户角色,发送消息等需要
- 如何遍历房间中的所有用户,并使用他们发送消息?
if (room != null) { //改方法,是每个人都发一条信息,显然不行 for (MUCRole role : room.getOccupants()) { try { room.sendPublicMessage(message, role); } catch (ForbiddenException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }