开发者社区 问答 正文

MQTT Token 客户端接口如何实现?


本文介绍 MQTT 客户端上传 Token、监听 Token 失效信息、监听 Token 非法信息三个接口的使用,并给出相关示例代码以供参考。

客户端上传 Token 凭证


发送 Topic:$SYS/uploadToken
内容:JSONString
内容信息:

名称类型说明
TokenString如果客户端选用 Token 模式,则需要上传 Token 字符串。
typeStringToken 类型,分为 W,R,RW 共三种,对应三种权限类型的 Token。一个客户端最多拥有这3个 Token,设置错误的类型会导致权限校验错误。

返回值
普通的 PubAck 报文。客户端必须等到该响应才能进行下一步 Pub 或者 Sub 操作,否则服务端可能会鉴权失败导致连接断开。

客户端监听即将失效的 Token 信息


接收 Topic:$SYS/tokenExpireNotice
内容:JSONString
内容信息:
名称类型说明
expireTimeint该 Token 即将于什么时候失效,一般提前5分钟通知,只通知一次。
typeStringToken 类型,分为 W,R,RW 共三种,对应客户端上传的三种权限类型的 Token。

响应:
客户端收到 Token 即将失效的消息后,需要尽快处理重新申请 Token 的动作,以免造成收发消息失败。

客户端监听 Token 非法的通知


接收 Topic:$SYS/tokenInvalidNotice
内容:JSONString
内容信息:
名称类型说明
codeintToken 校验失败的类型。
typeStringToken 类型,分为 W,R,RW 共三种,对应客户端上传的三种权限类型的 Token。

响应:
服务端校验 Token 失效,会导致鉴权失败,服务端会主动断开链接。断开链接之前,服务端会给客户端推送失败的 code,客户端根据 code 即可判断原因。
type code错误类型
1伪造 Token,不可解析
2Token 已经过期
3Token 已经被吊销
4资源和 Token 不匹配
5权限类型和 Token 不匹配
8签名不合法
-1帐号权限不合法

注意:
  • 服务端下推 Token 非法的通知后,会接着断开连接。正常情况下客户端应该能根据该通知判断是否需要申请 Token。
  • 异常情况下,可能尚未收到通知,即已经断开连接。此时客户端需要判断原先的 Token 是否到期,如果确实接近到期时间,则先申请 Token 再重连。


示例程序

  1. public static void main(String[] args) throws MqttException, InterruptedException {
  2.         String broker = "tcp://XXXX:1883";
  3.         String clientId = "GID_XXX@@@XXXX";
  4.         final String topic = "XXXX/XXXXX";
  5.         MemoryPersistence persistence = new MemoryPersistence();
  6.         final MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
  7.         final MqttConnectOptions connOpts = new MqttConnectOptions();
  8.         System.out.println("Connecting to broker: " + broker);
  9.         connOpts.setServerURIs(new String[] {broker});
  10.         connOpts.setCleanSession(true);
  11.         connOpts.setKeepAliveInterval(90);
  12.         sampleClient.setCallback(new MqttCallbackExtended() {
  13.             @Override
  14.             public void connectComplete(boolean reconnect, String serverURI) {
  15.                 //连接成功,需重新上传Token
  16.                 JSONObject object = new JSONObject();
  17.                 object.put("token", "XXXX");//设置Token内容
  18.                 object.put("type", "RW");//设置Token类型,共有RW,R,W三种类型
  19.                 MqttMessage message = new MqttMessage(object.toJSONString().getBytes());
  20.                 message.setQos(1);
  21.                 try {
  22.                     sampleClient.publish("$SYS/uploadToken", message);
  23.                     sampleClient.subscribe(topic, 0);
  24.                 } catch (MqttException e) {
  25.                     e.printStackTrace();
  26.                 }
  27.             }
  28.             @Override
  29.             public void connectionLost(Throwable throwable) {
  30.                 System.out.println("mqtt connection lost");
  31.                 throwable.printStackTrace();
  32.             }
  33.             @Override
  34.             public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
  35.                 if (topic.equals("$SYS/tokenInvalidNotice")) {
  36.                     //Token非法的通知
  37.                 } else if (topic.equals("$SYS/tokenExpireNotice")) {
  38.                     //Token即将失效的通知
  39.                 }
  40.             }
  41.             @Override
  42.             public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
  43.                 System.out.println("deliveryComplete:" + iMqttDeliveryToken.getMessageId());
  44.             }
  45.         });
  46.         sampleClient.connect(connOpts);
  47.         JSONObject object = new JSONObject();
  48.         object.put("token", "XXXX");//设置Token内容
  49.         object.put("type", "RW");//设置Token类型,共有RW,R,W三种类型
  50.         MqttMessage message = new MqttMessage(object.toJSONString().getBytes());
  51.         message.setQos(1);
  52.         MqttTopic pubTopic = sampleClient.getTopic("$SYS/uploadToken");
  53.         MqttDeliveryToken token = pubTopic.publish(message);
  54.         token.waitForCompletion();//同步等待上传结果
  55.         //Token上传成功,在开始正常的业务消息收发
  56.         sampleClient.subscribe(topic, 0);
  57.         while (true) {
  58.             sampleClient.publish(topic, message);
  59.             Thread.sleep(5000);
  60.         }
  61.     }

展开
收起
猫饭先生 2017-10-27 10:51:35 4653 分享 版权
0 条回答
写回答
取消 提交回答