采用环信免费mqtt,快速使用MQTT Flutter版 SDK实现消息收发

111 阅读1分钟

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>{"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)}");
});