您的位置:首页 > 运维架构

openfire服务端消息回执插件(接收方离线时的情况),判断用户的在线状态

2016-01-14 12:21 435 查看
该插件主要处理当接收方处于离线状态时,服务器端发送回执给客户端。工作原理是首先对消息进行拦截,判断消息类型为chat时,查询接收方是否在线,如果在线直接忽略,如果是离线状态,则将消息存放到离线消息列表,再对发送方进行回执。另一方面,在网络不稳定时,openfire容易出现掉包情况,原因是在客户端掉线,openfire并不能马上知道客户端已经断线。 为解决掉包问题,需要在客户端发消息时设置要求回执就行,然后在在服务器端发送回执给客户端,告诉客户端已经收到消息。

插件源碼如下:

/**
* 消息回执插件
* @author zjn
*/
public class MessageReceiptPlugIn implements Plugin, PacketInterceptor {

private static final Logger log = LoggerFactory.getLogger(MessageReceiptPlugIn.class);
private InterceptorManager interceptoerManager;

public MessageReceiptPlugIn() {
interceptoerManager = InterceptorManager.getInstance();
}

@Override
//初始化插件
public void initializePlugin(PluginManager manager, File pluginDirectory) {
interceptoerManager.addInterceptor(this);
System.out.println("初始化......加载插件成功!");
}

@Override
//服务器断开时销毁插件
public void destroyPlugin() {
interceptoerManager.removeInterceptor(this);
System.out.println("服务器断开......销毁插件成功!");
}

@SuppressWarnings("deprecation")
@Override
//消息拦截器
public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed)
throws PacketRejectedException {
System.out.println("接收到的消息内容:" + packet.toXML());
Packet copyPacket = packet.createCopy();
if (packet instanceof Message) {
Message message = (Message) copyPacket;
// 一对一聊天,单人模式,判断所拦截消息的类型为chat
if (message.getType() == Message.Type.chat) {
// 程序执行中;是否为结束或返回状态(是否是当前session用户发送消息)
if (processed || !incoming) {
return;
}
// 判断接受者是否在线,2代表离线状态,1代表在线状态,0代表用戶不存在
if (IsOnLineUtils.IsUserOnLine(message.getTo()) == 2) {
// 离线時,向offline表写数据
OfflineMessageStore offlineMessageStore = new OfflineMessageStore();
offlineMessageStore.addMessage(message);
// 向客户端发回执
Message receiptMessage = new Message();
receiptMessage.setTo(message.getFrom());
receiptMessage.setType(Message.Type.normal);
Element received = receiptMessage.addChildElement("received", "urn:xmpp:receipts");
received.setAttributeValue("id", message.getID());
System.out.println("0000000000回执内容" + receiptMessage);
try {
XMPPServer.getInstance().getPacketDeliverer().deliver(receiptMessage);
System.out.println("服务端回执成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}


以下是判断用户是否在线的方法:

public class IsOnLineUtils {
/**
* 判断openfire用户的状态 strUrl : url格式 -
* http://my.openfire.com:9090/plugins/presence/status?jid=user1@my.openfire * .com&type=xml 返回值 : 0 - 用户不存在; 1 - 用户在线; 2 - 用户离线 说明 :必须要求 openfire加载
* presence 插件,同时设置任何人都可以访问
*/
public final static String URL = "http://192.168.0.54:9090/plugins/presence/status?jid=";

public static short IsUserOnLine(JID jid) {
String strUrl = URL + jid + "&type=xml";
short shOnLineState = 0; // -不存在-
try {
URL oUrl = new URL(strUrl);
URLConnection oConn = oUrl.openConnection();
if (oConn != null) {
BufferedReader oIn = new BufferedReader(new InputStreamReader(oConn.getInputStream()));
if (null != oIn) {
String strFlag = oIn.readLine();
oIn.close();
if (strFlag.indexOf("type=\"unavailable\"") >= 0) {
shOnLineState = 2;
}
if (strFlag.indexOf("type=\"error\"") >= 0) {
shOnLineState = 0;
} else if (strFlag.indexOf("priority") >= 0 || strFlag.indexOf("id=\"") >= 0) {
shOnLineState = 1;
}
}
}
} catch (Exception e) {
}
return shOnLineState;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: