`
zhonglunshun
  • 浏览: 135393 次
  • 性别: 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>

 

这篇文章资料来自互联网,整理以便日后学习。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics