MQTT协议解析

本文基于快速开始进行MQTT协议解析开发说明,在开发之前请先阅读之.

创建mqtt编解码类

创建MqttDeviceMessageCodec并实现DeviceMessageCodec接口

创建类

编写解码逻辑

编辑decode方法

code

编写编码逻辑

编辑encode方法

code

将编解码器注册到协议中

编辑类MyProtocolSupportProvider

code

编写MQTT认证规则

通过mqtt直连接入时,需要先对mqtt请求进行认证. 在mqtt客户端发送CONNECT报文时,平台会根据clientId获取对应的设备实例, 然后调用此设备的协议包进行认证.认证通过后建立连接.

code

  1. //MQTT 认证
  2. support.addAuthenticator(DefaultTransport.MQTT, (request, device) -> {
  3. MqttAuthenticationRequest mqttRequest = ((MqttAuthenticationRequest) request);
  4. return device
  5. .getConfigs("username", "password")
  6. .flatMap(values -> {
  7. String username = values.getValue("username").map(Value::asString).orElse(null);
  8. String password = values.getValue("password").map(Value::asString).orElse(null);
  9. if (mqttRequest.getUsername().equals(username) && mqttRequest
  10. .getPassword()
  11. .equals(password)) {
  12. return Mono.just(AuthenticationResponse.success());
  13. } else {
  14. return Mono.just(AuthenticationResponse.error(400, "密码错误"));
  15. }
  16. });
  17. });

温馨提示

图中的device.getConfigs表示: 先从设备中获取配置,如果不存在则从产品中获取. 如果只从设备中获取可以使用device.getSelfConfigs

定义MQTT配置描述

在第5步中需要获取设备的配置信息username,password. 通过定义mqtt配置描述来告诉平台,使用该协议的产品或者设备需要进行相应的配置. 在对应的产品或者设备界面才会出现配置项目输入.

code

  1. //设置配置定义信息
  2. support.addConfigMetadata(DefaultTransport.MQTT,
  3. new DefaultConfigMetadata("MQTT认证配置", "MQTT接入时使用的认证配置")
  4. //产品和设备都可以配置
  5. .scope(DeviceConfigScope.device,DeviceConfigScope.product)
  6. .add("username", "username", "MQTT用户名", StringType.GLOBAL)
  7. .add("password", "password", "MQTT密码", PasswordType.GLOBAL)
  8. );

定义topic

注意

2.0版本后,如果是通过mqtt broker接入的设备,必须进行此步骤. 因为在启动设备接入网关时,会获取协议包定义的topic去从mqtt broker订阅数据.

可以通过{}来指定动态topic, 如 /function/{functionId},订阅时会自动转换为mqtt的topic/functoin/+, 如果要使用#则可以这样定义: /function/{#functionId},订阅时会自动转换为mqtt的topic/functoin/#

mqtt-route

  1. support.addRoutes(DefaultTransport.MQTT, Arrays.asList(
  2. Route.mqtt("/properties/report")
  3. .group("属性相关")
  4. .description("上报属性")
  5. .upstream(true)
  6. .build(),
  7. Route.mqtt("/function/{functionId}")
  8. .group("功能相关")
  9. .description("平台下发功能调用指令")
  10. .downstream(true)
  11. .build()
  12. ));

打包并发布到平台

执行mvn package打包.

package

将生成的jar包上传到平台即可.