針對 MQTT 的常用平臺澎媒,推薦對應(yīng)的第三方包如表 1?所示:
https://help.aliyun.com/document_detail/44866.html?spm=a2c4g.11186623.6.559.3a7d3d26JKCSDc
Android ? ? ? Eclipse Paho SDK ? ? ??https://github.com/eclipse/paho.mqtt.android
如下圖:
使用MQTT使用到的幾點(diǎn)
1樊诺、topic管理(也就是消息主題)
2、生產(chǎn)者管理(消息的發(fā)送者鹅巍,也就是服務(wù)端發(fā)送的數(shù)據(jù))
3千扶、消費(fèi)者管理(消息的接收者,也就是移動端接收的數(shù)據(jù))
4骆捧、實(shí)例管理
5澎羞、Group?Id管理
附上圖片:
以上這些一般都是后臺人員進(jìn)行創(chuàng)建,但是在測試階段敛苇,移動端開發(fā)人員也會自己去創(chuàng)建一個(gè)測試的實(shí)例進(jìn)行測試使用妆绞,所以此部分也是需要了解的,具體創(chuàng)建參考官方文檔即可。
自行寫DEMO工程:
根據(jù)官方教程:加上以下依賴:
repositories {
? ? maven {
? ? ? ? url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
? ? }
}
dependencies {
? ? compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
? ? compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
}
添加權(quán)限括饶,注冊service
<service android:name=".mqtt.service.MqttService" />
然后自行寫一個(gè)后臺服務(wù)去進(jìn)行MQTT服務(wù)連接株茶。
在github上下載下來的項(xiàng)目包含三個(gè)文件,如圖所示:
1巷帝、paho.mqtt.android.example?這個(gè)是我們需要使用到的接收消息的demo
2忌卤、org.eclipse.paho.android.service?這個(gè)是我們接收使用到的service的? library
3扫夜、org.eclipse.paho.android.sample?這個(gè)是模擬發(fā)送的demo(這里我沒有使用楞泼,而是使用后臺的發(fā)送代碼或者官網(wǎng)上生產(chǎn)者那里的發(fā)送進(jìn)行發(fā)送消息,就不做說明了)
具體代碼可參考:paho.mqtt.android.example
下面對修改后的參數(shù)進(jìn)行說明一下:
1笤闯、serverUri?服務(wù)器的域名加端口?例如:tcp://xxx:1883?因?yàn)椴荒苄孤兑恍?shù)據(jù)堕阔,所以使用xxx代替了,具體的地址則是在MQTT管理----》實(shí)例管理下的接入點(diǎn)域名颗味,復(fù)制的接入點(diǎn)域名即是xxx了超陆,注意,tcp還是需要的哦浦马,接入點(diǎn)域名只是xxx的那一部分时呀。
2、groupId? groupId可在?MQTT管理----》Group?Id管理中獲取到晶默,這個(gè)id是需要自己創(chuàng)建的谨娜。
3、topic?主題(注意:主題是需要一致的)
4磺陡、clientId?客戶端id趴梢,clientId?是由groupId +@@@+設(shè)備名。設(shè)備名可以隨便取币他,但是客戶端id有長度限制坞靶,具體長度限制可查看官方文檔。
5蝴悉、accessKey?與secretKey? 這兩也是需要自己創(chuàng)建彰阴,在創(chuàng)建完成后需要保存好。
以上代碼能進(jìn)行接收的主要區(qū)別是以下這段代碼:
String sign = null;
try {
? ? sign = MacSignature.macSignature(clientId.split("@@@")[0], secretKey);
} catch (InvalidKeyException e) {
? ? e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
? ? e.printStackTrace();
}
mqttConnectOptions.setUserName(accessKey);
mqttConnectOptions.setPassword(sign.toCharArray());
mqttConnectOptions.setCleanSession(cleanSession);
mqttConnectOptions.setKeepAliveInterval(90);
mqttConnectOptions.setAutomaticReconnect(true);
mqttConnectOptions默認(rèn)構(gòu)造器屬性拍冠,userName和password找后臺要尿这。
代碼掠影:
Service里代碼:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
init();
? ? return super.onStartCommand(intent, flags, startId);
}
/**
* MQTT服務(wù)連接
*/
public void connectToNet(){
MqttConnectOptions mqttConnectOptions =new MqttConnectOptions();
? ? String sign =null;
? ? try {
sign =macSignature(clientId, secretKey);
? ? }catch (InvalidKeyException e) {
e.printStackTrace();
? ? }catch (NoSuchAlgorithmException e) {
e.printStackTrace();
? ? }
mqttConnectOptions.setUserName("Signature|" +accessKey +"|" +instanceId);
? ? mqttConnectOptions.setPassword(sign.toCharArray());
? ? mqttConnectOptions.setCleanSession(false);
? ? mqttConnectOptions.setKeepAliveInterval(90);
? ? mqttConnectOptions.setAutomaticReconnect(true);
? ? mqttConnectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
? ? mqttConnectOptions.setConnectionTimeout(5000);
? ? try {
mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
@Override
? ? ? ? ? ? public void onSuccess(IMqttToken asyncActionToken) {
DisconnectedBufferOptions disconnectedBufferOptions =new DisconnectedBufferOptions();
? ? ? ? ? ? ? ? disconnectedBufferOptions.setBufferEnabled(true);
? ? ? ? ? ? ? ? disconnectedBufferOptions.setBufferSize(100);
? ? ? ? ? ? ? ? disconnectedBufferOptions.setPersistBuffer(false);
? ? ? ? ? ? ? ? disconnectedBufferOptions.setDeleteOldestMessages(false);
? ? ? ? ? ? ? ? mqttAndroidClient.setBufferOpts(disconnectedBufferOptions);
? ? ? ? ? ? ? ? subscribeToTopic();
? ? ? ? ? ? }
@Override
? ? ? ? ? ? public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.e("yyyy","onFailure:"+exception.getMessage());
? ? ? ? ? ? }
});
? ? }catch (MqttException ex){
ex.printStackTrace();
? ? }
}
/**
* @param text? ? ? 要簽名的文本
* @param secretKey 阿里云MQ secretKey
* @return 加密后的字符串
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
*/
public static StringmacSignature(String text, String secretKey)throws InvalidKeyException, NoSuchAlgorithmException {
Charset charset = Charset.forName("UTF-8");
? ? String algorithm ="HmacSHA1";
? ? Mac mac = Mac.getInstance(algorithm);
? ? mac.init(new SecretKeySpec(secretKey.getBytes(charset), algorithm));
? ? byte[] bytes = mac.doFinal(text.getBytes(charset));
? ? return new String(Base64.encodeBase64(bytes), charset);
}
public void subscribeToTopic(){
try {
mqttAndroidClient.subscribe(subscriptionTopic, 0, null, new IMqttActionListener() {
@Override
? ? ? ? ? ? public void onSuccess(IMqttToken asyncActionToken) {
Log.e("yyyy","subscriptionTopic is onsuccess");
? ? ? ? ? ? }
@Override
? ? ? ? ? ? public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.e("yyyy","subscriptionTopic is onFailure");
? ? ? ? ? ? }
});
? ? ? ? // THIS DOES NOT WORK!
? ? ? ? mqttAndroidClient.subscribe(subscriptionTopic, 0, new IMqttMessageListener() {
@Override
? ? ? ? ? ? public void messageArrived(String topic, MqttMessage message)throws Exception {
// message Arrived!
? ? ? ? ? ? ? ? Log.e("yyyy","subscriptionTopic message Arrived"+ message.toString());
? ? ? ? ? ? }
});
? ? }catch (MqttException ex){
System.err.println("Exception whilst subscribing");
? ? ? ? ex.printStackTrace();
? ? }
}
@Override
public void onDestroy() {
try {
mqttAndroidClient.disconnect(); //斷開連接
? ? }catch (MqttException e) {
e.printStackTrace();
? ? }
super.onDestroy();
}
參數(shù)配置:
private StringserverUri ="tcp://*************************";
private StringclientId ="GID_DEVICE_PUSH@@@device_sn_1";
StringaccessKey ="**************";
StringsecretKey ="**********************";
StringinstanceId ="mqtt-cn-v0h14cnqw02";
final StringsubTopic ="/mq4Iot";
final StringsubscriptionTopic ="DEVICE_PUSH_MQ" +subTopic;
private static MqttAndroidClientmqttAndroidClient;
以上,即可倦微,更多度娘F尬丁!P栏!T鹎颉!