传感器上传数据到阿里云Iot,然后从阿里云Iot传输数据到我的服务器和数据库

 整个系统架构如下:

MQTT 和RocketMQ的区别:


1、传感器采用GPRS传输数据,采用微消息队列MQTT,微消息队列 MQTT 主要承担移动端连接接入、连接管理、数据转发等工作,相当于一个无限扩展能力的连接网关。传感器传送数据到阿里云Iot。MQTT支持Python,java,有相应的sdk,地址如下:

https://help.aliyun.com/product/100973.html?spm=a2c4g.11186623.6.540.791c5695zBTImA

阿里云Iot的设备传输数据格式是json格式,采用post方式提交数据,具体格式如下:

设备属性上报

通过该Topic获取设备上报的属性信息。

Topic:/sys/{productKey}/{deviceName}/thing/event/property/post

数据格式:

{
    "iotId":"4z819VQHk6VSLmmBJfrf00107ee200",
    "productKey":"1234556554",
    "deviceName":"deviceName1234",
    "gmtCreate":1510799670074,
    "deviceType":"Ammeter",
    "items":{
        "Power":{
            "value":"on",
            "time":1510799670074
        },
        "Position":{
            "time":1510292697470,
            "value":{
                "latitude":39.9,
                "longitude":116.38
            }
        }
    }
}

参数说明:

 
参数类型说明
iotIdString设备在平台内的唯一标识
productKeyString设备所属产品的唯一标识
deviceNameString设备名称
deviceTypeString设备类型
itemsObject设备数据
PowerString属性名称,产品所具有的属性名称请参考TSL描述
PositionString属性名称,产品所具有的属性名称请参考TSL描述
value根据TSL定义属性值
timeLong属性产生时间,如果设备没有上报默认采用云端生成时间
gmtCreateLong数据流转消息产生时间

发送方式如下: 

 MQTT采用topic形式发送数据,生产者产生数据,通过topic进行发送,消费者订阅消息,接收消息。

 

 

 2、MQTT将消息进行转储,使用RocketMQ进行转储,RocketMQ支持HTTP协议,有相应的sdk开发包,进行开发,如Python,java,通过ip地址直接订阅消息,地址如下:https://help.aliyun.com/product/29530.html?spm=a2c4g.11186623.6.540.71694fb3z3Z3Kg

RocketMQ是一个消息队列,吞吐性能强大。格式如下,

自定义生产者与消费者如下:

producer

发送消息
public class Producer {
    public static void main(String[] args) throws MQClientException, InterruptedException {
        DefaultMQProducer producer = new DefaultMQProducer("pay_topic_01");
        producer.setNamesrvAddr("100.8.8.88:9876");
        producer.start(); 
        for (int i = 0; i < 1000; i++) {
            try {
                Message msg = new Message("TopicTest",// topic
                    "TagA",// tag
                    ("Hello RocketMQ " + i).getBytes()// body
                        );
                SendResult sendResult = producer.send(msg);
                System.out.println(sendResult);
            }
            catch (Exception e) {
                e.printStackTrace();
                Thread.sleep(1000);
            }
        }
        producer.shutdown();
    }
}
 

订阅消息
public class Consumer { 
    public static void main(String[] args) throws InterruptedException, MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name_4");
        consumer.setNamesrvAddr("100.8.8.88:9876");
        /**
         * 设置Consumer第一次启动是从队列头部开始消费还是队列尾部开始消费<br>
         * 如果非第一次启动,那么按照上次消费的位置继续消费
         */
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET); 
        consumer.subscribe("TopicTest", "*"); 
        consumer.registerMessageListener(new MessageListenerConcurrently() { 
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                    ConsumeConcurrentlyContext context) {
                System.out.println(Thread.currentThread().getName() + " Receive New Messages: " + msgs);
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
         consumer.start(); 
        System.out.println("Consumer Started.");
    }

3、阿里云官方Python 的sdk中的producer和consumer如下:

(1)producer

#初始化 client
mq_client = MQClient(
    #设置HTTP接入域名(此处以公共云生产环境为例)
    "${HTTP_ENDPOINT}",
    #AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建
    "${ACCESS_KEY}",
    #SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建
    "${SECRET_KEY}"
    )
#所属的 Topic
topic_name = "${TOPIC}"
#Topic所属实例ID,默认实例为空None
instance_id = "${INSTANCE_ID}"

producer = mq_client.get_producer(instance_id, topic_name)

# 循环发布多条消息
msg_count = 100
print "%sPublish Message To %s\nTopicName:%s\nMessageCount:%s\n" % (10 * "=", 10 * "=", topic_name, msg_count)

try:
    for i in range(msg_count):
        msg_body = "I am test message %s." % i
        msg = TopicMessage(
            # 消息内容
            "I am test message %s." % i, 
            # 消息标签
            ""
        )
        re_msg = producer.publish_message(msg)
        print "Publish Message Succeed. MessageID:%s, BodyMD5:%s" % (re_msg.message_id, re_msg.message_body_md5)
        time.sleep(1)
except MQExceptionBase, e:
    if e.type == "TopicNotExist":
        print "Topic not exist, please create it."
        sys.exit(1)
    print "Publish Message Fail. Exception:%s" % e
 

(2)consumer

重要的是message的body中的数据,取出数据即可实现通讯。

#初始化 client
mq_client = MQClient(
    #设置HTTP接入域名(此处以公共云生产环境为例)
    "${HTTP_ENDPOINT}",
    #AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建
    "${ACCESS_KEY}",
    #SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建
    "${SECRET_KEY}"
  )
#所属的 Topic
topic_name = "${TOPIC}"
#您在控制台创建的 Consumer ID(Group ID)
group_id = "${GROUP_ID}"
#Topic所属实例ID,默认实例为空None
instance_id = "${INSTANCE_ID}"

consumer = mq_client.get_consumer(instance_id, topic_name, group_id)

#长轮询表示如果topic没有消息则请求会在服务端挂住3s,3s内如果有消息可以消费则立即返回
#长轮询时间3秒(最多可设置为30秒)
wait_seconds = 3
#一次最多消费3条(最多可设置为16条)
batch = 3
print "%sConsume And Ak Message From Topic%s\nTopicName:%s\nMQConsumer:%s\nWaitSeconds:%s\n" % (10 * "=", 10 * "=", topic_name, group_id, wait_seconds)
while True:
    try:
        #长轮询消费消息
        recv_msgs = consumer.consume_message(batch, wait_seconds)
        for msg in recv_msgs:
            print "Receive, MessageId: %s\nMessageBodyMD5: %s \
                              \nMessageTag: %s\nConsumedTimes: %s \
                              \nPublishTime: %s\nBody: %s \
                              \nNextConsumeTime: %s \
                              \nReceiptHandle: %s" % \
                             (msg.message_id, msg.message_body_md5,
                              msg.message_tag, msg.consumed_times,
                              msg.publish_time, msg.message_body,//这里封装的数据问题
                              msg.next_consume_time, msg.receipt_handle)
    except MQExceptionBase, e:
        if e.type == "MessageNotExist":
            print "No new message! RequestId: %s" % e.req_id
            continue

        print "Consume Message Fail! Exception:%s\n" % e
        time.sleep(2)
        continue

    #msg.next_consume_time前若不确认消息消费成功,则消息会重复消费
    #消息句柄有时间戳,同一条消息每次消费拿到的都不一样
    try:
        receipt_handle_list = [msg.receipt_handle for msg in recv_msgs]
        consumer.ack_message(receipt_handle_list)
        print "Ak %s Message Succeed.\n\n" % len(receipt_handle_list)
    except MQExceptionBase, e:
        print "\nAk Message Fail! Exception:%s" % e
        #某些消息的句柄可能超时了会导致确认不成功
        if e.sub_errors:
          for sub_error in e.sub_errors:
            print "\tErrorHandle:%s,ErrorCode:%s,ErrorMsg:%s" % (sub_error["ReceiptHandle"], sub_error["ErrorCode"], sub_error["ErrorMessage"])

 

 具体的json数据解析请看另一篇文章:https://blog.csdn.net/u014535666/article/details/92848237

数据流转网址:https://help.aliyun.com/document_detail/73736.html?spm=a2c4g.11186623.6.599.3b4e2fcaPLzDhO

阿里物联网平台:https://iotnext.console.aliyun.com/lk/summary

消息服务控制台:https://mns.console.aliyun.com/?spm=5176.6660585.774526198.1.11946bf8o9CsYO#/logging/cn-beijing

微消息队列MQTT,消息队列RocketMQ:https://ons.console.aliyun.com/?spm=5176.11485173.0.0.23f759afSBZrGK#/?regionId=mq-internet-access

 

 

 

 

 

 

相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页