开发消息拦截器的步骤跟开发简单插件步骤一样,要开发消息拦截器插件,首先继承PacketInterceptor包拦截类,然后在initializelPlugin()方法中注册拦截器,就可以实现interceptPackage()方法中拦截包(即此方法中的packet参数)了。并且,可以通过入参incoming来判断是服务器发送的包还是接受的包(注:true为服务器接收的包;false为发出的包)。processed参数用处暂不明,猜想是对请求做了什么处理的标识,但不影响我们对包进行拦截和处理。
这个扩展方式与前一种相比的好处在于,这种方式不仅没有修改原注册流程的代码,而且最大程度的使用了原注册流程。这样可以避免一些不必要的风险。
package com.bis.plugin.messageplugin; import java.io.File; 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.xmpp.packet.Packet; public class MessagePlugIn implements Plugin,PacketInterceptor { private static PluginManager pluginManager; private InterceptorManager interceptoerManager; public MessagePlugIn() { interceptoerManager = InterceptorManager.getInstance(); } @Override public void initializePlugin(PluginManager manager, File pluginDirectory) { pluginManager = manager; interceptoerManager.addInterceptor(this); System.out.println("加载插件成功!"); } @Override public void destroyPlugin() { interceptoerManager.removeInterceptor(this); System.out.println("销毁插件成功!"); } @Override public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed) throws PacketRejectedException { System.out.println("接收到的消息内容:"+packet.toXML()); } }
1、继承Plugin接口,就是在系统启动的时候会执行initializePlugin()方法,表示这是一个插件类
2、继承PacketInterceptor接口,表示这个类是一个拦截Message的消息类,当拦截的时候,会执行interceptPacket方法
关于openfire是如何管理消息拦截器的?
我们可以看看MessageRouter类的route(Message packet)方法
public void route(Message packet) { if (packet == null) { throw new NullPointerException(); } ClientSession session = sessionManager.getSession(packet.getFrom()); try { // Invoke the interceptors before we process the read packet //系统的拦截器就是在这里调用的,遍历动态添加的所有拦截器 InterceptorManager.getInstance().invokeInterceptors(packet, session, true, false); if (session == null || session.getStatus() == Session.STATUS_AUTHENTICATED) { JID recipientJID = packet.getTo(); // Check if the message was sent to the server hostname if (recipientJID != null && recipientJID.getNode() == null && recipientJID.getResource() == null && serverName.equals(recipientJID.getDomain())) { if (packet.getElement().element("addresses") != null) { // Message includes multicast processing instructions. Ask the multicastRouter // to route this packet multicastRouter.route(packet); } else { // Message was sent to the server hostname so forward it to a configurable // set of JID's (probably admin users) sendMessageToAdmins(packet); } return; } try { // Deliver stanza to requested route routingTable.routePacket(recipientJID, packet, false); } catch (Exception e) { log.error("Failed to route packet: " + packet.toXML(), e); routingFailed(recipientJID, packet); } } else { packet.setTo(session.getAddress()); packet.setFrom((JID)null); packet.setError(PacketError.Condition.not_authorized); session.process(packet); } // Invoke the interceptors after we have processed the read packet //系统的拦截器就是在这里调用的,遍历动态添加的所有拦截器 InterceptorManager.getInstance().invokeInterceptors(packet, session, true, true); } catch (PacketRejectedException e) { // An interceptor rejected this packet if (session != null && e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) { // A message for the rejection will be sent to the sender of the rejected packet Message reply = new Message(); reply.setID(packet.getID()); reply.setTo(session.getAddress()); reply.setFrom(packet.getTo()); reply.setType(packet.getType()); reply.setThread(packet.getThread()); reply.setBody(e.getRejectionMessage()); session.process(reply); } } }
public void route(Message packet) { if (packet == null) { throw new NullPointerException(); } ClientSession session = sessionManager.getSession(packet.getFrom()); try { // Invoke the interceptors before we process the read packet //系统的拦截器就是在这里调用的,遍历动态添加的所有拦截器 InterceptorManager.getInstance().invokeInterceptors(packet, session, true, false); if (session == null || session.getStatus() == Session.STATUS_AUTHENTICATED) { JID recipientJID = packet.getTo(); // Check if the message was sent to the server hostname if (recipientJID != null && recipientJID.getNode() == null && recipientJID.getResource() == null && serverName.equals(recipientJID.getDomain())) { if (packet.getElement().element("addresses") != null) { // Message includes multicast processing instructions. Ask the multicastRouter // to route this packet multicastRouter.route(packet); } else { // Message was sent to the server hostname so forward it to a configurable // set of JID's (probably admin users) sendMessageToAdmins(packet); } return; } try { // Deliver stanza to requested route routingTable.routePacket(recipientJID, packet, false); } catch (Exception e) { log.error("Failed to route packet: " + packet.toXML(), e); routingFailed(recipientJID, packet); } } else { packet.setTo(session.getAddress()); packet.setFrom((JID)null); packet.setError(PacketError.Condition.not_authorized); session.process(packet); } // Invoke the interceptors after we have processed the read packet //系统的拦截器就是在这里调用的,遍历动态添加的所有拦截器 InterceptorManager.getInstance().invokeInterceptors(packet, session, true, true); } catch (PacketRejectedException e) { // An interceptor rejected this packet if (session != null && e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) { // A message for the rejection will be sent to the sender of the rejected packet Message reply = new Message(); reply.setID(packet.getID()); reply.setTo(session.getAddress()); reply.setFrom(packet.getTo()); reply.setType(packet.getType()); reply.setThread(packet.getThread()); reply.setBody(e.getRejectionMessage()); session.process(reply); } } }
最后附上xmpp的相关协议:
.openfire注册相关协议 1./*用户注册,原本的协议中没有province字段,这里为扩展*/ <iq id="g0G4m-1" to="zhanglj" type="set"> <query xmlns="jabber:iq:register"> <username>re3</username> <email></email> <name></name> <password>1</password> <province>合肥</province> </query> </iq> 2.用户注册成功 <iq type="result" id="g0G4m-1" from="zhanglj" to="re3@zhanglj/Spark 2.6.3"/> 3.用户注册失败 i. 用户名为空:code='500" <iq type="error" id="g0G4m-1" from="zhanglj" to="re3@zhanglj/Spark 2.6.3"> <query xmlns="jabber:iq:register"> <username/> <email/> <name/> <password>1</password> <province>合肥</province> </query> <error code="500" type="wait"> <internal-server-error xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> </error> </iq> ii.密码为空:code='406" <iq type="error" id="g0G4m-1" from="zhanglj" to="re3@zhanglj/Spark 2.6.3"> <query xmlns="jabber:iq:register"> <username>r</username> <email/> <name/> <password/> </query> <error code="406" type="modify"><not-acceptable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> </error> </iq> iii.用户已存在:code='409" <iq id="g0G4m-1" to="re3@zhanglj/Spark 2.6.3" from="zhanglj" type="error"> <query xmlns="jabber:iq:register"> <username>re5</username> <email/> <name/> <province>合肥</province> <password>1</password> </query> <error code="409" type="CANCEL"> <conflict xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> </error> </iq>
这篇文章资料来自互联网,整理以便日后学习。
相关推荐
在Openfire中,消息记录存储插件扮演着关键角色,它负责收集、存储以及检索用户的聊天记录,这对于企业级通信管理和合规性审计至关重要。 首先,我们要了解Openfire的消息记录功能。Openfire内置了消息记录管理,但...
openfire防止消息丢失插件,防止丢包插件
在Openfire的生态系统中,开发插件是增强其功能的有效方式。本文将深入探讨“Openfire消息回执插件”,并结合提供的三个关键文件——DbChatLogsManager.java、ChatLogPlugin.java和ChatLogs.java,解析该插件的设计...
5. **使用Openfire API**:Openfire提供了丰富的API供插件开发者使用,例如,你可以通过`AdminManager`来管理用户和群组,或者通过`PacketRouter`来发送和接收XMPP消息。理解并熟练运用这些API是开发高效插件的关键...
标题中的“openfire插件开发环境搭建”是指学习和配置Openfire服务器以开发自定义插件的过程。Openfire是一款开源的即时通讯服务器,基于XMPP(Extensible Messaging and Presence Protocol)协议,允许用户进行实时...
Openfire是一款开源、基于XMPP协议的实时协作服务器,它允许用户进行即时消息传递、音频/视频聊天以及群组聊天等操作。在企业或团队环境中,聊天记录的保存对于工作协同、问题排查以及合规审计具有重大意义。 这款...
openfire插件,本插件直接在openfire里安装即可,集成消息在线和离线的存储、查询接口,图片、表情、语音文件的上传和下载对外接口,因此,不需要修改openfire源码即可满足聊天的实用功能,对外提供3个接口,一消息...
开发者需要熟悉XMPP协议、Java编程和Web开发的相关知识,才能有效地利用Openfire的API进行插件开发。而部署源码则涉及到构建流程、依赖管理和服务器配置,确保插件能够在Openfire环境中正常运行。
Openfire 安装配置和插件开发详解 Openfire 是一个基于 XMPP 协议的即时通信服务器,可以实现实时的聊天服务。在本文中,我们将详细介绍 Openfire 的安装和配置过程,并探讨如何使用 Eclipse 进行插件开发。 一、...
利用Openfire提供的API,如`PluginManager`、`PacketInterceptor`等,实现所需的插件功能。这可能包括监听聊天消息、管理用户、扩展服务器功能等。 7. **打包与部署** 使用Maven或Gradle构建插件项目,生成JAR...
总之,"openfire群聊持久化插件"是Openfire服务器的一个重要补充,它通过保存群聊记录和离线消息,提升了用户体验和协作效率。安装和使用这个插件是确保团队沟通连贯性的重要步骤,特别是对于那些依赖群聊进行日常...
标题中的“openfire 插件开发”指的是Openfire系统中的插件开发技术。Openfire是一款开源的即时通讯(Instant Messaging, IM)服务器,基于XMPP协议,提供了丰富的API和插件扩展机制,允许开发者创建自定义功能来...
openfire shell插件
OpenFire插件开发系列的第一部分主要涉及如何搭建OpenFire的二次开发环境,为后续的插件开发工作做好准备。OpenFire是一款开源的即时通讯服务器,它基于Java技术,支持XMPP协议,允许开发者通过编写插件来扩展其功能...
在实时通信中,丢包问题常常是影响用户体验的重要因素,为此,开发者们设计了一款专门针对Openfire的防丢包插件,以确保消息的完整性和可靠性。本文将详细介绍该防丢包插件的工作原理,并对源码进行深入解析。 首先...
openfire服务器在进行消息转发时,如果接收者网络断开,服务器检测不到接收者已下线,转发后消息会丢失,为解决消息丢失,有四种解决方案: 1.发送之前“发送心跳” 2.发送之前“发自定义结构” 3.客服端收到消息...
NULL 博文链接:https://bsr1983.iteye.com/blog/2240070
这个"openfire聊天记录插件"是为了增强Openfire服务器的功能,提供聊天记录的存储和检索能力,使得用户可以回顾和查找之前的对话历史,这对于企业内部沟通、客户服务或者团队协作都是非常有价值的。 首先,我们要...
在Openfire中,为了保留用户间的交流历史,通常需要借助特定的插件来实现聊天记录的保存。在这个压缩包中,包含两个用于保存Openfire聊天记录的插件:`archive.jar`和`chatRecord.jar`。 1. **archive.jar**: 这...
openFire 保存聊天记录插件 亲测100%有效 插件直接拷贝到OpenFire安装目录的plugin下 自动安装后 进入OpenFire管理后台 服务器==》档案文件==》存档设置 几个单选框都勾选, 聊天记录保存在 ofMessageArchive 表...