1. 程式人生 > >Mqtt for Java 客戶端訂閱及多執行緒UI展示

Mqtt for Java 客戶端訂閱及多執行緒UI展示

最近需要用mqtt做一個小程式,感測器釋出客戶端暫時不考慮,需要完成一個mqtt訂閱客戶端來實時接收感測器端發來的資訊,因為mqtt有現成的java第三方,所以選擇用java來完成,而在寫碼過程中發現訂閱資訊的回撥函式如果用單執行緒釋出這些資訊,會造成回撥函式阻塞,從而造成連線中斷,為了解決這個問題,首先想到的是用多執行緒將UI分隔出去,這些方法就有很多了,我因為時間關係,選擇使用簡單的共享全域性變數的方法來實現這個功能,回撥函式中實時更新全域性變數,UI再按時顯示這個變數即可。

專案是建立的maven專案,檔案結構如下:


每個檔案功能分別如下:

Client:實現連線mqtt代理伺服器功能

Constant:儲存全域性變數,並被PushCallback和UI讀寫

MyThread:控制UI,以及定時顯示當前資訊

PushCallback:接收伺服器發來的資訊

UI:建立UI並展示資訊

主要程式碼如下所示:

MyThread檔案如下,實現定時2s顯示一次功能以及UI建立

public class MyThread extends Thread {

    private Client client;
    private UI ui;

    public MyThread(Client client) {
        this.client = client;
        ui = new UI(client);
    }

    public void run() {
        final long timeInterval = 2000;
        Runnable runnable = new Runnable() {
            public void run() {
                while (true) {
                    updateInfo();
                    try {
                        Thread.sleep(timeInterval);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }

    private void updateInfo() {
        if(Constant.info==null) return;
        ui.showInfo(Constant.info);
    }
}

PushCallback中的資訊接收函式如下:

public void messageArrived(String topic, MqttMessage message) throws Exception {
        // subscribe後得到的訊息會執行到這裡面
        String msg=new String(message.getPayload());
        System.out.println("接收訊息主題 : " + topic);
        System.out.println("接收訊息Qos : " + message.getQos());
        System.out.println("接收訊息內容 : " + msg);
        Constant.info=msg;
    }

其餘程式碼不一一展示,類似的demo有很多