`
zhonglunshun
  • 浏览: 139528 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

开发openfire 消息拦截器插件PacketInterceptor

    博客分类:
  • xmpp
阅读更多

开发消息拦截器的步骤跟开发简单插件步骤一样,要开发消息拦截器插件,首先继承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防止消息丢失插件,防止丢包插件

    openfire消息回执插件

    在Openfire的生态系统中,开发插件是增强其功能的有效方式。本文将深入探讨“Openfire消息回执插件”,并结合提供的三个关键文件——DbChatLogsManager.java、ChatLogPlugin.java和ChatLogs.java,解析该插件的设计...

    openfire服务器开发插件的简单demo

    5. **使用Openfire API**:Openfire提供了丰富的API供插件开发者使用,例如,你可以通过`AdminManager`来管理用户和群组,或者通过`PacketRouter`来发送和接收XMPP消息。理解并熟练运用这些API是开发高效插件的关键...

    openfire插件开发环境搭建

    标题中的“openfire插件开发环境搭建”是指学习和配置Openfire服务器以开发自定义插件的过程。Openfire是一款开源的即时通讯服务器,基于XMPP(Extensible Messaging and Presence Protocol)协议,允许用户进行实时...

    openfire 聊天历史纪录插件1

    Openfire是一款开源、基于XMPP协议的实时协作服务器,它允许用户进行即时消息传递、音频/视频聊天以及群组聊天等操作。在企业或团队环境中,聊天记录的保存对于工作协同、问题排查以及合规审计具有重大意义。 这款...

    Openfire消息记录插件(消息、上传、下载插件合集)

    openfire插件,本插件直接在openfire里安装即可,集成消息在线和离线的存储、查询接口,图片、表情、语音文件的上传和下载对外接口,因此,不需要修改openfire源码即可满足聊天的实用功能,对外提供3个接口,一消息...

    编写Openfire开发插件、部署源码

    开发者需要熟悉XMPP协议、Java编程和Web开发的相关知识,才能有效地利用Openfire的API进行插件开发。而部署源码则涉及到构建流程、依赖管理和服务器配置,确保插件能够在Openfire环境中正常运行。

    Openfire 的安装和配置、插件开发

    Openfire 安装配置和插件开发详解 Openfire 是一个基于 XMPP 协议的即时通信服务器,可以实现实时的聊天服务。在本文中,我们将详细介绍 Openfire 的安装和配置过程,并探讨如何使用 Eclipse 进行插件开发。 一、...

    第一个openfire插件源码及说明

    利用Openfire提供的API,如`PluginManager`、`PacketInterceptor`等,实现所需的插件功能。这可能包括监听聊天消息、管理用户、扩展服务器功能等。 7. **打包与部署** 使用Maven或Gradle构建插件项目,生成JAR...

    openfire群聊持久化插件

    总之,"openfire群聊持久化插件"是Openfire服务器的一个重要补充,它通过保存群聊记录和离线消息,提升了用户体验和协作效率。安装和使用这个插件是确保团队沟通连贯性的重要步骤,特别是对于那些依赖群聊进行日常...

    openfire 插件开发

    标题中的“openfire 插件开发”指的是Openfire系统中的插件开发技术。Openfire是一款开源的即时通讯(Instant Messaging, IM)服务器,基于XMPP协议,提供了丰富的API和插件扩展机制,允许开发者创建自定义功能来...

    openfire shell插件

    openfire shell插件

    openfire插件开发(1)

    OpenFire插件开发系列的第一部分主要涉及如何搭建OpenFire的二次开发环境,为后续的插件开发工作做好准备。OpenFire是一款开源的即时通讯服务器,它基于Java技术,支持XMPP协议,允许开发者通过编写插件来扩展其功能...

    openfire防丢包插件及源码

    在实时通信中,丢包问题常常是影响用户体验的重要因素,为此,开发者们设计了一款专门针对Openfire的防丢包插件,以确保消息的完整性和可靠性。本文将详细介绍该防丢包插件的工作原理,并对源码进行深入解析。 首先...

    openfire防消息丢失插件

    openfire服务器在进行消息转发时,如果接收者网络断开,服务器检测不到接收者已下线,转发后消息会丢失,为解决消息丢失,有四种解决方案: 1.发送之前“发送心跳” 2.发送之前“发自定义结构” 3.客服端收到消息...

    openfire安装WebSocket插件

    NULL 博文链接:https://bsr1983.iteye.com/blog/2240070

    openfire 聊天记录插件

    这个"openfire聊天记录插件"是为了增强Openfire服务器的功能,提供聊天记录的存储和检索能力,使得用户可以回顾和查找之前的对话历史,这对于企业内部沟通、客户服务或者团队协作都是非常有价值的。 首先,我们要...

    openfire保存聊天记录插件2个

    在Openfire中,为了保留用户间的交流历史,通常需要借助特定的插件来实现聊天记录的保存。在这个压缩包中,包含两个用于保存Openfire聊天记录的插件:`archive.jar`和`chatRecord.jar`。 1. **archive.jar**: 这...

    openFire 保存聊天记录插件 亲测100%有效

    openFire 保存聊天记录插件 亲测100%有效 插件直接拷贝到OpenFire安装目录的plugin下 自动安装后 进入OpenFire管理后台 服务器==》档案文件==》存档设置 几个单选框都勾选, 聊天记录保存在 ofMessageArchive 表...

Global site tag (gtag.js) - Google Analytics