文章出處

在之前的文章《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());
        }
    }

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()