码迷,mamicode.com
首页 > 其他好文 > 详细

openfire client聊天消息交互和存储离线(在线)消息记录策略

时间:2016-07-19 10:16:10      阅读:864      评论:0      收藏:0      [点我收藏+]

标签:

【0】如何将离线消息存档,且在接收者上线之后,推送消息到接收者
发送方发送消息 -> 检测接收方是否在线 ->
-> y -> 发送在线消息 -> 发送成功后,存档到消息记录;
-> n -> 修改数据包(XML流) 发送离线消息 ->  存档到消息记录 -> 不断检测某离线消息的接收方是否在线
-> y -> 推送离线消息记录(未读)到 刚刚登陆的离线用户;
-> n -> 继续检测;

【1】消息交互
1)intro:  以下消息内容
是小生我从 smack client 发送 消息(hello, abcdefg) 和另外一个 client 与 的 消息交互情况; 
2)接收方离线和发送方在线,而后接收方在线的情况
Attention)incoming(true->sender,false->receiver), processed(true->after processed, false->before processed)
step1)发送msg时,接收者离线;(openfire处理前)
<message to="tangtang@lenovo-pc" id="8akb9-36" type="chat" from="pacoson@lenovo-pc/Smack"><body>hello, abcdefg</body><thread>1d5f0c93-4eb6-4461-a09a-0da6fc9d3ac6</thread></message>
org.jivesoftware.openfire.session.LocalClientSession@1960f3cb status: 3 address: pacoson@lenovo-pc/Smack id: 8vqkiso6gv presence: 
<presence id="8akb9-34" from="pacoson@lenovo-pc/Smack">
  <c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://www.igniterealtime.org/projects/smack" ver="os2Kusj3WEOivn5n4iFr/ZEO8ls="/>
</presence>
incoming = true, processed = false
step2)发送msg时,接收者离线;(openfire处理后)
<message to="tangtang@lenovo-pc" id="8akb9-36" type="chat" from="pacoson@lenovo-pc/Smack"><body>hello, abcdefg</body><thread>1d5f0c93-4eb6-4461-a09a-0da6fc9d3ac6</thread></message>
org.jivesoftware.openfire.session.LocalClientSession@1960f3cb status: 3 address: pacoson@lenovo-pc/Smack id: 8vqkiso6gv presence: 
<presence id="8akb9-34" from="pacoson@lenovo-pc/Smack">
  <c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://www.igniterealtime.org/projects/smack" ver="os2Kusj3WEOivn5n4iFr/ZEO8ls="/>
</presence>
incoming = true, processed = true
Attention)
A1)以上就是当发送者在线,而接收者离线的openfire消息记录;
A2)以下是 接收者登录后的 openifre 消息记录;

step3)接收者登录在线(openfire处理前)
<message to="tangtang@lenovo-pc" id="8akb9-36" type="chat" from="pacoson@lenovo-pc/Smack"><body>hello, abcdefg</body><thread>1d5f0c93-4eb6-4461-a09a-0da6fc9d3ac6</thread><delay xmlns="urn:xmpp:delay" from="lenovo-pc" stamp="2016-07-18T00:39:29.759Z"/></message>
org.jivesoftware.openfire.session.LocalClientSession@46cc3cbd status: 3 address: tangtang@lenovo-pc/Smack id: 4qrph1nzci presence: 
<presence id="2h2Pk-7" from="tangtang@lenovo-pc/Smack">
  <c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://www.igniterealtime.org/projects/smack" ver="os2Kusj3WEOivn5n4iFr/ZEO8ls="/>
</presence>
incoming = false, processed = false
step4)接收者登录在线(openfire处理后)
<message to="tangtang@lenovo-pc" id="8akb9-36" type="chat" from="pacoson@lenovo-pc/Smack"><body>hello, abcdefg</body><thread>1d5f0c93-4eb6-4461-a09a-0da6fc9d3ac6</thread><delay xmlns="urn:xmpp:delay" from="lenovo-pc" stamp="2016-07-18T00:39:29.759Z"/></message>
org.jivesoftware.openfire.session.LocalClientSession@46cc3cbd status: 3 address: tangtang@lenovo-pc/Smack id: 4qrph1nzci presence: 
<presence id="2h2Pk-7" from="tangtang@lenovo-pc/Smack">
  <c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://www.igniterealtime.org/projects/smack" ver="os2Kusj3WEOivn5n4iFr/ZEO8ls="/>
</presence>
incoming = false, processed = true
Conclusion)openfire 对离线消息的处理: 当接收者不在线的时候,openfire 会把 msg 存储到 ofoffline 这个数据库表中;当 接收者登录在线后,openfire 会把该消息push 给 接收者,因而接收者在线后接受 openfire 推送的离线消息 后,会发送 响应消息(参见session 的 from 元素值);之后openfire 会将该消息从 ofoffline 表中清空(即时删除已经发送到用户的离线消息);
技术分享

3)接收方和发送方都在线的情况
step1)发送方发送消息(处理前)
<message to="tangtang@lenovo-pc" id="8akb9-76" type="chat" from="pacoson@lenovo-pc/Smack"><body>i am a student.</body><thread>20b6bc6b-64b8-4cc8-a58c-c416090ae1bc</thread></message>
org.jivesoftware.openfire.session.LocalClientSession@647c5490 status: 3 address: pacoson@lenovo-pc/Smack id: 30glj4xlhu presence: 
<presence id="8akb9-72" from="pacoson@lenovo-pc/Smack">
  <c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://www.igniterealtime.org/projects/smack" ver="os2Kusj3WEOivn5n4iFr/ZEO8ls="/>
</presence>
incoming = true, processed = false
step2)接收方接收消息(处理前)
<message to="tangtang@lenovo-pc" id="8akb9-76" type="chat" from="pacoson@lenovo-pc/Smack"><body>i am a student.</body><thread>20b6bc6b-64b8-4cc8-a58c-c416090ae1bc</thread></message>
org.jivesoftware.openfire.session.LocalClientSession@32e2ab29 status: 3 address: tangtang@lenovo-pc/Smack id: 3t4gvqjm80 presence: 
<presence id="ZvrMI-7" from="tangtang@lenovo-pc/Smack">
  <c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://www.igniterealtime.org/projects/smack" ver="os2Kusj3WEOivn5n4iFr/ZEO8ls="/>
</presence>
incoming = false, processed = false
step3)接收方接收消息(处理后)
<message to="tangtang@lenovo-pc" id="8akb9-76" type="chat" from="pacoson@lenovo-pc/Smack"><body>i am a student.</body><thread>20b6bc6b-64b8-4cc8-a58c-c416090ae1bc</thread></message>
org.jivesoftware.openfire.session.LocalClientSession@32e2ab29 status: 3 address: tangtang@lenovo-pc/Smack id: 3t4gvqjm80 presence: 
<presence id="ZvrMI-7" from="tangtang@lenovo-pc/Smack">
  <c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://www.igniterealtime.org/projects/smack" ver="os2Kusj3WEOivn5n4iFr/ZEO8ls="/>
</presence>
incoming = false, processed = true
step4)发送方发送消息(处理后)
<message to="tangtang@lenovo-pc" id="8akb9-76" type="chat" from="pacoson@lenovo-pc/Smack"><body>i am a student.</body><thread>20b6bc6b-64b8-4cc8-a58c-c416090ae1bc</thread></message>
org.jivesoftware.openfire.session.LocalClientSession@647c5490 status: 3 address: pacoson@lenovo-pc/Smack id: 30glj4xlhu presence: 
<presence id="8akb9-72" from="pacoson@lenovo-pc/Smack">
  <c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://www.igniterealtime.org/projects/smack" ver="os2Kusj3WEOivn5n4iFr/ZEO8ls="/>
</presence>
incoming = true, processed = true

Conclusion) 
C1)我们发现,不管是发送在线消息 还是 离线消息,在openfire 处理前后,都可以对消息进行拦截;
C2)根据以上打印info,我们计划在 incoming = true, processed = true 的case下 存储消息记录;
C3) 如果接收方成功接收消息后(incoming = false, processed = true),我们存储在线消息,有且仅在该case下存储消息到 ofchatlog 数据库表;如果没有接收方的响应信息(incoming 始终等于true,即session.jsi 始终是 发送者,没有接收者,表明接收者离线),openfire会存储离线消息; 当离线的接收者登录后,openfire 推送离线消息给 该接收者(参见“2->step3,step4”的交互消息步骤),我们就在 incoming = false, processed = true的case下 将该消息转储到到 ofchatlog;
C4)一句话说完,我们的ChatLog 插件 涉及的 ofchatlog 数据库表 只存储 在线消息,而离线消息存储在 ofoffline(owned by openfire);所以当接收者离线的时候,离线消息不会存储到 ofchatlog,而是会存储到 ofoffline,离线用户登录后,会将 消息从 ofoffline 转储到 ofchatlog;
<pre name="code" class="java">public class ChatlogPlugin implements PacketInterceptor, Plugin {

	private static final Logger log = LoggerFactory.getLogger(ChatlogPlugin.class);
	private static PluginManager pluginManager;
	private static ChatlogManager logsManager;
	// Hook for intercpetorn
	private InterceptorManager interceptorManager;
	private PresencePlugin presencePlugin;
	
	public ChatlogPlugin() {
		interceptorManager = InterceptorManager.getInstance();
		logsManager = ChatlogManager.getInstance();
	}

	/**
	 * <b>function:</b> 拦截消息核心方法,Packet就是拦截消息对象
	 */
	@Override
	public void interceptPacket(Packet packet, Session session,
			boolean incoming, boolean processed) throws PacketRejectedException {
		Packet copyPacket = packet.createCopy();
		
		if (packet instanceof Message) {
			Message message = (Message) copyPacket;
			System.out.println(message.toXML());
			System.out.println(session);
			System.out.println("incoming = " + incoming + ", processed = " + processed);
			if (message.getType() == Message.Type.chat) { // 一对一聊天,单人模式
				if (!incoming && processed) { // 有且仅在该case下,存储在线消息(或转储离线消息->chatlog 数据库表)
					logsManager.insert(buildChatlog(packet, incoming, session));
				} else {
					return ;
				}

openfire client聊天消息交互和存储离线(在线)消息记录策略

标签:

原文地址:http://blog.csdn.net/pacosonswjtu/article/details/51939013

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!