乐趣区

关于mqtt:CocoaMQTT-v20首个支持-MQTT-50-的-iOS-客户端

2017 年 8 月,OASIS MQTT Technical Committee 正式公布了用于 Public Review 的 MQTT 5.0 的草案。2018 年,MQTT 5.0 正式公布,然而直到目前苹果生态里仍没有残缺反对 MQTT 5.0 的客户端 SDK。

CocoaMQTT 是 EMQ 团队为 iOS 开发者提供的 MQTT 客户端 SDK,目前在 iOS 开发者中有着较为宽泛的应用。

为补救苹果生态中对 MQTT 5.0 反对方面的空白,EMQ 团队于近日正式公布了 CocoaMQTT 全新版本 v2.0。CocoaMQTT v2.0 反对 MQTT 5.0,同时兼容 3.1.1 版本,反对 iOS、tvOS 与 OSX 操作系统。用户现已可通过 CocoaMQTT 实现 iOS 零碎设施连贯 MQTT 5.0 云服务,享受 MQTT 5.0 带来的弱小性能加成。

CocoaMQTT 应用 Swift 语言开发,而非 Objective-C。这是因为 Swift 是一门类型平安的语言,对协定的反对更加丰盛,配合扩大(extension)、泛型、关联类型等能够实现面向协定编程,从而大大提高代码的灵活性。

此外,在 WWDC 2021 大会上,苹果发表了 Swift 语言中并发模型的重大更新:通过编译器实现的 Actor 并发模型,新增 Actor 援用类型帮忙开发者防止数据竞争问题。

因而,咱们置信在 MQTT 相干的 I/O 密集型并发利用中,相较于 Objective-C,Swift 的体现将更值得期待。

MQTT 5.0 vs MQTT 3.1.1

MQTT 3.1.1 依然有很多不欠缺的中央,例如连贯异样断开时无奈告诉起因到对端。MQTT 5.0 在 MQTT 3.1.1 的根底上做了很多扭转,但并不是向下兼容的。

MQTT 协定 5.0 版本新增了会话 / 音讯延时性能、起因码、主题别名、in-flight 流控、用户属性、共享订阅等性能,以及用于加强认证平安的 AUTH 报文。其中,起因码和用户属性 Property 字段使得 MQTT 5.0 可能携带更多上下文信息,从而解决在 3.1.1 版本因协定不残缺而较难解决的问题。

MQTT 5.0 的次要性能劣势有:

  • 进一步反对更大规模的可扩大零碎
  • 更加具体的错误报告和解决机制
  • 容量摸索和申请响应等通用模式的规范化操作
  • 可扩大的用户属性(User Property)
  • 改良性能并反对小型客户端
  • 会话放弃和音讯超时设置
  • 新增反对 Req/Rsp 音讯模式

CocoaMQTT 客户端的应用

本文将应用 EMQ 提供的 收费公共 MQTT 服务器 进行 CocoaMQTT 性能应用介绍,该服务基于 MQTT 云服务 EMQ X Cloud 创立。

服务器接入信息如下:

  • Broker: broker-cn.emqx.io
  • TCP Port: 1883
  • Websocket Port: 8083
  • TCP/TLS 端口: 8883
  • Websocket/TLS 端口:8084

连贯 MQTT 服务

咱们看到 MQTT 5.0 减少了许多属性,其中 Property 字段能够让使用者依据本人的状况,更加粗疏化去实现需要。

///MQTT 5.0
let clientID = "CocoaMQTT-" + String(ProcessInfo().processIdentifier)
let mqtt5 = CocoaMQTT5(clientID: clientID, host: "broker-cn.emqx.io", port: 1883)

let connectProperties = MqttConnectProperties()
connectProperties.topicAliasMaximum = 0
connectProperties.sessionExpiryInterval = 0
connectProperties.receiveMaximum = 100
connectProperties.maximumPacketSize = 500
mqtt5.connectProperties = connectProperties

mqtt5.username = "test"
mqtt5.password = "public"
mqtt5.willMessage = CocoaMQTTWill(topic: "/will", message: "dieout")
mqtt5.keepAlive = 60
mqtt5.delegate = self
mqtt5.connect()

///MQTT 3.1.1
let clientID = "CocoaMQTT-" + String(ProcessInfo().processIdentifier)
let mqtt = CocoaMQTT(clientID: clientID, host: "broker-cn.emqx.io", port: 1883)
mqtt.username = "test"
mqtt.password = "public"
mqtt.willMessage = CocoaMQTTWill(topic: "/will", message: "dieout")
mqtt.keepAlive = 60
mqtt.delegate = self
mqtt.connect()

订阅主题

MQTT 5.0 在 MQTT 3.1.1 下面多了订阅选项等操作。

///MQTT 5.0
mqtt5.subscribe("chat/room/animals/client/+", qos: CocoaMQTTQoS.qos1)
//or
//let subscriptions : [MqttSubscription] = [MqttSubscription(topic: "chat/room/animals/client/+"),MqttSubscription(topic: "chat/room/foods/client/+"),MqttSubscription(topic: "chat/room/trees/client/+")]
//mqtt.subscribe(subscriptions)

///MQTT 3.1.1
mqtt.subscribe("chat/room/animals/client/+", qos: CocoaMQTTQoS.qos1)
//or
//let subscriptions : [(String, CocoaMQTTQoS)] = [("chat/room/animals/client/+", qos: CocoaMQTTQoS.qos1),("chat/room/foods/client/+", qos: CocoaMQTTQoS.qos1),("chat/room/trees/client/+", qos: CocoaMQTTQoS.qos1)]
//mqtt.subscribe(subscriptions)

公布音讯

///MQTT 5.0
mqtt5!.publish("chat/room/animals/client/" + animal!, withString: message!, qos: .qos1, DUP: false, retained: false, properties: publishProperties)

///MQTT 3.1.1
mqtt!.publish("chat/room/animals/client/" + animal!, withString: message!, qos: .qos1)

主动重连

MQTT 是基于 TCP 长连贯的协定,在理论应用的场景中,因为网络故障或信号问题导致连贯中断是经常出现的问题。许多开发者会心愿 SDK 可能提供方便的主动重连形式。

///MQTT 5.0
mqtt5!.autoReconnect = true

///MQTT 3.1.1
mqtt!.autoReconnect = true

单双向 SSL 连贯

///MQTT 5.0
mqtt5!.enableSSL = true

///MQTT 3.1.1
mqtt!.enableSSL = true

let clientCertArray = getClientCertFromP12File(certName: "client-keycert", certPassword: "MySecretPassword")
var sslSettings: [String: NSObject] = [:]
sslSettings[kCFStreamSSLCertificates as String] = clientCertArray

///MQTT 5.0
mqtt5!.sslSettings = sslSettings

///MQTT 3.1.1
mqtt!.sslSettings = sslSettings

如果须要 .p12 文件能够在终端应用以下语句生成

1openssl pkcs12 -export -clcerts -in client-cert.pem -inkey client-key.pem -out client.p12

设置保留音讯和遗嘱音讯

MQTT 5.0 与 MQTT 3.1.1 比,多了更多的属性设置可供用户应用。

///MQTT 5.0
let lastWillMessage = CocoaMQTTMessage(topic: "/chat/room/animals/client/Sheep", string: "dieout")
lastWillMessage.retained = true
lastWillMessage.qos = .qos1
mqtt5!.willMessage = lastWillMessage

///MQTT 3.1.1
mqtt!.willMessage = CocoaMQTTMessage(topic: "/will", string: "dieout")

AUTH 报文

MQTT 单纯通过 CONNECT 可能无奈提供足够的信息给 Server 进行身份认证,所以 MQTT 5.0 新增此性能。用于客户端和服务器之间的增强认证。

  let authProperties = MqttAuthProperties()
        mqtt5!.auth(reasonCode: CocoaMQTTAUTHReasonCode.continueAuthentication, authProperties: authProperties)

iOS 利用后盾运行

举荐应用「Background fetch」模式或 IOS 13 新增的「Background processing」模式。

如果应用 beginBackgroundTaskWithNameendBackgroundTask 相干的 API,能够放弃 APP 在后盾运行 30 秒。

总结

至此,咱们实现了应用 CocoaMQTT 客户端连贯到公共 MQTT 服务器,并实现了客户端与 MQTT 服务器的连贯、音讯公布和订阅。

我的项目残缺代码请见 https://github.com/emqx/Cocoa…。

EMQ 致力于帮忙用户轻松便捷地应用 MQTT 发展物联网业务,咱们的一系列客户端 SDK 均在继续开发中,敬请关注。

退出移动版