开发消息拦截器的步骤跟开发简单插件步骤一样,要开发消息拦截器插件,首先继承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源码即可满足聊天的实用功能,对外提供3个接口,一消息...
这是为openfire服务器开发插件的简单demo,参照博客:http://blog.csdn.net/ibm_hoojo/
NULL 博文链接:https://xrb2008.iteye.com/blog/1972738
openfire服务器在进行消息转发时,如果接收者网络断开,服务器检测不到接收者已下线,转发后消息会丢失,为解决消息丢失,有四种解决方案: 1.发送之前“发送心跳” 2.发送之前“发自定义结构” 3.客服端收到消息...
目的:主要是为了监控Openfire各类message,然后对message body做进一步...局限:因为时间有限,本插件并没有对Openfire message协议进行扩展,都是基于原生的xml协议,因此后续开发还需要进行更加深入的二次开发操作。
openfire群聊持久化插件,直接放到plugin目录下可用,解决群聊房间推出后房间销毁问题 附带的两张数据库表用来保存群聊离线消息
NULL 博文链接:https://bsr1983.iteye.com/blog/2240070
这是一个文档,内容是如何编写Openfire开发插件、部署源码
openfire 历史纪录插件,可以存放聊天记录,内含sql文件,自己写的亲测,后期继续完善
openfire 聊天记录插件,已经经过测试,欢迎下载。
openfire消息、监听、启动流程分析 openfire消息、监听、启动流程分析 openfire消息、监听、启动流程分析
openfire第一个插件开发以及源码说明,QQ群:28588322
XMPP 协议讲解 openfire 结构分析以及插件开发指南 希望能帮到想学习openfire的同学
openfire shell插件
openFire 保存聊天记录插件 亲测100%有效 插件直接拷贝到OpenFire安装目录的plugin下 自动安装后 进入OpenFire管理后台 服务器==》档案文件==》存档设置 几个单选框都勾选, 聊天记录保存在 ofMessageArchive 表...
NULL 博文链接:https://beautyofprogram.iteye.com/blog/772281
两个保存聊天记录的openfire的插件 亲测可以用