====== 快速使用MQTT Flutter版 SDK实现消息收发 ====== ===== 1. 前提条件 ===== ==== 1.1 部署Flutter开发环境 ==== 配置好Flutter开发环境。 ==== 1.2 导入项目依赖 ==== 在yaml文件里配置 mqtt_client: ^9.8.1 在iOS开发中需要增加一下代码到位于**ios/Runner/Info.plist**中的**Info.plist***文件中: NSLocalNetworkUsageDescription Looking for local tcp Bonjour service NSBonjourServices mqtt.tcp ==== Android ==== Android **AndroidManifest.xml** 增加如下代码 ===== 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"; } [[https://docs-im.easemob.com/_detail/playground/message/setting.jpg?id=mqtt%3Aqsandroidsdk|{{https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ef6db705001d4e4a8073b8489678a47e~tplv-k3u1fbpfcp-zoom-1.image|img}}]] [[https://docs-im.easemob.com/_detail/playground/message/develop.jpg?id=mqtt%3Aqsandroidsdk|{{https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/03d32d7bfaba44f68a8aa2abc584d4b9~tplv-k3u1fbpfcp-zoom-1.image|img}}]] ==== 2.2 获取token ==== * 首先获取App Token Dio dio = Dio(); Response> data = await dio.post("${restapi}openapi/rm/app/token",data: {"appClientId": appClientId, "appClientSecret": appClientSecret}); var token = (data.data!["body"] as Map )["access_token"]; * 然后根据App Token获取User Token,User Token作为连接服务的密码 Response> data2 = await dio.post("${restapi}openapi/rm/user/token",data: {"username": "username", "cid": clientID},options: Options(headers: {r'Authorization': token})); var mqtttoken = (data2.data!["body"] as Map )["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)}"); });