zoukankan      html  css  js  c++  java
  • 开发openfire 消息拦截器插件PacketInterceptor

    开发消息拦截器的步骤跟开发简单插件步骤一样,要开发消息拦截器插件,首先继承PacketInterceptor包拦截类,然后在initializelPlugin()方法中注册拦截器,就可以实现interceptPackage()方法中拦截包(即此方法中的packet参数)了。并且,可以通过入参incoming来判断是服务器发送的包还是接受的包(注:true为服务器接收的包;false为发出的包)。processed参数用处暂不明,猜想是对请求做了什么处理的标识,但不影响我们对包进行拦截和处理。

       这个扩展方式与前一种相比的好处在于,这种方式不仅没有修改原注册流程的代码,而且最大程度的使用了原注册流程。这样可以避免一些不必要的风险。

    1. package com.bis.plugin.messageplugin;
    2.  
    3. import java.io.File;
    4.  
    5. import org.jivesoftware.openfire.container.Plugin;
    6. import org.jivesoftware.openfire.container.PluginManager;
    7. import org.jivesoftware.openfire.interceptor.InterceptorManager;
    8. import org.jivesoftware.openfire.interceptor.PacketInterceptor;
    9. import org.jivesoftware.openfire.interceptor.PacketRejectedException;
    10. import org.jivesoftware.openfire.session.Session;
    11. import org.xmpp.packet.Packet;
    12.  
    13. public class MessagePlugIn implements Plugin,PacketInterceptor {
    14. private static PluginManager pluginManager;
    15. private InterceptorManager interceptoerManager;
    16.  
    17.  
    18.  
    19. public MessagePlugIn() {
    20. interceptoerManager = InterceptorManager.getInstance();
    21. }
    22.  
    23. @Override
    24. public void initializePlugin(PluginManager manager, File pluginDirectory) {
      interceptoerManager = InterceptorManager.getInstance();
    25. pluginManager = manager;
    26. interceptoerManager.addInterceptor(this);
    27. System.out.println("加载插件成功!");
    28. }
    29.  
    30. @Override
    31. public void destroyPlugin() {
    32. interceptoerManager.removeInterceptor(this);
    33. System.out.println("销毁插件成功!");
    34. }
    35.  
    36. @Override
    37. public void interceptPacket(Packet packet, Session session,
    38. boolean incoming, boolean processed) throws PacketRejectedException {
    39. System.out.println("接收到的消息内容:"+packet.toXML());
    40. }
    41.  
    42. }

     1、继承Plugin接口,就是在系统启动的时候会执行initializePlugin()方法,表示这是一个插件类

    2、继承PacketInterceptor接口,表示这个类是一个拦截Message的消息类,当拦截的时候,会执行interceptPacket方法

     

    关于openfire是如何管理消息拦截器的?

    我们可以看看MessageRouter类的route(Message packet)方法

     

    1. public void route(Message packet) {
    2. if (packet == null) {
    3. throw new NullPointerException();
    4. }
    5. ClientSession session = sessionManager.getSession(packet.getFrom());
    6. try {
    7. // Invoke the interceptors before we process the read packet
    8. //系统的拦截器就是在这里调用的,遍历动态添加的所有拦截器
    9. InterceptorManager.getInstance().invokeInterceptors(packet, session, true, false);
    10. if (session == null || session.getStatus() == Session.STATUS_AUTHENTICATED) {
    11. JID recipientJID = packet.getTo();
    12.  
    13. // Check if the message was sent to the server hostname
    14. if (recipientJID != null && recipientJID.getNode() == null && recipientJID.getResource() == null &&
    15. serverName.equals(recipientJID.getDomain())) {
    16. if (packet.getElement().element("addresses") != null) {
    17. // Message includes multicast processing instructions. Ask the multicastRouter
    18. // to route this packet
    19. multicastRouter.route(packet);
    20. }
    21. else {
    22. // Message was sent to the server hostname so forward it to a configurable
    23. // set of JID's (probably admin users)
    24. sendMessageToAdmins(packet);
    25. }
    26. return;
    27. }
    28.  
    29. try {
    30. // Deliver stanza to requested route
    31. routingTable.routePacket(recipientJID, packet, false);
    32. }
    33. catch (Exception e) {
    34. log.error("Failed to route packet: " + packet.toXML(), e);
    35. routingFailed(recipientJID, packet);
    36. }
    37. }
    38. else {
    39. packet.setTo(session.getAddress());
    40. packet.setFrom((JID)null);
    41. packet.setError(PacketError.Condition.not_authorized);
    42. session.process(packet);
    43. }
    44. // Invoke the interceptors after we have processed the read packet
    45. //系统的拦截器就是在这里调用的,遍历动态添加的所有拦截器
    46. InterceptorManager.getInstance().invokeInterceptors(packet, session, true, true);
    47. } catch (PacketRejectedException e) {
    48. // An interceptor rejected this packet
    49. if (session != null && e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) {
    50. // A message for the rejection will be sent to the sender of the rejected packet
    51. Message reply = new Message();
    52. reply.setID(packet.getID());
    53. reply.setTo(session.getAddress());
    54. reply.setFrom(packet.getTo());
    55. reply.setType(packet.getType());
    56. reply.setThread(packet.getThread());
    57. reply.setBody(e.getRejectionMessage());
    58. session.process(reply);
    59. }
    60. }
    61. }

     

     

    1. public void route(Message packet) {
    2. if (packet == null) {
    3. throw new NullPointerException();
    4. }
    5. ClientSession session = sessionManager.getSession(packet.getFrom());
    6. try {
    7. // Invoke the interceptors before we process the read packet
    8. //系统的拦截器就是在这里调用的,遍历动态添加的所有拦截器
    9. InterceptorManager.getInstance().invokeInterceptors(packet, session, true, false);
    10. if (session == null || session.getStatus() == Session.STATUS_AUTHENTICATED) {
    11. JID recipientJID = packet.getTo();
    12.  
    13. // Check if the message was sent to the server hostname
    14. if (recipientJID != null && recipientJID.getNode() == null && recipientJID.getResource() == null &&
    15. serverName.equals(recipientJID.getDomain())) {
    16. if (packet.getElement().element("addresses") != null) {
    17. // Message includes multicast processing instructions. Ask the multicastRouter
    18. // to route this packet
    19. multicastRouter.route(packet);
    20. }
    21. else {
    22. // Message was sent to the server hostname so forward it to a configurable
    23. // set of JID's (probably admin users)
    24. sendMessageToAdmins(packet);
    25. }
    26. return;
    27. }
    28.  
    29. try {
    30. // Deliver stanza to requested route
    31. routingTable.routePacket(recipientJID, packet, false);
    32. }
    33. catch (Exception e) {
    34. log.error("Failed to route packet: " + packet.toXML(), e);
    35. routingFailed(recipientJID, packet);
    36. }
    37. }
    38. else {
    39. packet.setTo(session.getAddress());
    40. packet.setFrom((JID)null);
    41. packet.setError(PacketError.Condition.not_authorized);
    42. session.process(packet);
    43. }
    44. // Invoke the interceptors after we have processed the read packet
    45. //系统的拦截器就是在这里调用的,遍历动态添加的所有拦截器
    46. InterceptorManager.getInstance().invokeInterceptors(packet, session, true, true);
    47. } catch (PacketRejectedException e) {
    48. // An interceptor rejected this packet
    49. if (session != null && e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) {
    50. // A message for the rejection will be sent to the sender of the rejected packet
    51. Message reply = new Message();
    52. reply.setID(packet.getID());
    53. reply.setTo(session.getAddress());
    54. reply.setFrom(packet.getTo());
    55. reply.setType(packet.getType());
    56. reply.setThread(packet.getThread());
    57. reply.setBody(e.getRejectionMessage());
    58. session.process(reply);
    59. }
    60. }
    61. }

     最后附上xmpp的相关协议:

    1. .openfire注册相关协议
    2. 1./*用户注册,原本的协议中没有province字段,这里为扩展*/
    3. <iq id="g0G4m-1" to="zhanglj" type="set">
    4. <query xmlns="jabber:iq:register">
    5. <username>re3</username>
    6. <email></email>
    7. <name></name>
    8. <password>1</password>
    9. <province>合肥</province>
    10. </query>
    11. </iq>
    12.  
    13. 2.用户注册成功
    14. <iq type="result" id="g0G4m-1" from="zhanglj" to="re3@zhanglj/Spark 2.6.3"/>
    15.  
    16. 3.用户注册失败
    17. i. 用户名为空:code='500"
    18. <iq type="error" id="g0G4m-1" from="zhanglj" to="re3@zhanglj/Spark 2.6.3">
    19. <query xmlns="jabber:iq:register">
    20. <username/>
    21. <email/>
    22. <name/>
    23. <password>1</password>
    24. <province>合肥</province>
    25. </query>
    26. <error code="500" type="wait">
    27. <internal-server-error xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    28. </error>
    29. </iq>
    30.  
    31. ii.密码为空:code='406"
    32. <iq type="error" id="g0G4m-1" from="zhanglj" to="re3@zhanglj/Spark 2.6.3">
    33. <query xmlns="jabber:iq:register">
    34. <username>r</username>
    35. <email/>
    36. <name/>
    37. <password/>
    38. </query>
    39. <error code="406" type="modify"><not-acceptable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    40. </error>
    41. </iq>
    42.  
    43. iii.用户已存在:code='409"
    44. <iq id="g0G4m-1" to="re3@zhanglj/Spark 2.6.3" from="zhanglj" type="error">
    45. <query xmlns="jabber:iq:register">
    46. <username>re5</username>
    47. <email/>
    48. <name/>
    49. <province>合肥</province>
    50. <password>1</password>
    51. </query>
    52. <error code="409" type="CANCEL">
    53. <conflict xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    54. </error>
    55. </iq>

     https://blog.csdn.net/zhonglunshun/article/details/84695804

  • 相关阅读:
    Python基础Day1—下
    Python基础Day1—上
    Asp.net +Jquery-uploadify多文件上传
    C#txt文件读写基本操作
    C#获取窗口,模拟按键操作
    百度搜索优化-如何使搜索结果显示图文
    纯CSS3实现超立体的3D图片侧翻倾斜效果
    Android http通信 HttpURLConnection
    Android Socket 知识点汇总
    Android http通信案例
  • 原文地址:https://www.cnblogs.com/tiancai/p/10064631.html
Copyright © 2011-2022 走看看