开发openfire 消息拦截器插件PacketInterceptor
开发消息拦截器的步骤跟开发简单插件步骤一样,要开发消息拦截器插件,首先继承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();
-
}
-
-
-
public void initializePlugin(PluginManager manager, File pluginDirectory) {
interceptoerManager = InterceptorManager.getInstance();
-
pluginManager = manager;
-
interceptoerManager.addInterceptor(this);
-
System.out.println("加载插件成功!");
-
}
-
-
-
public void destroyPlugin() {
-
interceptoerManager.removeInterceptor(this);
-
System.out.println("销毁插件成功!");
-
}
-
-
-
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
-
<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>
https://blog.csdn.net/zhonglunshun/article/details/84695804