物联网开发 第4讲 中移OneNET HTTP推送服务接入

在使用OneNET平台时,如果我们自己开发应用,基本上会有获取设备的上下线信息以及设备上传的数据点的需求。

为了满足上述的需求,我们有以下两种方法:

  1. 使用OneNET的HTTP RESTful API轮询获取设备上下线状态以及数据点

  2. 使用OneNET提供的数据推送的服务,实时推送设备上下线状态以及数据点至自己的服务器。

上面的两个方法,针对不同的应用场景,选择其中一种就可以了。

比如我之前给孩子买过一个联网的机器人学习机,我用自己的微信通过商家的公众号与学习机绑定,学习机一旦开机,就会有一条“设备上线”的通知发到我的微信上。这种场景使用HTTP推送服务就再合适不过了。(我突然有个想法,后面实战的环节,我也可以模仿这个场景进行实战的演示)

本篇我主要讲解OneNET平台的多协议产品如何使用HTTP推送服务。其中我在文章演示时的后台开发语言使用python(不懂python的朋友可以忽略python源码),大家可以用自己擅长的语言进行开发,毕竟步骤和思想都是一样的。

我们先来看下OneNET官方关于HTTP推送的一些说明。

OneNET平台提供数据推送功能,可以将平台作为客户端,将相关信息以HTTP/HTTPS请求的方式,发送给应用服务器。

值得注意一点,其中的“相关信息”包括:

  • 设备新增数据点消息

  • 设备上下线消息

  • 设备对于下行命令的应答信息(仅限NB设备)

OneNET推送服务提供数据过滤功能,用户可以以数据流模板为过滤条件,过滤掉例如设备的频繁的周期性上报等大量时间不敏感数据,只推送用户自己关心的实时性要求较高的数据,如下图所示。

图 OneNET数据过滤框架(来自OneNET官方)

当然,OneNET推送服务提供数据压缩的功能,用户可以设置数据量以及时间的压缩方式,将一定时间内的一定量的多包单信息报文,合并成为一包包含多条信息的json数据,可以大大减少应用服务器的处理压力,如下图所示

图 OneNET数据压缩框架(来自OneNET官方)

下面,我们直接进行演示,这里我基于MQTT协议的产品(其它协议使用方法是一样的)进行演示。

如何创建产品和设备我就不多讲了,前面几个章节都讲的比较仔细。

下图是我创建好的一个演示数据推送的MQTT产品:

点击进入产品详情,创建一个新的设备,如下:

点击OneNET控制台左侧列表的"数据推送\HTTP推送"

消息推送的控制页面如下

接下来,我们首先添加一条全局推送。

添加全局推送就是要添加一个支持OneNET相应开发规则的URL,首先我们先准备一个能正常访问的URL,比如我这里的:

http://152.136.74.228:5000/he/data/push/global

一定要先确保该URL链接能 正常访问、正常访问、正常访问

我此时的python源码为:

from flask import Flask
from flask import request
import hashlib
import base64app = Flask(__name__)# OneNET全局推送链接
@app.route("/he/data/push/global", methods=['GET'])
def he_data_push_global():return 'Hello IOT'if __name__ == '__main__':app.run(host='0.0.0.0', debug=True)

点击"添加全局推送"

填写相关的信息:

URL:http://152.136.74.228:5000/he/data/push/global
Token:20200321182801
消息加密方式:明文模式
数据推送:全部数据流

然后点击"添加"按钮,此时OneNET会弹出如下信息:

大概的意思是"鉴权失败,验证Token失败"。同时,当你点击"添加"按钮后,你可以看到你填写的URL会接收到如下一个请求:

GET /he/data/push/global?msg=LeoTAq&signature=/7hXrr3IpM538Z1uHvxSlA==&nonce=B0k7pDoe

可以看到URL后面携带了三个参数msg、signature、nonce,好了,这就要涉及到OneNET URL验证的问题了。

在使用推送服务时,OneNET作为客户端,而用户的第三方应用是作为服务器,第三方应用需要支持URL验证以及数据接收两部分服务。

用户在配置页面完成配置并点击“添加”时,OneNET平台会向填写URL地址发送HTTP GET请求进行URL验证,请求形式示例如下:

http://url?msg=xxx&nonce=xxx&signature=xxx

其中,url为用户在页面配置时填写的URL,nonce、msg、signature用于URL及token的验证

token验证过程如下:

1. 将配置页面中配置的token与URL中的nonce、msg的值计算MD5,并且编码为Base64字符串值

2. 将上一步中Base64字符串值通过URL Decode计算后的值与请求参数signature的值进行对比,如果相等则表示token验证成功

3. 如果token验证成功,返回msg参数值,表示URL验证通过。

但是,还有一点,OneNET作了特别说明:

如果用户不想验证token,可以选择跳过MD5计算过程,直接返回msg参数值

也就是说,只要你的URL返回请求中的msg值,那就说明URL验证通过。我们先不对token进行校验,我们简单一点,直接获取并返回URL中的msg参数。流程跑通之后,我们再研究token验证的问题。

如下,我修改了服务端的Python代码:

@app.route("/he/data/push/global", methods=['GET'])
def he_data_push_global():msg = request.args.get('msg') or Nonesignature = request.args.get('signature') or Nonenonce = request.args.get('nonce') or Noneif not all([msg, signature, nonce]):return 'invalid parameter'return msg

然后再点击"添加"按钮,

此时可以看到,全局推送URL添加成功。

然后我们再来看一下数据推送的内容。

通常数据推送内容包括

  • 设备上下线信息

  • 设备新增数据点消息

OneNET平台以HTTP POST请求形式向第三方平台URL地址推送数据,第三方平台接收到数据后需要返回 HTTP 200,否则OneNET会认为此次推送无效并重试。

推送数据相关信息以JSON串的形式置于HTTP请求中的body部分,其中各个字段的含义如下:

既然OneNET是以POST形式推送数据,那么我们就得在我们服务器指定的URL支持POST连接,我修改服务器端代码如下:

@app.route("/he/data/push/global", methods=['GET', 'POST'])
def he_data_push_global():if request.method == 'POST':print('**** Receive Post Data *****')print(request.data)return 'POST SUCCESS'msg = request.args.get('msg') or Nonesignature = request.args.get('signature') or Nonenonce = request.args.get('nonce') or Noneif not all([msg, signature, nonce]):return 'invalid parameter'return msg

服务端没有做什么内容,只是打印输出POST传递过来的Body数据。

下面开始实验,我为了演示方便,写了一个多协议的设备模拟器,该软件的最新版本我会上传到QQ群940556740。

例1:MQTT设备上线

设备上线之后,服务器端接收到推送的数据:

对比前面的表格,整理并分析其中的Body数据如下:

{"msg":{"at":1585579321430,  //时间戳"login_type":7,    //设备登录协议类型 7-MQTT"type":2,          //消息类型  2:设备上下线消息"dev_id":589888962,  //设备ID"status":1        //设备上下线标识  1:设备上线},"msg_signature":"1FtJkDnewfBiKFJKKheJPA==",  //消息摘要"nonce":"w&INtJ9+"    //用于计算消息摘要的随机串
}

例2:MQTT设备下线

设备下线之后,服务器端接收到推送的数据:

{"msg":{"at":1585579700235,    //时间戳"login_type":7,      //设备登录协议类型 7-MQTT"type":2,            //消息类型  2:设备上下线消息"dev_id":589888962,    //设备ID"status":0      //设备上下线标识  1:设备下线},"msg_signature":"YPpafOSW1Byncd7xdXtF0Q==",  //消息摘要"nonce":"iSX$ZVVD"    //用于计算消息摘要的随机串
}

例3:MQTT设备新增数据点

服务器端接收到推送的数据如下:

{"msg":{"at":1585579995234,    //时间戳"type":1,       //消息类型  1:设备上下线消息"ds_id":"temperature",    //数据流名称"value":"12.34",        //数据点"dev_id":589888962      //设备ID},"msg_signature":"h1oeGIrbyreHf6S81qet9w==", //消息摘要"nonce":"Mal9%W-E"     //用于计算消息摘要的随机串
}

上面3个例子,实际演示了数据推送的内容。服务器端接收到推送的数据之后,可以根据不同的应用场景做后续的工作,比如开篇我提到的学习机,我们完全可以根据推送过来的设备上下线信息通过微信服务号的形式推送到客户微信客户端(后面一定要写个这样的实战项目)。

其它的协议类型,可以用我的设备模拟器去验证

文章讲到这里,最简单的数据推送的流程基本就演示完毕了。但是还有个地方需要再补充说明,就是URL验证部分。

我在第3小节添加URL时并没有加入Token验证,这一节我就加上这个功能。

OneNET的Token验证过程分为以下4步

  • 第1步,将URL添加时配置页面中配置的token与URL GET请求nonce、msg的值计算MD5

  • 第2步,将计算出的MD5值编码为Base64字符串值

  • 第3步,将编码后的Base64字符串值通过URL Decode编码

  • 第4步,将URL Decode编码后的值与请求参数signature的值进行对比,如果相等则表示token验证成功,返回msg值,否则返回其它自定义值。

根据上面的步骤,我在服务器端修改python代码,如下:

@app.route("/he/data/push/global", methods=['GET', 'POST'])
def he_data_push_global():if request.method == 'POST':print('**** Receive Post Data *****')print(request.data)return 'POST SUCCESS'msg = request.args.get('msg') or Nonesignature = request.args.get('signature') or Nonenonce = request.args.get('nonce') or Noneif not all([msg, signature, nonce]):return 'invalid parameter'token = '20200321182801'    # 这里是URL添加时填写的Token# 第1步 计算MD5params_str = token + nonce + msgmd5 = hashlib.md5(params_str.encode('utf-8')).digest()# 第2步 编码为Base64字符串值b64_str = base64.b64encode(md5)# 第3步 将上一步中Base64字符串值通过URL Decodeb64_str = b64_str.decode('utf-8')# 第4步 将URL Decode编码后的值与请求参数signature的值进行对比if signature == b64_str:return msgreturn 'invalid token'

讲到这里,还有群组推送以及推送时的消息加密没有讲,读者请自行琢磨,如有不会,可以留言交流。

码云地址:https://gitee.com/mybelief321/jliot

物联网学习 第4讲 中移OneNET HTTP推送服务接入相关推荐

  1. Worktile中的实时消息推送服务实现

    在团队协同工具worktile的使用过程中,你会发现无论是右上角的消息通知,还是在任务面板中拖动任务,还有用户的在线状态,都是实时刷新.Worktile中的推送服务是采用的是基于xmpp协议.erla ...

  2. Netty学习总结(3)——Netty百万级推送服务

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  3. 中移物联网onenet入门学习笔记2:中移物联的通信格式

    中移物联网onenet入门学习笔记2:中移物联的通信格式 中移物联网硬件接入协议:LWM2M协议,EDP协议,MQTT协议,HTTP协议,TCP透传,MODBUS协议,JT/T808协议,RCMP协议 ...

  4. ESP32运行MicroPython通过MQTT上报温湿度到中移OneNET物联网平台(附源码)

    前言:MQTT是当下物联网用的比较多的协议,本篇聊一聊用esp32通过MQTT连接到中移OneNET物联网平台. OneNET平台创建产品和设备 1.​创建产品:开发者中心->全部产品-> ...

  5. 公有云平台专题《中移云平台,NB-IoT模组对接中移OneNET平台》

    目录 1.中移OneNET平台介绍 2.中移OneNET平台注册 3.OneNET平台创建产品 4.NB模组对接OneNET平台 5.NB模组上报数据.接收下行数据 1.中移OneNET平台介绍 On ...

  6. 骑士智能科技M5310模块连接中移OneNet平台实现数据交互

    一.实验目的 使用骑士智能科技M5310模块加USB转串口,连接到中移OneNet平台上,并实现温湿度数据交互 二.准备工作 硬件:骑士智能科技M5310模块 + 移动NB卡.USB转串口.天线 软件 ...

  7. 解决.NET Core中MailKit无法使用阿里云邮件推送服务的问题

    在博问中(.net core怎么实现邮件发送)知道了MailKit无法使用阿里云邮件推送服务发送邮件的问题,自已实测也遇到同样的问题,而用自己搭建的邮件服务器没这个问题. 于是,向阿里云提交了工单.. ...

  8. 【PWA学习】4. 使用 Push API 实现消息推送

    引言 在接下来的内容里,我们会探究 PWA 中的另一个重要功能--消息推送与提醒(Push & Notification).这个能力让我们可以从服务端向用户推送各类消息并引导用户触发相应交互 ...

  9. Android中集成Jpush实现推送消息通知与根据别名指定推送附示例代码下载

    场景 经常会有后台服务向Android推送消息通知的情况. 实现 首先在Android Studio中新建一个Android应用 在Project根目录的build.gradle中配置了jcenter ...

最新文章

  1. php让十进制输出十六进制(ascill)码
  2. python 表达式求值数据结构_python 数据结构与算法
  3. LeetCode 71. 简化路径(栈)
  4. contenttype添加field
  5. codeforces hack
  6. =====BJmeter性能测试小接=====
  7. Winfrom 线程实现 http、https 文件下载 显示下载进度详情
  8. opencv5-objdetect之级联分类器
  9. 【通信协议学习】关于Xmodem、Ymodem、Zmodem、ASCII、Binary传输协议
  10. 分布式机器学习——入门篇
  11. windows更新系统后,git报错unsafe repository xxx is owned by someone else
  12. 简易串口助手通信(齐全) 可实现ASII和十六进制发送指令 并显示
  13. Mac版微信内存飙升卡死解决办法
  14. 设计师们都在用的3D软件汇总,确定不来学学嘛
  15. [读后感] 书名:追风筝的人
  16. 【Web前端】千年之恋注册页面——源代码展示
  17. 股票自动委托下单html,股票怎么设置自动挂单?股票挂单的方式
  18. 妙眠新零售系统开发 ——PHP程序源码搭建
  19. LeetCode 0792. 匹配子序列的单词数
  20. 爬虫进阶 之 Scrapy 框架 1(实例: 爬取ITcast 的教师信息)

热门文章

  1. 半导体SECS协议低频工业读写器读卡机CK-S650-PA60S之1协议
  2. 菏泽学院计算机系北京工作,菏泽学院毕业季 “网红”班长一天获赞88万
  3. 网格布局java_Java 网格布局
  4. Android 中如何从一个App启动另外一个App(如启动支付界面、启动地图界面、应用商场下载App等场景)...
  5. 计算机三级信息安全技术名称的英文缩写(3)
  6. 模型违约概率到信用评分的转化
  7. Docker Issue Network Delay(自定义网络启动会延迟大概40秒!)
  8. 虚拟私有云:内部部署计算的替代解决方案
  9. 议程公布 | 华为、爱立信、中兴三大通信巨头确认出席NEPCON峰会
  10. 上传文件报413 Request Entity Too Large错误解决办法