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

 整个系统架构如下:

传感器上传数据到阿里云Iot,然后从阿里云Iot传输数据到我的服务器和数据库_第1张图片

MQTT 和RocketMQ的区别:


传感器上传数据到阿里云Iot,然后从阿里云Iot传输数据到我的服务器和数据库_第2张图片

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

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

传感器上传数据到阿里云Iot,然后从阿里云Iot传输数据到我的服务器和数据库_第3张图片

阿里云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
            }
        }
    }
}

参数说明:

 
参数 类型 说明
iotId String 设备在平台内的唯一标识
productKey String 设备所属产品的唯一标识
deviceName String 设备名称
deviceType String 设备类型
items Object 设备数据
Power String 属性名称,产品所具有的属性名称请参考TSL描述
Position String 属性名称,产品所具有的属性名称请参考TSL描述
value 根据TSL定义 属性值
time Long 属性产生时间,如果设备没有上报默认采用云端生成时间
gmtCreate Long 数据流转消息产生时间

发送方式如下: 

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

 传感器上传数据到阿里云Iot,然后从阿里云Iot传输数据到我的服务器和数据库_第4张图片

 

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

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

传感器上传数据到阿里云Iot,然后从阿里云Iot传输数据到我的服务器和数据库_第5张图片

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

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第一次启动是从队列头部开始消费还是队列尾部开始消费

         * 如果非第一次启动,那么按照上次消费的位置继续消费
         */
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET); 
        consumer.subscribe("TopicTest", "*"); 
        consumer.registerMessageListener(new MessageListenerConcurrently() { 
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List 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

 

 

 

 

 

 

你可能感兴趣的:(阿里云Iot)