openfire服务端消息回执插件(接收方离线时的情况),判断用户的在线状态
2017-06-07 08:35
531 查看
openfire服务端消息回执插件(接收方离线时的情况),判断用户的在线状态
标签: openfire插件消息回执服务端在线状态2016-01-14 12:21 1472人阅读 评论(1) 收藏 举报
分类:
Openfire(2)
版权声明:本文为博主原创文章,未经博主允许不得转载。
该插件主要处理当接收方处于离线状态时,服务器端发送回执给客户端。工作原理是首先对消息进行拦截,判断消息类型为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(); } } } } } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
以下是判断用户是否在线的方法:
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; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
顶
相关文章推荐
- openfire服务端消息回执插件(接收方离线时的情况),判断用户的在线状态
- openfire服务端消息回执插件(接收方离线时的情况),判断用户的在线状态
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(九) 之 用 Redis 实现用户在线离线状态消息处理(一)
- 关于判断openfire 服务器中用户的在线状态问题
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(八) 之 用 Redis 实现用户在线离线状态消息处理
- openfire xmpp 如何判断用户是否在线
- 判断离线在线状态
- openfire插件最佳实践(四)离线消息推送ios服务器
- Js - 判断用户是否上网(连接网络) - HTML5在线、离线online的使用
- HTML5判断设备在线离线及监听网络状态变化例子
- OpenFire源码学习之二十五:消息回执与离线消息(下)
- openfire xmpp 通过presence service判断用户是否在线
- openfire插件最佳实践(四)离线消息推送ios服务器
- OpenFire源码学习之二十四:消息回执与离线消息(上)
- 可以用JS判断客服QQ号在线还是离线状态的程序
- 判断用户的在线状态 onbeforeunload事件
- smack+openfire插件实现广播。向所有在线用户发送消息。
- JS判断客服QQ号在线还是离线状态的方法
- 关于XMPP和openfire中的消息回执和聊天状态
- Mysql-之定时器调用存储过程(当用户超时未向服务端发送请求时更新用户状态为离线)