快速使用MQTT Flutter版 SDK实现消息收发
1. 前提条件
1.1 部署Flutter开发环境
配置好Flutter开发环境。
1.2 导入项目依赖
在yaml文件里配置
mqtt_client: ^9.8.1
在iOS开发中需要增加一下代码到位于ios/Runner/Info.plist中的Info.plist*文件中:
<key>NSLocalNetworkUsageDescription</key>
<string>Looking for local tcp Bonjour service</string>
<key>NSBonjourServices</key>
<array>
<string>mqtt.tcp</string>
</array>
Android
Android AndroidManifest.xml 增加如下代码
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
2. 实现流程
2.1 获取初始化信息
登录console后台
1.点击菜单栏【MQTT】→【服务概览】→【服务配置】,获取「连接地址」、「连接端口」、「AppID」以「及REST API地址」等信息。
注:clientID由两部分组成,组织形式为“deviceID@AppID”,deviceID由用户自定义,AppID见【服务配置】。
示例:正确的clientID格式为:“device001@aitbj0”;
2.点击菜单栏【应用概览】→【应用详情】→【开发者ID】,获取「Client ID」与「ClientSecret」信息。
3.初始化代码
static const String restapi= "https://api.cn1.mqtt.chat/app/$appID/"; //环信MQTT REST API地址 通过console后台[MQTT]->[服务概览]->[服务配置]下[REST API地址]获取
static const String endpoint= "**"; //环信MQTT服务器地址 通过console后台[MQTT]->[服务概览]->[服务配置]下[连接地址]获取
static const int port = **; // 协议服务端口 通过console后台[MQTT]->[服务概览]->[服务配置]下[连接端口]获取
static const String appID= "**"; // appID 通过console后台[MQTT]->[服务概览]->[服务配置]下[AppID]获取
static late String deviceId ;// 自定义deviceID
static late String clientID ;// deviceId + '@' + appID
static const String appClientId= "**"; //开发者ID 通过console后台[应用概览]->[应用详情]->[开发者ID]下[ Client ID]获取
static const String appClientSecret= "**"; // 开发者密钥 通过console后台[应用概览]->[应用详情]->[开发者ID]下[ ClientSecret]获取
static void init() async{
deviceId = "deviceId";
clientID = "$deviceId@$appID";
}
2.2 获取token
- 首先获取App Token
Dio dio = Dio();
Response<Map<String,dynamic>> data = await dio.post("${restapi}openapi/rm/app/token",data: {"appClientId": appClientId, "appClientSecret": appClientSecret});
var token = (data.data!["body"] as Map<String, dynamic> )["access_token"];
- 然后根据App Token获取User Token,User Token作为连接服务的密码
Response<Map<String,dynamic>> data2 = await dio.post("${restapi}openapi/rm/user/token",data: {"username": "username", "cid": clientID},options: Options(headers: <String, dynamic>{r'Authorization': token}));
var mqtttoken = (data2.data!["body"] as Map<String, dynamic> )["access_token"];
2.3 连接服务器
创建MqttAndroidClient对象,并配置连接密码、cleansession标志、心跳间隔、超时时间等信息,调用connect()函数连接至环信MQTT消息云。
var client = MqttServerClient.withPort(endpoint, clientID, port);
/// 是否打印mqtt日志信息
client.logging(on: true);
/// 设置协议版本,默认是3.1,根据服务器需要的版本来设置
/// _client.setProtocolV31();
client.setProtocolV311();
/// 保持连接ping-pong周期。默认不设置时关闭。
client.keepAlivePeriod = 60;
/// 设置自动重连
client.doAutoReconnect();
/// 设置超时时间,单位:毫秒
client.connectTimeoutPeriod = 60000;
/// 连接成功回调
client.onConnected = _onConnected;
/// 连接断开回调
client.onDisconnected = _onDisconnected;
/// 取消订阅回调
client.onUnsubscribed = _onUnsubscribed;
/// 订阅成功回调
client.onSubscribed = _onSubscribed;
/// 订阅失败回调
client.onSubscribeFail = _onSubscribeFail;
/// ping pong响应回调
client.pongCallback = _pong;
client.connect(username,mqtt_token);
static void _onConnected() {
LogManager.log.d("连接成功....");
_initTopic();
}
static void _onDisconnected() {
LogManager.log.d("连接断开");
}
static void _onUnsubscribed(String? topic) {
LogManager.log.d("取消订阅 $topic");
}
static void _onSubscribed(String topic) {
LogManager.log.d("订阅 $topic 成功");
}
static void _onSubscribeFail(String topic) {
LogManager.log.e("订阅主题: $topic 失败");
}
static void _pong() {
LogManager.log.d("Ping的响应");
}
2.4 订阅(subscribe)
2.4.1 订阅主题
当客户端成功连接环信MQTT消息云后,需尽快向服务器发送订阅主题消息。在连接成功后调用
client.subscribe(topic, MqttQos.atLeastOnce);
2.4.2 取消订阅
_client?.unsubscribe(topic)
2.5 收发消息
2.5.1 发送消息
配置发送消息回调方法,向环信MQTT消息云中指定topic发送消息。
var builder = MqttClientPayloadBuilder();
builder.addUTF8String("This is a message");
client.publishMessage("topic", MqttQos.atLeastOnce, builder.payload!);
2.5.2 接收消息
配置接收消息回调方法,从环信MQTT消息云接收订阅消息。
_client?.updates?.listen((event) {
var recvMessage = event[0].payload as MqttPublishMessage;
LogManager.log.d("原始数据-----:${recvMessage.payload.message}");
/// 转换成字符串
LogManager.log.d(
"接收到了主题${event[0].topic}的消息: ${const Utf8Decoder().convert(recvMessage.payload.message)}");
});