Android使用MQTT實現訊息釋出與訂閱
關於MQTT
MQTT(Message Queuing Telemetry Transport,訊息佇列遙測傳輸)是IBM開發的一個即時通訊協議,有可能成為物聯網的重要組成部分。該協議支援所有平臺,幾乎可以把所有聯網物品和外部連線起來,被用來當做感測器和制動器(比如通過Twitter讓房屋聯網)的通訊協議。
MQTT應用
通過MQTT協議,目前已經擴展出了數十個MQTT伺服器端程式,可以通過PHP,JAVA,Python,C,C#等系統語言來向MQTT傳送相關訊息。國內很多企業都廣泛使用MQTT作為Android手機客戶端與伺服器端推送訊息的協議,隨著移動網際網路的發展,MQTT由於開放原始碼,耗電量小等特點,將會在移動訊息推送領域會有更多的貢獻,在物聯網領域,感測器與伺服器的通訊,資訊的收集,MQTT都可以作為考慮的方案之一。在未來MQTT會進入到我們生活的各各方面。
MQTT特點
1、使用釋出/訂閱訊息模式,提供一對多的訊息釋出,解除應用程式耦合;
2、對負載內容遮蔽的訊息傳輸;
3、使用 TCP/IP 提供網路連線;
4、有三種訊息釋出服務質量:“至多一次”,訊息釋出完全依賴底層 TCP/IP 網路。會發生訊息丟失或重複。這一級別可用於如下情況,環境感測器資料,丟失一次讀記錄無所謂,因為不久後還會有第二次傳送。“至少一次”,確保訊息到達,但訊息重複可能會發生。“只有一次”,確保訊息到達一次。這一級別可用於如下情況,在計費系統中,訊息重複或丟失會導致不正確的結果。
5、小型傳輸,開銷很小(固定長度的頭部是 2 位元組),協議交換最小化,以降低網路流量;
6、使用 Last Will 和 Testament 特性通知有關各方客戶端異常中斷的機制;
MQTT Android中使用
MainActivity程式碼:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private String mClintId; public static MqttClient mMqClint; public MqttConnectOptions mMqttConnectOptions; private ScheduledExecutorService scheduler; private final staticString TAG = MainActivity.class.getSimpleName(); private Button mBtSub,mBtSend; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtSub = this.findViewById(R.id.bt_sub); mBtSend = this.findViewById(R.id.bt_send); mBtSend.setOnClickListener(this); mBtSub.setOnClickListener(this); initMqtt(); } /** * 初始化mqtt */ private void initMqtt() { StringBuffer sb = new StringBuffer(); sb.append(System.currentTimeMillis()); sb.append(RandomStringUtil.getInstance().RandomStringUtil()); mClintId = sb.toString(); try { mMqClint = new MqttClient(Constant.HOST, mClintId, new MemoryPersistence()); mMqttConnectOptions = new MqttConnectOptions(); //清除快取 mMqttConnectOptions.setCleanSession(true); //設定使用者名稱 mMqttConnectOptions.setUserName(Constant.USERNAME); //設定使用者密碼 mMqttConnectOptions.setPassword(Constant.USERPASSWORD.toCharArray()); // 設定超時時間,單位:秒 mMqttConnectOptions.setConnectionTimeout(10); // 心跳包傳送間隔,單位:秒 mMqttConnectOptions.setKeepAliveInterval(20); //設定回撥 mMqClint.setCallback(new PushCallBack()); //MqttTopic topic = client.getTopic(ConnectUrl.SUBSCRIBETOPIC); //options.setWill(topic, "close".getBytes(), 0, true); //訂閱訊息 connect(); } catch (MqttException e) { e.printStackTrace(); } } /** * mqtt連結 */ public void connect() { ThreadTask.getInstance().executorOtherThread(new Runnable() { @Override public void run() { try { if (mMqClint != null) { //開始連結 mMqClint.connect(mMqttConnectOptions); } } catch (Exception e) { e.printStackTrace(); } } }, ThreadTask.ThreadPeriod.PERIOD_HIGHT); } /** * 定時檢查mqtt是否連線 */ private void startReconnect() { scheduler = Executors.newSingleThreadScheduledExecutor(); scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { if (!mMqClint.isConnected()) { connect(); } } }, 0 * 1000, 10 * 1000, TimeUnit.MILLISECONDS); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.bt_sub: if (mMqClint.isConnected()){ try { mMqClint.subscribe(Constant.SUBSCRIBETOPIC,0); } catch (MqttException e) { e.printStackTrace(); } } break; case R.id.bt_send: MqttTopic topic = mMqClint.getTopic(Constant.SENDPIC); MqttMessage message = new MqttMessage(); message.setPayload("要傳送的訊息".getBytes()); try { topic.publish(message); } catch (MqttException e) { e.printStackTrace(); } break; } } public static class PushCallBack implements MqttCallback { @Override public void connectionLost(Throwable throwable) { Log.i(TAG, "connectionLost: 連結丟失"); } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { Log.i(TAG, "messageArrived: 接收訊息回撥"); } @Override public void deliveryComplete(IMqttDeliveryToken token) { Log.i(TAG, "deliveryComplete: 釋出訊息回撥"); } } }xml佈局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:orientation="vertical" android:layout_height="match_parent" tools:context="cn.puming.struggle.mqttdemo.MainActivity"> <Button android:id="@+id/bt_sub" android:layout_width="match_parent" android:layout_height="48dp" android:text="開始訂閱!"/> <Button android:id="@+id/bt_send" android:layout_width="match_parent" android:layout_height="48dp" android:text="傳送訊息!" /> </LinearLayout>Manifest申請網路許可權:
<uses-permission android:name="android.permission.INTERNET"/>Demo下載地址:https://download.csdn.net/download/zhuhuitao_struggle/10421853