Java spring mvc 结合阿里MQTT功能

近期,公司准备使用阿里MQTT,自己做了一个demo。

准备工作

首先,你歹有一个阿里云帐号,去阿里云注册一个MQTT实例,现在有免费试用一个月的

在这我们要记得尤其记一下我们购买的实例是买的哪的 比如我的这个是深圳  可以写进配置文件中

    public final static  String instanceId  = "";

    public final static  String accessKey= "";

    public final static  String secretKey= "";

    public final static  String connectEndpoint= "";;

    public final static  String topicId ="demo";

    public final static  String groupId ="GID_demo";
    
    public final static  String messageModel="5000";

    public final static  String sendMsgTimeoutMillis="5000";

    public final static  String suspendTimeMillis="5000";

    /**
     * 消息消费失败时的最大重试次数
     */
    public final static  String maxReconsumeTimes="10";

    /**
     * QoS参数代表传输质量,可选0,1,2
     */
    public final static  int qosLevel = 0;
    /**
     * 客户端超时时间
     */
    public final static   int timeToWait =5000;
    /**
     * MQTT所在地域
     */  
    public final static  String mqttAddress= "cn-shenzhen";

MQTT消息队列的实现功能

我们主要完成五个接口功能的实现

1.设备code发送消息到topic中

2.设备code发送消息到指定设备上(P2P模式)

3.服务启动监听队列消息

4.根据设备ID及所在队列查询设备当前状态消息(单独设备)

5.根据设备ID及所在队列批量查询设备当前状态消息(注意最大只是支持十个设备的查询)

设备code发送消息到topic中

主要思路是创建连接MQTT,直接将消息发送到对应的topic中

 public void sendMqttMsgTopic(
 		   @RequestParam(value = "deviceCode", required = true) String deviceCode,
           @RequestParam(value = "msg", required = true) String msg) throws InterruptedException, MqttException{   	
      	String listenTopic ="earTagTopic";
      	 String clientId = MqttConfig.earTagGroupId + "@@@" + deviceCode;
      	 String topic = MqttConfig.earTagTopicId + "/" + listenTopic;      	
        //发送消息到消息队列
            MqttMessage message = new MqttMessage(msg.getBytes());
            message.setQos(MqttConfig.qosLevel);
            /**
             *  发送普通消息时,topic 必须和接收方订阅的 topic 一致,或者符合通配符匹配规则
             */            
            try {
				mqttClient = MqtttClient.getProducerConnection(clientId,topic,deviceCode,MqttConfig.earTagGroupId);				
				mqttClient.publish(topic, message);
			} catch (InvalidKeyException | NoSuchAlgorithmException | MqttException e1) {
				System.out.printf("消息发送失败:{}", e1.getMessage());
				e1.printStackTrace();
			}
            mqttClient.disconnect();
            Thread.sleep(Long.MAX_VALUE);

        return ;
    }

我们可以看到我们向earTag的eraTagTopic的主题消息发送成功,并且可以看到已经监听到并打印

如果我们不需要发送成功返回的回调,我们直接将callback代码去掉即可

  mqttClient.setCallback(new MqttCallbackExtended()

我们可以看到这两条就是去掉成功回调,我们直接监听到返回结果了

设备code发送消息到指定设备上(P2P模式)

主要思路也是连接到MQTT上,然后直接向目标设备发送消息。

    public void sendMqttp2pMsg(
    		   @RequestParam(value = "deviceCode", required = true) String deviceCode,
               @RequestParam(value = "msg", required = true) String msg
    		) throws InterruptedException, MqttException{
        /**
         * MQ4IoT支持点对点消息,即如果发送方明确知道该消息只需要给特定的一个设备接收,且知道对端的 clientId,则可以直接发送点对点消息。
         * 点对点消息不需要经过订阅关系匹配,可以简化订阅方的逻辑。点对点消息的 topic 格式规范是  {{parentTopic}}/p2p/{{targetClientId}}
         */
        //对指定设备发送p2p消息  当前测试只是给监听我这个队列的设备发送消息
    	String listenTopic ="earTagTopic";
     	 String clientId = MqttConfig.earTagGroupId + "@@@" + deviceCode+"aa";
     	 String topic = MqttConfig.earTagTopicId + "/" + listenTopic; 
        	//String msgSendTopic = MqttConfig.earTagTopicId  + "/p2p/" +  MqttConfig.earTagGroupId + "@@@" + deviceCode;
     	String msgSendTopic = MqttConfig.topicId  + "/p2p/" +  MqttConfig.groupId + "@@@" + deviceCode;

            MqttMessage mqttMessage = new MqttMessage(msg.getBytes());
            mqttMessage.setQos(MqttConfig.qosLevel);      
			try {
				mqttClient = MqtttClient.getProducerConnection(clientId,topic,deviceCode+"aa",MqttConfig.earTagGroupId);	
				mqttClient.publish(msgSendTopic, mqttMessage);
			} catch (InvalidKeyException | NoSuchAlgorithmException | MqttException e1) {
				System.out.printf("消息发送失败:{}", e1.getMessage());
				e1.printStackTrace();
			}
			  mqttClient.disconnect();
			Thread.sleep(Long.MAX_VALUE);
			   return ;

        }

我向GID_demo@@@test3的设备发送指定的消息,GID_demo@@@test3这个设备成功接收到了。

服务启动监听队列消息

主要思路使用ApplicationListener来进行实现 项目启动自动启动监听

根据设备ID及所在队列查询设备当前状态消息(单独设备)

主要思路传想要查询的主题及设备code,返回当前状态信息

    public SourceDataBean<DeviceStateBean> querySessionByClientId(
			@RequestParam(value = "topic", required = true) String topic,
			@RequestParam(value = "deviceCode", required = true) String deviceCode) throws InterruptedException, MqttException{ 	
		SourceDataBean<DeviceStateBean> sdb = new SourceDataBean<DeviceStateBean>();	
		List<DeviceStateBean> res = queryDeviceStateService.querySessionByClientId(topic, deviceCode);
		if(res.size()>0) {
			sdb.setDataSource(new DataSource<>(res,1,1,1));
			sdb.setMessage(RestCode.SUCCESS.code,PropertiesUtil.getValue("config.properties","QuerySuccessful"));
		}else {
      	 sdb.setMessage(RestCode.FAILED.code,res.get(0).getOnlineStatusName());
		}
		return sdb;
    }

根据设备ID及所在队列批量查询设备当前状态消息(注意最大只是支持十个设备的查询)

主要思路传想要查询的主题及设备codes,返回查询设备的状态信息

注意deviceCodes  使用逗号分隔即可,当前阿里MQTT官方文档写的是最大只是十个设备的查询,因为我这边的分页最大数量是10,未做超过10的测试。

    public SourceDataBean<DeviceStateBean> querySessionByClientIds(
			@RequestParam(value = "topic", required = true) String topic,
			@RequestParam(value = "deviceCodes", required = true) String deviceCodes) throws InterruptedException, MqttException{ 	
		SourceDataBean<DeviceStateBean> sdb = new SourceDataBean<DeviceStateBean>();
		List<DeviceStateBean> res = queryDeviceStateService.querySessionByClientIds(topic, deviceCodes);
		if(res.size()>0) {
			sdb.setDataSource(new DataSource<>(res,res.size(),0,0));
			sdb.setMessage(RestCode.SUCCESS.code,PropertiesUtil.getValue("config.properties","QuerySuccessful"));
		}else {
      	 sdb.setMessage(RestCode.FAILED.code,res.get(0).getOnlineStatusName());
		}
		return sdb;
    }


这样,springMVC结合阿里MQTT的基本使用就完成了。

有不懂的地方可以QQ联系我,外接私活,源码出售,欢迎各位老板。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值