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();
         }
     }*/
}

 

posted @ 2018-12-05 07:29  甜菜波波  阅读(800)  评论(0编辑  收藏  举报