MQTT協(xié)議通過Apache Apollo代理服務(wù)器摸屠,使用eclipse paho發(fā)送推送消息到android客戶端

前言

MQTT是輕量級基于代理的發(fā)布/訂閱的消息傳輸協(xié)議谓罗,設(shè)計(jì)思想是開放、簡單季二、輕量檩咱、易于實(shí)現(xiàn)。這些特點(diǎn)使它適用于受限環(huán)境胯舷。關(guān)于MQTT的詳細(xì)介紹推薦這篇文章推薦文章

Apache apollo是一個(gè)代理服務(wù)器刻蚯,其是在ActiveMQ基礎(chǔ)上發(fā)展而來的,可以支持STOMP, AMQP, MQTT, Openwire, SSL, and WebSockets 等多種協(xié)議桑嘶。運(yùn)行apollo需要先配置JAVA_HOME
Apollo下載地址

paho是eclipse提供一個(gè)訪問MQTT服務(wù)器的一種開源客戶端庫炊汹,其中提供7種不同平臺的客戶端類庫,今天咱們以java客戶端為例子演示
paho下載地址

apollo使用的時(shí)候需要 配置JAVA_HOME配置成功之后逃顶,命令行指定到bin目錄下讨便,然后輸入apollo create mybroker(圖1)這時(shí)候會(huì)在bin目錄下生成一個(gè)mybroker文件夾(圖2)在mybroker中進(jìn)入bin目錄(圖3)命令行 cd mybroker/bin(圖4)然后輸入apollo-broker run(圖5)顯示成功后打開瀏覽器輸入 http://127.0.0.1:61680 這時(shí)候要是顯示(圖6)界面就證明成功了充甚。用戶名和密碼可以通過myorker/etc 下的users.properties文件中找到默認(rèn)用戶名和密碼是 admin和password.

1.png
2.png
3.png
4.png
5.png
6.png

paho下載完成后進(jìn)入文件夾啟動(dòng)paho.exe(圖7)點(diǎn)擊+號創(chuàng)建服務(wù)器連接(圖8)。服務(wù)器地址在之前創(chuàng)建的mybroker/etc文件夾中打開apollo.xml找到圖9中那一行改成自己本機(jī)的局域網(wǎng)IP地址霸褒。完成后在圖8中服務(wù)器地址中輸入相同的地址和端口伴找,這時(shí)候點(diǎn)擊連接會(huì)提示“連接失敗-錯(cuò)誤的用戶名和密碼”。在選項(xiàng)中需要開啟登錄輸入之前apollo配置的用戶名和密碼(圖10)重新點(diǎn)擊連接這時(shí)候連接狀態(tài)會(huì)顯示已連接(圖11)

7.png
8.png
9.png
10.png
11.png

下面是android客戶端配置

  • module的build.gradle中找到dependencies 然后添加

compile'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1'

compile'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'

后Sync Project with Gradle Files

  • AndroidManifest.xml中添加

<service android:name="org.eclipse.paho.android.service.MqttService"/>

  • 初始化MQTT
public class MQTTService extends Service {

    public static final String TAG = MQTTService.class.getSimpleName();

    private static MqttAndroidClient client;
    private MqttConnectOptions conOpt;
    private String host = "tcp://192.168.100.41:61613";
    private String userName = "admin";
    private String passWord = "password";
    private static String myTopic = "test";
    private String clientId = "clientId";

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        init();
        return super.onStartCommand(intent, flags, startId);
    }

    public static void publish(String msg){
        Integer qos = 0;
        Boolean retained = false;
        try {
            client.publish(myTopic, msg.getBytes(), qos.intValue(), retained.booleanValue());
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    private void init() {
        // 服務(wù)器地址(協(xié)議+地址+端口號)
        client = new MqttAndroidClient(this, host, clientId);
        // 設(shè)置MQTT監(jiān)聽并且接受消息
        client.setCallback(mqttCallback);
        conOpt = new MqttConnectOptions();
        // 清除緩存
        conOpt.setCleanSession(true);
        // 設(shè)置超時(shí)時(shí)間废菱,單位:秒
        conOpt.setConnectionTimeout(10);
        // 心跳包發(fā)送間隔技矮,單位:秒
        conOpt.setKeepAliveInterval(20);
        // 用戶名
        conOpt.setUserName(userName);
        // 密碼
        conOpt.setPassword(passWord.toCharArray());
        boolean doConnect = true;
        String message = "{\"terminal_uid\":\"" + clientId + "\"}";
        Integer qos = 0;
        Boolean retained = false;
        client.getClientId();
        if ((!message.equals("")) || (!myTopic.equals(""))) {
            try {
                //setWill方法,如果項(xiàng)目中需要知道客戶端是否掉線可以調(diào)用該方法昙啄。設(shè)置最終端口的通知消息
                conOpt.setWill(myTopic, message.getBytes(), qos.intValue(), retained.booleanValue());
            } catch (Exception e) {
                doConnect = false;
                iMqttActionListener.onFailure(null, e);
            }
        }

        if (doConnect) {
            doClientConnection();
        }

    }

    @Override
    public void onDestroy() {
        try {
            client.disconnect();
        } catch (MqttException e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }

    /** 連接MQTT服務(wù)器 */
    private void doClientConnection() {
        if (!client.isConnected() && isConnectIsNomarl()) {
            try {
                client.connect(conOpt, null, iMqttActionListener);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }

    }

    // MQTT是否連接成功
    private IMqttActionListener iMqttActionListener = new IMqttActionListener() {

        @Override
        public void onSuccess(IMqttToken arg0) {
            Log.i(TAG, "連接成功 ");
            try {
                // 訂閱myTopic話題
                client.subscribe(myTopic,1);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(IMqttToken arg0, Throwable arg1) {
            arg1.printStackTrace();
            // 連接失敗穆役,重連
            Log.i(TAG, "連接失敗 ");
        }
    };

    // MQTT監(jiān)聽并且接受消息
    private MqttCallback mqttCallback = new MqttCallback() {

        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {

            String str1 = new String(message.getPayload());
            MQTTMessage msg = new MQTTMessage();
            msg.setMessage(str1);
            EventBus.getDefault().post(msg);
            String str2 = topic + ";qos:" + message.getQos() + ";retained:" + message.isRetained();
            Log.i(TAG, "messageArrived:" + str1);
            Log.i(TAG, str2);
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken arg0) {

        }

        @Override
        public void connectionLost(Throwable arg0) {
            // 失去連接,重連
            Toast.makeText(MQTTService.this, " 失去連接梳凛,重連", Toast.LENGTH_SHORT).show();
        }
    };

    /** 判斷網(wǎng)絡(luò)是否連接 */
    private boolean isConnectIsNomarl() {
        ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = connectivityManager.getActiveNetworkInfo();
        if (info != null && info.isAvailable()) {
            String name = info.getTypeName();
            Log.i(TAG, "MQTT當(dāng)前網(wǎng)絡(luò)名稱:" + name);
            return true;
        } else {
            Log.i(TAG, "MQTT 沒有可用網(wǎng)絡(luò)");
            return false;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

最后通過Paho發(fā)布消息 客戶端就能收到推送過來的內(nèi)容了耿币!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市韧拒,隨后出現(xiàn)的幾起案子淹接,更是在濱河造成了極大的恐慌,老刑警劉巖叛溢,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件塑悼,死亡現(xiàn)場離奇詭異,居然都是意外死亡楷掉,警方通過查閱死者的電腦和手機(jī)厢蒜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烹植,“玉大人斑鸦,你說我怎么就攤上這事〔莸瘢” “怎么了巷屿?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長墩虹。 經(jīng)常有香客問我嘱巾,道長,這世上最難降的妖魔是什么诫钓? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任旬昭,我火速辦了婚禮,結(jié)果婚禮上菌湃,老公的妹妹穿的比我還像新娘稳懒。我一直安慰自己,他們只是感情好慢味,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布场梆。 她就那樣靜靜地躺著,像睡著了一般纯路。 火紅的嫁衣襯著肌膚如雪或油。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天驰唬,我揣著相機(jī)與錄音顶岸,去河邊找鬼。 笑死叫编,一個(gè)胖子當(dāng)著我的面吹牛辖佣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播搓逾,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼卷谈,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了霞篡?” 一聲冷哼從身側(cè)響起世蔗,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎朗兵,沒想到半個(gè)月后污淋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡余掖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年寸爆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盐欺。...
    茶點(diǎn)故事閱讀 40,110評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡赁豆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出找田,到底是詐尸還是另有隱情歌憨,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布墩衙,位于F島的核電站务嫡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏漆改。R本人自食惡果不足惜心铃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望挫剑。 院中可真熱鬧去扣,春花似錦、人聲如沸樊破。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至奔滑,卻和暖如春艾岂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背朋其。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工王浴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人梅猿。 一個(gè)月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓氓辣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親袱蚓。 傳聞我的和親對象是個(gè)殘疾皇子钞啸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評論 2 355