zoukankan      html  css  js  c++  java
  • openfire的组件(Component)开发

    在之前的文章《Openfire阶段实践总结》中提到过一种openfire的扩展模式Compoent。本文将主要探讨对这种模式的应用与开发方法。

    内部与外部组件介绍

      在openfire中的许多插件都实现了Compoent,Compoent的灵活性在于它可以通过对特定的二级子域包进行处理。在XMPP协议中最为明显的使用场景就是群聊,这就是一个典型的例子。看看openfire中的聊天室JID都是什么格式:room1@conference.domain,很明这里多了一个conference。对比用户的JID:user1@domain。openfire通过一个注册路由器来为这种子域提供路由功能。

      这种机制带来了一个很灵活的扩展场景,就是你可以完全定义一套自己的协议处理,使得openfire作为一个消息中转中心而存在。在自己的组件内部可以实现更多的复杂的业务。

    当然为了扩展的更丰富,openfire提供了内部与外部组件两种方式

    • 内部组件,主要是以插件的形式,jar包的形式。内部组件可以和主域有同样的访问和控制权限。比如你想获取主域中的所有用户那是可以的。
    • 外部组件,可是独立的一个应用程序,以tcp形式连接到openfire中,当然就不能获取到主域中的资源啦。

    这两种组件的应用场景各有不同,内部组件可以与主域实现的比较紧密,基本上就是openfire一部分,比如你想扩展群聊为QQ形式的群,就可以使用内部组件来实现。而如果业务系统集成需要集成openfire的一些功能时,就可以选择外部组件模式,这样就要方便的多啦。比如你的商城需要有一个在线客户机器人,那么就可以选择外部组件。

    主要的开发包

     在openfire中提供了两个开发包,tinder和whack。

    • tinder

      主要封装了XMPP协议的基础包,JAVA开发的。在openfire中就引用了这个包,所以基本上服务端中使用这个协议包。

    • whack

      在tinder基础上提供了外部组件开发的一个开发包,使开发人员更方便的搭建openfire的外部组件。

    这说明tinder是一个核心,这样也更好的用于各类项目,包括openfire自己。而whack更像是一个工具包,用于外部组件快速开发的东西,方便的集成到java项目中。tinder和whack都是maven包,这样对于maven项目就方便多啦。不像openfire是ant的,最初还挺不习惯的。

    实现简单的机器人

     那么实现一个简单的自动回复机器人,以此来展示一下组件的开发方法。

    1、创建一个机器人,这个机器人主要是实现了自动回复的功能,所以机器人比较笨,只会说三句话,而且只能随机的回复。代码如下:

    package org.jivesoftware.demo;
    
    import java.util.Random;
    
    import org.xmpp.packet.Message;
    
    public class RobotService {
        private static final RobotService INSTANCES = new RobotService();
        private String[] autoReply = {"你好我是机器人大G,很高兴与你聊天", "哦,你说什么?", "下次再来吧,今天有点忙。"};
        
        private RobotService() {
            
        }
        
        private String getAutoReply() {
            Random random = new Random();
            Integer idx = random.nextInt(autoReply.length);
            return autoReply[idx];
        }
        
        public synchronized static RobotService getInstance () {
            return INSTANCES;
        }
        
        public Message Reply(Message msg) {
            Message reply = new Message();
            reply.setID(msg.getID());
            reply.setTo(msg.getFrom());
            reply.setFrom(msg.getTo());
            reply.setType(Message.Type.chat);
            reply.setBody(getAutoReply());
            return reply;
        }
    }

    机器人会自动从自己学会的语言中找一句回复。

    2、实现外部组件

    因为机器人自动回复并不需要与openfire内部作太多的交互,所以只需要做一个外部的组件即可。将前方发来的消息都转到特定的机器人组件中处理即可。这里需要的是实现AbstractComponent抽象类。

    package org.jivesoftware.demo;
    
    import org.xmpp.component.AbstractComponent;
    import org.xmpp.packet.Message;
    
    public class RobotComponent extends AbstractComponent{
        private String name;
        private String serverDomain;
    
        public RobotComponent(String name, String serverDomain) {
            this.name = name;
            this.serverDomain = serverDomain;
        }
        
        @Override
        public String getDescription() {
            return "我是一个机器人";
        }
    
        @Override
        public String getName() {
            return name;
        }
        
        @Override
        protected void handleMessage(Message message) {
            if ((message.getBody() == null)) {
                return;
            }
            //使用机器人回复
            Message reply = RobotService.getInstance().Reply(message);
            send(reply);
        }
    
    }

    这里要说明的是AbstractComponent这个抽象类,此类是tinder中为了简化Component的开发而提供的。其实就是对IQ、Mesage、disco等包的处理做了封装并提供了重写方法给派生类实现。开发者只需要关心具体的实现即可,不用关心协议的解析与处理。而如果直接实现Component接口的话就要逐一的去解析协议命名空间,再具体的进行处理。

    由于机器人这个应用中只是简单的自动回复,所以只需要实现handleMessage方法即可。这个方法会自动获取到发送过来的Message数据包。而我们只需要将机器人回复的消息再发回给发送者即可。

    3、将外部组件注册到openfire

    这个比较简单,直接看代码:

    package org.jivesoftware.demo;
    
    import org.jivesoftware.weather.WeatherComponent;
    import org.jivesoftware.whack.ExternalComponentManager;
    import org.xmpp.component.ComponentException;
    
    public class RobotDemoServer {
        public static void main(String[] args) {
            final ExternalComponentManager manager = new ExternalComponentManager("localhost", 5275);
            manager.setSecretKey("robot", "test");
            manager.setMultipleAllowed("robot", true);
            try {
                manager.addComponent("robot", new RobotComponent("robot", manager.getServerName()));
                
                //使程序不要退出
                while (true) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } catch (ComponentException e) {
                e.printStackTrace();
            }
        }
    }

    这里面主要的是ExternalComponentManager,这个类是whack提供的一个用于连接到openfire组件服务的封装类。

    服务器地址和端口中的端口是指外部组件访问端口,这个端口可以在openfire服务器设置。

    setSecretKey是用于设置连接的密码,这个也要根据服务器的设置来填写。

    服务器的设置如下图中:

    然后启动试试吧,向这个机器人发送消息即可。

        public static void TestSendMessage() {        
            Message msg = new Message("test1@robot." + connection.getServiceName());    
            msg.setBody("hello robot");
            try {
                connection.sendStanza(msg);
            } catch (NotConnectedException e) {
                System.err.println("send error." + e.getMessage());
            }
        }
  • 相关阅读:
    3. 动态代理Mapper实现类(官方推荐方式)
    2. MyBatis快速入门
    1.Mybaits底层执行过程
    RabbitMQ安装(windows环境)
    消息中间件(一)MQ详解及四大MQ比较
    Nginx location正则表达式
    SpringBoot
    网络协议--HTTPS
    spring--根据执行jar包的参数使用不同的环境配置
    python读取配置文件模块ConfigParser
  • 原文地址:https://www.cnblogs.com/5207/p/5583745.html
Copyright © 2011-2022 走看看