openfire聊天消息记录插件关键代码
package com.sqj.openfire.chat.logs; import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID; import org.apache.commons.lang.StringUtils;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.jivesoftware.openfire.OfflineMessageStore;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.interceptor.InterceptorManager;
import org.jivesoftware.openfire.interceptor.PacketInterceptor;
import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.openfire.user.UserManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.Packet;
import org.xmpp.packet.Presence; import com.sqj.openfire.chat.logs.entity.Chat;
import com.sqj.openfire.chat.logs.entity.XmlToMap; /** <b>function:</b> 聊天记录插件
* @author shm
* @createDate 2016-3-14
* @version 1.0
*/
public class ChatLogsPlugin implements PacketInterceptor, Plugin {
private static final Logger log = LoggerFactory.getLogger(ChatLogsPlugin.class);
private static PluginManager pluginManager;
private static DbChatLogsManager logsManager;
private InterceptorManager interceptorManager; public ChatLogsPlugin()
{
this.interceptorManager = InterceptorManager.getInstance();
logsManager = DbChatLogsManager.getInstance();
} /**
* * <b>function:</b> 拦截消息核心方法,Packet就是拦截消息对象
* * @author shm
* * @createDate 2016-3-14
* */
@Override
public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed) throws PacketRejectedException {
if (session != null) {
//debug(packet, incoming, processed, session);
}
JID recipient = packet.getTo();
if (recipient != null) {
String username = recipient.getNode();
// 广播消息或是不存在/没注册的用户.
if (username == null || !UserManager.getInstance().isRegisteredUser(recipient)) {
return;
} else if (!XMPPServer.getInstance().getServerInfo().getXMPPDomain().equals(recipient.getDomain())) {
// 非当前openfire服务器信息
return;
} else if ("".equals(recipient.getResource())) {
}
}
this.doAction(packet, incoming, processed, session);
} /**
* <b>function:</b> 执行保存/分析聊天记录动作
* @author shm
* @createDate 2016-3-14
* @param packet 数据包
* @param incoming true表示发送方
* @param session 当前用户session
*/
private void doAction(Packet packet, boolean incoming, boolean processed, Session session) {
Packet copyPacket = packet.createCopy();
if (packet instanceof Message) {
Message message = (Message) copyPacket;
// 一对一聊天,单人模式
if (message.getType() == Message.Type.chat) {
log.info("单人聊天信息:{}", message.toXML());
//debug("单人聊天信息:" + message.toXML());
// 程序执行中;是否为结束或返回状态(是否是当前session用户发送消息)
if (processed || !incoming) {
return;
} java.sql.Timestamp date = new java.sql.Timestamp(new Date().getTime()); //在原有的扩展xml中添加发送日期子节点
Element chatInfoElement = message.getElement().element("chatinfo");
Element timeElement = DocumentFactory.getInstance().createDocument().addElement("sendtime");
timeElement.setText(String.valueOf(date.getTime()));
chatInfoElement.add(timeElement); //logsManager.add(this.get(packet, incoming, session));
logsManager.addByMap(this.getMsgInfo(packet, incoming, session, date)); //保存到离线消息表,客户端收到后调用删除离线消息功能,这样可确保即使网络突然掉线或不好的情况下消息丢失的问题
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.addAttribute("id", message.getID());
received.addAttribute("type", "normal");
log.info("回执内容:" + receiptMessage); // 判断接受者是否在线,2代表离线状态,1代表在线状态,0代表用戶不存在
//注意一定要修改Constant类中的url,否则url错误或导致消息发送很慢,因为url不对时查找用户是否在线会浪费很多时间
/*if (IsOnLineUtils.IsUserOnLine(message.getTo()) == 1) {
received.addAttribute("status", "1");
} else if (IsOnLineUtils.IsUserOnLine(message.getTo()) == 0) {
received.addAttribute("status", "0");
} else if (IsOnLineUtils.IsUserOnLine(message.getTo()) == 2) {
received.addAttribute("status", "2");
}*/ try {
XMPPServer.getInstance().getPacketDeliverer().deliver(receiptMessage);
log.info("服务端回执成功!");
} catch (Exception e) {
e.printStackTrace();
} // 群聊天,多人模式
} else if (message.getType() == Message.Type.groupchat) {
List<?> els = message.getElement().elements("x");
if (els != null && !els.isEmpty()) {
log.info("群聊天信息:{}", message.toXML());
debug("群聊天信息:" + message.toXML());
} else {
log.info("群系统信息:{}", message.toXML());
debug("群系统信息:" + message.toXML());
}
// 其他信息
}else {
log.info("其他信息:{}", message.toXML());
//debug("其他信息:" + message.toXML());
}
} else if (packet instanceof IQ) {
IQ iq = (IQ) copyPacket;
if (iq.getType() == IQ.Type.set && iq.getChildElement() != null && "session".equals(iq.getChildElement().getName())) {
log.info("用户登录成功:{}", iq.toXML());
//debug("用户登录成功:" + iq.toXML());
}
} else if (packet instanceof Presence) {
Presence presence = (Presence) copyPacket;
if (presence.getType() == Presence.Type.unavailable) {
log.info("用户退出服务器成功:{}", presence.toXML());
//debug("用户退出服务器成功:" + presence.toXML());
}
}
} /**
* <b>function:</b> 创建一个聊天记录实体对象,并设置相关数据
* @author shm
* @createDate 2016-3-14
* @param packet 数据包
* @param incoming 如果为ture就表明是发送者
* @param session 当前用户session
* @return 聊天实体
*/
@SuppressWarnings("unchecked")
private Chat get(Packet packet, boolean incoming, Session session) {
Message message = (Message) packet;
JID jid = session.getAddress(); Map<String, Object> map = XmlToMap.xmlToHashMap(message.toXML());
Chat chat = new Chat();
if(map.containsKey("zid") && !"null".equals(map.get("zid")) && !StringUtils.isEmpty(map.get("zid")+"")){
chat.setId(map.get("zid")+"");
}else{
chat.setId(UUID.randomUUID().toString().replace("-", ""));
}
chat.setCaseId(map.get("caseid")+"");
chat.setContent(message.getBody());
chat.setCreator(jid.getNode());
chat.setSender(jid.getNode());
chat.setModifier(jid.getNode());
chat.setSendee(message.getTo().getNode());
chat.setIdentity(map.get("identity")+"");
chat.setzType(map.get("ztype")+"");
chat.setSenderId(map.get("senderid")+"");
chat.setSendeeId(map.get("sendeeid")+""); if(map.get("msglength") != null && !"".equals(map.get("msglength")))
{
chat.setMsgLength(Integer.parseInt(map.get("msglength")+""));
}
return chat;
} @SuppressWarnings({ "unchecked", "rawtypes" })
private Map getMsgInfo(Packet packet, boolean incoming, Session session, java.sql.Timestamp date) {
Message message = (Message) packet;
Map<String, Object> map = XmlToMap.xmlToHashMap(message.toXML());
map.put("content", message.getBody());
map.put("sendtime", date);
log.info("tag:{}", map.get("tag"));
//debug("tag:" + map.get("tag"));
return map;
} /**
* * <b>function:</b> 调试信息
* @author shm
* @createDate 2016-3-14
* @param packet 数据包
* @param incoming 如果为ture就表明是发送者
* @param processed 执行
* @param session 当前用户session
*/
private void debug(Packet packet, boolean incoming, boolean processed, Session session) {
//String info = "[ packetID: " + packet.getID() + ", to: " + packet.getTo() + ", from: " + packet.getFrom() + ", incoming: " + incoming + ", processed: " + processed + " ]";
StringBuilder info = new StringBuilder();
info.append("[ packetID: ").append(packet.getID()).append(", to: ").append(packet.getTo()).append(", from: ").append(packet.getFrom()).append(", incoming: ").append(incoming).append(", processed: ").append(processed).append(" ]"); long timed = System.currentTimeMillis();
debug("################### start ###################" + timed);
debug("id:" + session.getStreamID() + ", address: " + session.getAddress());
debug("info: " + info); debug("xml: " + packet.toXML());
debug("################### end #####################" + timed);
log.info("id:" + session.getStreamID() + ", address: " + session.getAddress());
log.info("info: {}", info);
log.info("plugin Name: " + pluginManager.getName(this) + ", xml: " + packet.toXML());
} private void debug(Object message) {
if (true) {
System.out.println(message);
}
} @Override
public void destroyPlugin() {
interceptorManager.removeInterceptor(this);
debug("销毁聊天记录插件成功!");
} @Override
public void initializePlugin(PluginManager manager, File pluginDirectory) {
interceptorManager.addInterceptor(this);
pluginManager = manager;
debug("安装聊天记录插件成功!");
} /* // 判断接受者是否在线,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();
}
}*/
}
openfire聊天消息记录插件关键代码的更多相关文章
- 源码详解openfire保存消息记录_修改服务端方式
实现openfire消息记录通常有两种方式,修改服务端和添加消息记录插件. 今天,简单的说明一下修改服务端方式实现消息记录保存功能. 实现思路 修改前: 默认的,openfire只提供保存离线记录至o ...
- 基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件[转]
上一篇文章介绍到怎么在自己的Java环境中搭建openfire插件开发的环境,同时介绍到怎样一步步简单的开发openfire插件.一步步很详细的介绍到简单插件开发,带Servlet的插件的开发.带JS ...
- openfire:基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件
基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件 上一篇文章介绍到怎么在自己的Java环境中搭建openfire插件开发的环境,同时介绍到怎样一步步简单的开发openfir ...
- 基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件
原文:http://www.cnblogs.com/hoojo/archive/2013/03/29/openfire_plugin_chatlogs_plugin_.html 随笔-150 评论- ...
- spark结合 Openfire服务器,发送聊天消息
1.下载OpenFire服务器,进行安装,参考http://www.cnblogs.com/hoojo/archive/2012/05/17/2506769.html 2.程序运行客户端:下载客户端代 ...
- Smack 结合 Openfire服务器,建立IM通信,发送聊天消息
在文章开始,请你了解和熟悉openfire方面的相关知识,这样对你理解下面代码以及下面代码的用途有很好的了解.同时,你可能需要安装一个简单的CS聊天工具,来测试你的代码是否成功的在openfire服务 ...
- 七、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-聊天消息项的实现
会话好友列表的实现 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入框扩展 ...
- 微信iOS消息拦截插件教程-Tweak HelloWorld
微信iOS消息拦截插件教程-Tweak HelloWorld 标签(空格分隔): 越狱开发教程 1.环境准备 准备一台越狱的手机,具体参照上一篇教程 搭建Theos越狱开发环境 2.开发过程 新建一个 ...
- 微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)
1.点评 对于IM系统来说,如何做到IM聊天消息离线差异拉取(差异拉取是为了节省流量).消息多端同步.消息顺序保证等,是典型的IM技术难点. 就像即时通讯网整理的以下IM开发干货系列一样: <I ...
随机推荐
- TestNG的一个不足之处
PS:本博客selenium分类不会记载selenium打开浏览器,定位元素,操作页面元素,切换到iframe,处理alter.confirm和prompt对话框这些在网上随处可见的信息:本博客此分类 ...
- React学习一
一.运行起来react 1.引入react库 引入对应的js即可,第三方cdn引入 <script src="https://cdnjs.cloudflare.com/ajax/lib ...
- MetInfo数据库结构表
met_admin_table 表 Key 字段名称 数据类型 不为空 默认值 说明 PK id INT(11) Yes 编号 admin_type TEXT Yes 管理员类型 ad ...
- Android实现apk文件下载并自动安装
//下载apk程序代码 protected File downLoadFile(String httpUrl) { // TODO Auto-generated method stub final S ...
- Leetcode: K-th Smallest in Lexicographical Order
Given integers n and k, find the lexicographically k-th smallest integer in the range from 1 to n. N ...
- Fitnesse在eclipse中的调试
需要在Fitnesse的wik中添加: '''此句话专门用来Debug'''!define COMMAND_PATTERN {java -Xdebug -Xrunjdwp:transport=dt_s ...
- JSP 和 Servlet 有哪些相同点和不同点,他们之间的联系是什么?
JSP 和 Servlet 有哪些相同点和不同点,他们之间的联系是什么? 联系: JSP 是 Servlet 技术的扩展,本质上是 Servlet 的简易方式,更强调应用的外表表达. JSP编译后是& ...
- 单点登录 SSO 的实现原理
单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任. 单点登录在大型网站里使用 ...
- JAVA TcpServer端使用Scanner读取不到数据的解决办法
在使用JAVA进行Socket通信时,在Server端使用Scanner的nextLine()方法读取数据时,一直读取不到数据是因为Scanner是一个扫描器,它扫描数据都是去内存中一块缓冲区中进行扫 ...
- JS变量、内存、作用域小结
确保占用最少的内存可以让页面获得更好的性能,优化内存占用的最佳方式:为执行中的代码 只保存必要的数据.一旦数据不再有用,最好通过将其值置为null来释放其引用.适用于大多 数全局变量和全局对象的属性. ...