Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android IM之基於Openfire+Smack的聊天服務器的搭建與測試

Android IM之基於Openfire+Smack的聊天服務器的搭建與測試

編輯:關於Android編程

XMPP協議(Extensible Messaging and PresenceProtocol,可擴展消息處理現場協議)是一種基於XML的協議,目的是為了解決及時通信標准而提出來的,最早是在Jabber上實現的。它繼承了在XML環境中靈活的發展性。因此,基於XMPP的應用具有超強的可擴展性。並且XML很易穿過防火牆,所以用XMPP構建的應用不易受到防火牆的阻礙。利用XMPP作為通用的傳輸機制,不同組織內的不同應用都可以進行有效的通信。

先來了解幾個概念

Openfire主要是作為服務器,負責管理客戶端的通信連接,以及提供客戶端一些通信信息和連接信息。

Smack主要是xmpp協議的實現,提供了一套很好的api,所以下面操作xmpp都是通過使用Smack的api來實現,從4.1.0開始,它就支持Android了,所以我們直接使用Smack即可,當然在這不支持之前是使用Asmack這個包的,裡面方法跟smack包差不多。

Spark 是IM客戶端的實現,其實就是使用了Smack 的api實現的。

 

這裡寫圖片描述

第二個是一套基於XMPP實現的API,我們直接引用其即可,在Android Studio中,我們直接在gradle中添加依賴即可。

    compile 'org.igniterealtime.smack:smack-android-extensions:4.1.4'
    compile 'org.igniterealtime.smack:smack-tcp:4.1.4'

然後我們需要添加網絡權限

    

接下來我們先不管android端,我們先進行兩個軟件的安裝。首先安裝openfire.

點擊安裝包打開進行初始化

這裡寫圖片描述

選擇語言,這裡選擇中文

這裡寫圖片描述

確定後再點下一步

這裡寫圖片描述

同意許可點擊下一步

這裡寫圖片描述

選擇安裝目錄點擊下一步,這裡是默認目錄<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxpbWcgYWx0PQ=="這裡寫圖片描述" src="/uploadfile/Collfiles/20150928/201509280853358.png" title="\" />

繼續下一步

這裡寫圖片描述

耐心等待文件解壓完成

這裡寫圖片描述

點擊完成後運行Openfire

這裡寫圖片描述

運行成功後點擊Launch Admin進入後台完成剩下的安裝工作

這裡寫圖片描述

選擇語言

這裡寫圖片描述
服務器配置,我們將域修改為本機的局域網IP地址

我們需要獲得我們電腦的IP地址。

這裡寫圖片描述

獲得的IP地址為10.0.0.24,將域修改為這個值

這裡寫圖片描述

數據庫我們選擇使用外部數據庫,所以勾選第一個

這裡寫圖片描述

接下來就是一些值,第一項的下拉選擇mysql,之後值會被填充。接下來我們就需要在mysql中添加一個數據庫。

這裡寫圖片描述

這裡假設你的本地有mysql服務器,打開後台,添加一個用戶,勾選創建與用戶名同名的數據庫並授予所有權限

這裡寫圖片描述

把database name和hostname修改成對應的值,用戶名和密碼為你剛才mysql中創建的用戶和密碼

這裡寫圖片描述

選擇初始設置

這裡寫圖片描述

設置openfire管理員賬號密碼,這裡賬號設置為admin,密碼自己設置

這裡寫圖片描述

點擊登錄到管理控制台

這裡寫圖片描述

進入到後台,輸入賬號密碼進行登陸

這裡寫圖片描述

登陸成功後就是後台了

這裡寫圖片描述

然後安裝Spark,點擊下載的安裝包

這裡寫圖片描述

選擇安裝目錄

這裡寫圖片描述

點擊下一步

這裡寫圖片描述

繼續點擊下一步

這裡寫圖片描述

等待安裝完成

這裡寫圖片描述

點擊finish運行spark

這裡寫圖片描述

使用我們的管理員賬號admin進行登陸,服務器為本地,127.0.0.1

這裡寫圖片描述

如果登陸成功了就會出現下面的界面

這裡寫圖片描述

然後我們添加兩個測試賬號,在openfire後台,輸入這些信息進行添加用戶

這裡寫圖片描述

添加了兩個測試賬號,分別為test和test1

這裡寫圖片描述

接下來最重要的事就是Android端了,在這之前,我們需要讓我們的手機和電腦出於同一個局域網內,如果你使用的是模擬器,那麼,不存在這個問題。

獲得的IP地址為10.0.0.24,接下來就是編寫代碼進行登陸了。

獲得一個連接

 private XMPPTCPConnection getConnection(){
        String server=10.0.0.24;
        int port=5222;
        XMPPTCPConnectionConfiguration.Builder builder = XMPPTCPConnectionConfiguration.builder();
        builder.setServiceName(server);
        builder.setHost(server);
        builder.setPort(port);
        builder.setCompressionEnabled(false);
        builder.setDebuggerEnabled(true);
        builder.setSendPresence(true);
        builder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
        XMPPTCPConnection connection = new XMPPTCPConnection(builder.build());
        return connection;
    }

初始化變量

private EditText account, password,to,content;
private Button login,logout,send;
private  XMPPTCPConnection connection;

connection=getConnection();

account = (EditText) findViewById(R.id.account);
password = (EditText) findViewById(R.id.password);
to = (EditText) findViewById(R.id.to);
content = (EditText) findViewById(R.id.content);
login = (Button) findViewById(R.id.login);
logout = (Button) findViewById(R.id.logout);
send = (Button) findViewById(R.id.send);
login.setOnClickListener(this);
logout.setOnClickListener(this);
send.setOnClickListener(this);

對應的點擊事件的實現,也就是登陸,登出,發送消息的邏輯

@Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.login:{
                final String a = account.getText().toString();
                final String p = password.getText().toString();
                if (TextUtils.isEmpty(a) || TextUtils.isEmpty(p)) {
                    Toast.makeText(getApplicationContext(), 賬號或密碼不能為空, Toast.LENGTH_LONG).show();
                    return;
                }
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            connection.connect();
                            connection.login(a, p);
                            Presence presence = new Presence(Presence.Type.available);
                            presence.setStatus(我是在線狀態);
                            connection.sendStanza(presence);
                            ChatManager chatmanager = ChatManager.getInstanceFor(connection);
                            chatmanager.addChatListener(new ChatManagerListener() {
                                @Override
                                public void chatCreated(Chat chat, boolean createdLocally) {
                                    chat.addMessageListener(new ChatMessageListener() {
                                        @Override
                                        public void processMessage(Chat chat, Message message) {
                                            String content=message.getBody();
                                            if (content!=null){
                                                Log.e(TAG, from: + message.getFrom() +  to: + message.getTo() +  message: + message.getBody());
                                                android.os.Message message1= android.os.Message.obtain();
                                                message1.what=1;
                                                message1.obj=收到消息: + message.getBody()+ 來自:+message.getFrom();
                                                mHandler.sendMessage(message1);
                                            }

                                        }
                                    });
                                }
                            });
                        } catch (SmackException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (XMPPException e) {
                            e.printStackTrace();
                        }

                    }
                }).start();
                break;
            }
            case R.id.logout:
                connection.disconnect();
                break;
            case R.id.send:
                final String t = to.getText().toString();
                final String c = content.getText().toString();
                if (TextUtils.isEmpty(t)||TextUtils.isEmpty(c)) {
                    Toast.makeText(getApplicationContext(), 接收方或內容, Toast.LENGTH_LONG).show();
                    return;
                }

                try {
                    ChatManager chatmanager = ChatManager.getInstanceFor(connection);
                    Chat mChat = chatmanager.createChat([email protected]);
                    mChat.sendMessage(c);
                }
                catch (SmackException.NotConnectedException e) {
                    e.printStackTrace();
                }
                break;
        }

    }

收到消息後需要在主線程裡操作,簡單的Toast一下

private Handler mHandler=new Handler(){
    @Override
    public void handleMessage(android.os.Message msg) {
        switch (msg.what){
            case 1:
                Toast.makeText(getApplicationContext(),msg.obj+,Toast.LENGTH_SHORT).show();
                break;
        }
        super.handleMessage(msg);
    }
};

這時候如果你使用測試賬號進行登陸,你會發現登陸不了,會報一個錯誤

這裡寫圖片描述

解決方法也比較簡單,到Openfire的安裝目錄中,尋找conf/openfire.xml文件

這裡寫圖片描述

在最後一個節點閉合前加入代碼

  
     PLAIN 
  

這裡寫圖片描述

重啟OpenFire,這時候你會發現成功登陸了,並能正常的設置用戶的在線狀態了

這裡寫圖片描述

將我們的Spark使用測試賬號test1登陸,Android端使用test登陸,測試消息是否能成功送到。

這裡寫圖片描述源碼。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved