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聊天记录插件的更多相关文章

  1. openfire:基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件

    基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件 上一篇文章介绍到怎么在自己的Java环境中搭建openfire插件开发的环境,同时介绍到怎样一步步简单的开发openfir ...

  2. 基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件

    原文:http://www.cnblogs.com/hoojo/archive/2013/03/29/openfire_plugin_chatlogs_plugin_.html 随笔-150  评论- ...

  3. 基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件[转]

    上一篇文章介绍到怎么在自己的Java环境中搭建openfire插件开发的环境,同时介绍到怎样一步步简单的开发openfire插件.一步步很详细的介绍到简单插件开发,带Servlet的插件的开发.带JS ...

  4. XMPP即时通讯协议使用(六)——开发Openfire聊天记录插件

    转载地址:http://www.cnblogs.com/hoojo/archive/2013/03/29/openfire_plugin_chatlogs_plugin_.html 开发环境: Sys ...

  5. Openfire Meetings插件是一个包含各种Jitsi项目(如VideoBridge和Meet)的实现

    Openfire Meetings插件是一个包含各种Jitsi项目(如VideoBridge和Meet)的实现.要创建与Openfire Meetings一起使用的本机客户端,建议使用Jitsi项目提 ...

  6. Openfire 编译插件

    新增的插件打包方法: 3.打包插件 a.第一次打包需配置ant工具.在环境变量中, 添加 path=C:\Program Files\Java\jdk1.5.0_09\;D:\Program File ...

  7. openfire Hazelcast插件集群配置

    原文:http://blog.csdn.net/frankcheng5143/article/details/48708899 注意虽然hazelcast 官方已经有了3.5.2版本,但是openfi ...

  8. OpenFire后台插件上传获取webshell及免密码登录linux服务器

    1.目标获取 (1)fofa.so网站使用搜索body="Openfire, 版本: " && country=JP,可以获取日本存在的Openfire服务器.如图 ...

  9. openfire聊天消息记录插件关键代码

    package com.sqj.openfire.chat.logs; import java.io.File; import java.util.Date; import java.util.Lis ...

随机推荐

  1. 使用自连接、for xml path('')和stuff合并显示多行数据到一行中(转)

    原文: http://njm.iteye.com/blog/795881 --使用 自连接.for xml path('')和stuff合并显示多行数据到一行中 --注 --1.计算列可以不用包含在聚 ...

  2. android开发学习---linux下开发环境的搭建&& android基础知识介绍

    一.配置所需开发环境 1.基本环境配置 JDK 5或以上版本(仅有JRE不够) (http://www.oracle.com/technetwork/java/javase/downloads/ind ...

  3. MyStack

    #pragma once class MyQueue { public: MyQueue(); ~MyQueue(); void Insert(int aValue); int Top(); void ...

  4. Agile Development敏捷软件开发之何为敏捷开发

    敏捷软件开发之何为敏捷开发 敏捷开发,Agile Development,就是指能够在需求迅速变化的情况下快速开发软件.我们接触最多敏捷实践方式有:极限编程(XP).结对编程.测试驱动开发(TDD)等 ...

  5. 树莓派UFW防火墙简单设置

    ufw是一个主机端的iptables类防火墙配置工具,比较容易上手.如果你有一台暴露在外网的树莓派,则可通过这个简单的配置提升安全性. 安装方法 sudo apt-get install ufw 当然 ...

  6. VC对话框使用OnEraseBkgnd函数位图背景并透明

    1.使用OnEraseBkgnd函数实现对话框位图背景 BOOL CDisplayBmpBackGroundDlg::OnEraseBkgnd(CDC *pDC) { CRect rect; GetC ...

  7. Intellij Idea免费激活方法

    填入下面的license server: http://intellij.mandroid.cn/http://idea.imsxm.com/http://idea.iteblog.com/key.p ...

  8. GIF Brewery for Mac(录制 Gif 动图工具)安装

    1.软件简介    GIF Brewery 一款用于录制 Gif 动图等的工具. 2.资源列表 链接 提取密码 系统要求 软件语言 GIF Brewery for Mac v3.9.5 ltmf ma ...

  9. symbolicatecrash App Bug 分析工具

    1.symbolicatecrash 简介 symbolicatecrash 是一个 Xcode 自带解析 iOS Crash 文件的工具. 其它下载地址 symbolicatecrash,密码:6p ...

  10. 【struts2】<s:url>标签

    <s:url>标签一般和超链接 <a>一起使用,用于带多个参数. <a href=" <s:url action=""> < ...