RESTful的CoAP协议

CoAP: 嵌入式系统的REST

引自维基百科上的介绍,用的是谷歌翻译。。。

受约束的应用协议(COAP)是一种软件协议旨在以非常简单的电子设备,使他们能够在互联网上进行交互式通信中使用。它特别针对小型低功率传感器,开关,阀门和需要被控制或监督远程,通过标准的Internet网络类似的组件。 COAP是一个应用层协议,该协议是用于在资源受限的网络连接设备,例如无线传感器网络节点使用。 COAP被设计为容易地转换为HTTP与Web简化集成,同时也能满足特殊的要求,例如多播支持,非常低的开销,和简单性。多播,低开销,以及简单性是因特网极其重要物联网(IOT)和机器对机器(M2M)设备,这往往是积重难返,有太多的内存和电源,比传统的互联网设备有。因此,效率是非常重要的。 COAP可以在支持UDP或UDP的模拟大多数设备上运行。

简单地来说,CoAP是简化了HTTP协议的RESTful API,因而也只提供了REST的四个方法,即PUT,GET,POST和DELETE。对于微小的资源受限,在资源受限的通信的IP的网络,HTTP不是一种可行的选择。它占用了太多的资源和太多的带宽。而对于物联网这种嵌入式设备来说,关于资源与带宽,是我们需要优先考虑的内容。

CoAP采用了二进制报头,而不是文本报头(text header)

CoAP降低了头的可用选项的数量。

CoAP减少了一些HTTP的方法

CoAP可以支持检测装置

CoAP 命令行工具

为了测试测试我们的代码是否是正确工作,我们需要一个CoAP的命令行工具。目前有两个不错的工具可以使用。

CoAP-cli,一个基于NodeJS的CoAP命令行工具,其核心是基于Node-CoAP库。

libcooap,一个用C写的CoAP命令行工具。

FireFox Copper, 一个Firefox的插件。

Node CoAP CLI

安装命令如下

bashnpm install coap-cli -g

CoAP命令行

在coap-cli中,一共有四个方法。分别表示REST的四种不同的方式:

bashCommands:

get performs a GET request

put performs a PUT request

post performs a POST request

delete performs a DELETE request

bashcoap get coap://vs0.inf.ethz.ch/

(2.05) ************************************************************

I-D

测试一下现在的最小的物联网系统CoAP版

bashcoap get coap://iot-coap.phodal.com/id/1

(2.05) [{"id":1,"value":"is id 1","sensors1":19,"sensors2":20}]

libcoap

mac os libcoap安装

Mac OS下可以直接用

bashbrew install libcoap

Ubuntu libcoap安装

Ubuntu GNU/Linux下

Windows libcoap安装

Windows 下

安装完libcoap,我们可以直接用自带的两个命令

bashcoap-client

coap-server

1.用coap-server启一个CoAP服务

bashcoap-server

2.客户端获取数据

bashcoap-client -m get coap://localhost

返回结果

bashv:1 t:0 tkl:0 c:1 id:37109

This is a test server made with libcoap (see http://libcoap.sf.net)

Copyright (C) 2010--2013 Olaf Bergmann

Firefox Copper

为了能访问coap://localhost/,于是我们便需要安装一个Firefox并安装一个名为Copper的插件。

CoAP Hello,World

接着我们便开始试试做一个简单的CoAP协议的应用:

这里用到的是一个Nodejs的扩展Node-CoAP

node-coap is a client and server library for CoAP modelled after the http module.

Node-CoAP是一个客户端和服务端的库用于CoAP的模块建模。创建一个package.json文件,添加这个库

javascript{

"dependencies":{

"coap": "0.7.2"

}

}

接着执行

bashnpm install

就可以安装好这个库。如果遇到权限问题,请用

bashsudo npm install

接着,创建这样一个app.js

javascriptconst coap = require('coap')

, server = coap.createServer()

server.on('request', function(req, res) {

res.end('Hello ' + req.url.split('/')[1] + '\n')

})

server.listen(function() {

console.log('server started')

})

执行

bashnode app.js

便可以在浏览器上访问了,因为现在什么也没有,所以什么也不会返回。

接着下来再创建一个client端的js,并运行之

javascriptconst coap = require('coap')

, req = coap.request('coap://localhost/World')

req.on('response', function(res) {

res.pipe(process.stdout)

})

req.end()

就可以在console上输出

bashHello World

也就达到了我们的目的,用CoAP协议创建一个服务,接着我们应该用它创建更多的东西,如产生JSON数据,以及RESTful。和HTTP版的最小物联网系统一样,CoAP版的最小物联网系统也是要返回JSON的。

CoAP 数据库查询

Node Module

这说里NodeJS Module的意义是因为我们需要在别的地方引用到db_helper这个库,也就是下一小节要的讲的内容。

这样我们就可以在server.js类似于这样去引用这个js库。

javascriptvar DBHelper = require('./db_helper.js');

DBHelper.initDB();

而这样调用的前提是我们需要去声明这样的module,为了方便地导出函数功能调用。

javascriptfunction DBHelper(){

}

DBHelper.initDB = function(){};

module.exports = DBHelper;

Node-Sqlite3

这次我们用的是SQLite3(你可以用MySQL,出于安全考虑用SQLite3,SQLite3产生的是一个文件)。一个简单的initDB函数

javascriptvar db = new sqlite3.Database(config["db_name"]);

var create_table = 'create table if not exists basic (' + config["db_table"] + ');';

db.serialize(function() {

db.run(create_table);

_.each(config["init_table"], function(insert_data) {

db.run(insert_data);

});

});

db.close();

首先从配置中读取db_name,接着创建table,然后调用underscore的each方法,创建几个数据。配置如下所示

javascriptconfig = {

"db_name": "iot.db",

"db_table": "id integer primary key, value text, sensors1 float, sensors2 float",

"init_table":[

"insert or replace into basic (id,value,sensors1,sensors2) VALUES (1, 'is id 1', 19, 20);",

"insert or replace into basic (id,value,sensors1,sensors2) VALUES (2, 'is id 2', 20, 21);"

],

"query_table":"select * from basic;"

};

而之前所提到的url查询所做的事情便是

javascriptDBHelper.urlQueryData = function (url, callback) {

var db = new sqlite3.Database("iot.db");

var result = [];

console.log("SELECT * FROM basic where " + url.split('/')[1] + "=" + url.split('/')[2]);

db.all("SELECT * FROM basic where " + url.split('/')[1] + "=" + url.split('/')[2], function(err, rows) {

db.close();

callback(JSON.stringify(rows));

});

};

将URL传进来,便解析这个参数,接着再放到数据库中查询,再回调回结果。这样我们就可以构成之前所说的查询功能,而我们所谓的post功能似乎也可以用同样的方法加进去。

查询数据

简单地记录一下在IoT-CoAP中一次获取数据地过程。

先看看在示例中的Get.js的代码,这关乎在后面server端的代码。

javascriptconst coap = require('coap')

,requestURI = 'coap://localhost/'

,url = require('url').parse(requestURI + 'id/1/')

,req = coap.request(url)

,bl = require('bl');

req.setHeader("Accept", "application/json");

req.on('response', function(res) {

res.pipe(bl(function(err, data) {

var json = JSON.parse(data);

console.log(json);

}));

});

req.end();

const定义数据的方法,和我们在其他语言中有点像。只是这的const主要是为了程序的健壮型,减少程序出错,当然这不是javascript的用法。

我们构建了一个请求的URL

bashcoap://localhost/id/1/

我们对我们的请求添加了一个Header,内容是Accept,值是'application/json'也就是JSON格式。接着,便是等待请求回来,再处理返回的内容。

判断请求的方法

在这里先把一些无关的代码删除掉,并保证其能工作,so,下面就是简要的逻辑代码。

javascriptvar coap = require('coap');

var server = coap.createServer({});

var request_handler = require('./request_handler.js');

server.on('request', function(req, res) {

switch(req.method){

case "GET": request_handler.getHandler(req, res);

break;

}

});

server.listen(function() {

console.log('server started');

});

创建一个CoAP服务,判断req.method,也就是请求的方法,如果是GET的话,就调用request_handler.getHandler(req, res)。而在getHandler里,判断了下请求的Accept

javascriptrequest_helper.getHandler = function(req, res) {

switch (req.headers['Accept']) {

case "application/json":

qh.returnJSON(req, res);

break;

case "application/xml":

qh.returnXML(req, res);

break;

}

};

如果是json刚调用returnJSON,

Database与回调

而这里为了处理回调函数刚分为了两部分

javascriptquery_helper.returnJSON = function(req, res) {

DBHelper.urlQueryData(req.url, function (result) {

QueryData.returnJSON(result, res);

});

};

而这里只是调用了

javascriptDBHelper.urlQueryData = function (url, callback) {

var db = new sqlite3.Database(config["db_name"]);

console.log("SELECT * FROM basic where " + url.split('/')[1] + "=" + url.split('/')[2]);

db.all("SELECT * FROM basic where " + url.split('/')[1] + "=" + url.split('/')[2], function(err, rows) {

db.close();

callback(JSON.stringify(rows));

});

};

这里调用了node sqlite3去查询对应id的数据,用回调处理了数据无法到外部的问题,而上面的returnJSON则只是返回最后的结果,code以及其他的内容。

javascriptQueryData.returnJSON = function(result, res) {

if (result.length == 2) {

res.code = '4.04';

res.end(JSON.stringify({

error: "Not Found"

}));

} else {

res.code = '2.05';

res.end(result);

}

};

当resulst的结果为空时,返回一个404,因为没有数据。这样我们就构成了整个的链,再一步步返回结果。

在IoT-CoAP中我们使用到了一个Block2的东西,于是便整理相关的一些资料,作一个简单的介绍,以及在代码中的使用。

CoAP Block

CoAP是一个RESTful传输协议用于受限设备的节点和网络。基本的CoAP消息是一个不错的选择对于小型载荷如

温度传感器

灯光开关

楼宇自动化设备

然而,有时我们的应用需要传输更大的有效载荷,如——更新固件。与HTTP,TCP做繁重工作将大型有效载荷分成多个数据包,并确保他们所有到达并以正确的顺序被处理。

CoAP是同UDP与DLTS一样是基于数据报传输的,这限制了资源表示(resource representation)的最大大小,使得传输不需要太多的分割。虽然UDP支持通过IP分片传输更大的有效载荷,且仅限于64KiB,更重要的是,并没有真正很好地约束应用和网络。

而不是依赖于IP分片,这种规范基本COAP了对“块”选项,用于传输信息从多个资源区块的请求 - 响应对。在许多重要的情况下,阻止使服务器能够真正无状态:服务器可以处理每块分开传输,而无需建立连接以前的数据块传输的其他服务器端内存。

综上所述,块(Block)选项提供了传送一个最小的在分块的方式更大的陈述。

CoAP POST

看看在IoT CoAP中的post示例。

javascriptconst coap = require('coap')

,request = coap.request

,bl = require('bl')

,req = request({hostname: 'localhost',port:5683,pathname: '',method: 'POST'});

req.setOption('Block2', [new Buffer('1'),new Buffer("'must'"), new Buffer('23'), new Buffer('12')]);

req.setHeader("Accept", "application/json");

req.on('response', function(res) {

res.pipe(bl(function(err, data) {

console.log(data);

process.exit(0);

}));

});

req.end();

Block2中一共有四个数据,相应的数据结果应该是

javascript{ name: 'Block2', value: }

{ name: 'Block2', value: }

{ name: 'Block2', value: }

{ name: 'Block2', value: }

这是没有解析的Block2,简单地可以用

javascript_.values(e).toString()

将结果转换为

Block2,1

Block2,'must'

Block2,23

Block2,12

接着按","分开,

javascript_.values(e).toString().split(',')[1]

就有

bash[ '1', '\'must\'', '23', '12' ]

便可以很愉快地将其post到数据库中了,

在做IoT-CoAP的过程中只支持JSON,查阅CoAP的草稿时发现支持了诸多的Content Types。

CoAP Content Types

以下文字来自谷歌翻译:

互联网媒体类型是通过HTTP字符串标识,如“application/xml”。该字符串是由一个顶层的类型“applicaion”和子类型的“XML”。为了尽量减少使用这些类型的媒体类型来表示的开销消息有效载荷,COAP定义一个标识符编码方案互联网媒体类型的子集。预计这桌将可扩展标识符的值的IANA维护。内容类型选项被格式化为一个8位无符号整数。初始映射到一个合适的互联网媒体类型标识符表所示。复合型高层次类型(multipart和不支持消息)。标识符值是从201-255保留的特定于供应商的,应用程序特定的或实验使用和不由IANA。

下面是HTTP的标识符及类型

Internet media type

Identifier

text/plain (UTF-8)

0

text/xml (UTF-8)

1

text/csv (UTF-8)

2

text/html (UTF-8)

3

image/gif

21

image/jpeg

22

image/png

23

image/tiff

24

audio/raw

25

video/raw

26

application/link-format [I-D.ietf-core-link-format]

40

application/xml

41

application/octet-stream

42

application/rdf+xml

43

application/soap+xml

44

application/atom+xml

45

application/xmpp+xml

46

application/exi

47

application/x-bxml

48

application/fastinfoset

49

application/soap+fastinfoset

50

application/json

51

而在CoAP中只有简单地几个

Media type

Encoding

Id.

Reference

text/plain;

-

0

[RFC2046][RFC3676][RFC5147]

charset=utf-8

application/

-

40

[RFC6690]

link-format

application/xml

-

41

[RFC3023]

application/

-

42

[RFC2045][RFC2046]

octet-stream

application/exi

-

47

[EXIMIME]

application/json

-

50

[RFC4627]

简单地说就是:

诸如application/json的Content Types在CoAP中应该是50。如上表所示的结果是其对应的结果,这样的话可以减少传递的信息量。

CoAP JSON

于是在一开始的时候首先支持的便是"application/json"这样的类型。

首先判断请求的header

javascriptrequest_helper.getHandler = function(req, res) {

switch (req.headers['Accept']) {

case "application/json":

qh.returnJSON(req, res);

break;

case "application/xml":

qh.returnXML(req, res);

break;

}

};

再转至相应的函数处理,而判断的依据则是Accept是不是"application/json"。

javascriptregisterFormat('text/plain', 0)

registerFormat('application/link-format', 40)

registerFormat('application/xml', 41)

registerFormat('application/octet-stream', 42)

registerFormat('application/exi', 47)

registerFormat('application/json', 50)

对应地我们需要在一发出请求的时候设置好Accept,要不就没有办法返回我们需要的结果。

javascriptreq.setHeader("Accept", "application/json");

返回JSON

在给IoT CoAP添加了JSON支持之后,变得非常有意思,至少我们可以获得我们想要的结果。在上一篇中我们介绍了一些常用的工具——CoAP 命令行工具集。

CoAP客户端代码

开始之前我们需要有一个客户端代码,以便我们的服务端可以返回正确的数据并解析

javascriptvar coap = require('coap');

var requestURI = 'coap://localhost/';

var url = require('url').parse(requestURI + 'id/1/');

console.log("Request URL: " + url.href);

var req = coap.request(url);

var bl = require('bl');

req.setHeader("Accept", "application/json");

req.on('response', function(res) {

res.pipe(bl(function(err, data) {

var json = JSON.parse(data);

console.log(json);

}));

});

req.end();

代码有点长内容也有点多,但是核心是这句话:

javascriptreq.setHeader("Accept", "application/json");

这样的话,我们只需要在我们的服务端一判断,

javascriptif(req.headers['Accept'] == 'application/json') {

//do something

};

这样就可以返回数据了

CoAP Server端代码

Server端的代码比较简单,判断一下

javascriptif (req.headers['Accept'] == 'application/json') {

parse_url(req.url, function(result){

res.end(result);

});

res.code = '2.05';

}

请求的是否是JSON格式,再返回一个205,也就是Content,只是这时设计是请求一个URL返回对应的数据。如

bashcoap://localhost/id/1/

这时应该请求的是ID为1的数据,即

javascript[ { id: 1, value: 'is id 1', sensors1: 19, sensors2: 20 }]

而parse_url只是从数据库从读取相应的数据。

javascriptfunction parse_url(url ,callback) {

var db = new sqlite3.Database(config["db_name"]);

var result = [];

db.all("SELECT * FROM basic;", function(err, rows) {

callback(JSON.stringify(rows));

})

}

并且全部都显示出来,设计得真是有点不行,不过现在已经差不多了。

coap python_一步步搭建物联网系统——RESTful的CoAP协议相关推荐

  1. 如何从0到1搭建物联网系统?

    如何从0到1搭建物联网系统? 2019年是一个好的开端,在互联网行业混迹3年,充分理解互联网行业关于用户思维.平台思维的诠释后,以及对于敏捷研发.协同工作等新思想新管理模式实践后,我准备回身物联网产业 ...

  2. python iot 开源_开源IOT 最小物联网系统

    文档 一步步搭建物联网系统 HTTP vs CoAP 现有的这个版本是HTTP版,目前的CoAP版正在开发中,欢迎加入. https://github.com/phodal/iot-coap Mini ...

  3. 物联网系统的搭建(九)

    构建基于CoAP协议的物联网系统 1 CoAP: 嵌入式系统的REST 引自维基百科上的介绍,用的是谷歌翻译... 受约束的应用协议(COAP)是一种软件协议旨在以非常简单的电子设备,使他们能够在互联 ...

  4. rola物联网框架_如何搭建一个物联网系统框架?

    下面将谈到几个关键问题: 设备如何接入网络? 设备间如何通信? 物联网数据的用途? 如何搭建起一个物联网系统框架呢?它的技术架构又是怎么样呢? 物联网终端软件系统架构? 物联网云平台系统架构? 1.物 ...

  5. 开源系统搭建物联网和智能家居平台

    一.项目简介 1. 物美智能 (wumei-smart) 是一个简单易用的生活物联网平台.可用于搭建物联网平台以及二次开发和学习. 2. 设备接入使用EMQX消息服务器,加密认证:后端采用Spring ...

  6. 【迷你强的物联网】起始篇-简介与MQTT服务器【从零开始搭建自己的物联网系统】

    简介 此为系列文章,主要写什么是物联网,当然啦,这个概念过于抽象,所以我会从自己动手构建出一个完整的物联网系统这个方式来折腾.   这个项目也会是一个连载项目,完成一部分就会发布出来,会同步更新于工坊 ...

  7. 毕业设计之进销存管理系统 —— 一步步搭建自己的框架及系统

    大学四年,即将毕业! 大学期间的最后一篇博客,总结分享下我做的毕业设计.我选的论文命题为<燃气管网设备仪器进销存管理系统之后台设计>,由于我们专业只有我一个走技术路线,所以,我一个人完成了 ...

  8. IoT -- (四) 物联网系统架构介绍

    物联网系统框架介绍 下面将谈到几个关键问题: 设备如何接入网络? 设备间如何通信? 物联网数据的用途? 如何搭建起一个物联网系统框架呢?它的技术架构又是怎么样呢? 物联网终端软件系统架构? 物联网云平 ...

  9. IOT(5)---物联网系统框架介绍

    转载: https://blog.csdn.net/robert_tin 物联网系统框架介绍 下面将谈到几个关键问题: 设备如何接入网络? 设备间如何通信? 物联网数据的用途? 如何搭建起一个物联网系 ...

  10. 物联网系统中常见的通信协议分析

    物联网(Internet of Things, 简称IoT)是指将各种传感器.设备等通过互联网连接起来,形成一个庞大的网络,实现物与物之间的互联互通.在实现这个过程中,各种不同的通信协议被广泛应用.本 ...

最新文章

  1. Comp-Agg (A Compare-Aggregate Model for Matching Text Sequences)
  2. linux 内核load addr,linux2.4启动分析(1)---内核启动地址的确定 vmlinux LOAD_ADDR ZRELADDR...
  3. 怎么退出自适应巡航_沃尔-ACC 自适应巡航控制系统
  4. vue省市区三级联动mysql,js/json,html/jsp
  5. 4-输出基本数据类型
  6. opencv中mean函数耗时_使用OpenCV进行人脸对齐
  7. 【ZZULIOJ】1047: 对数表
  8. (十二)GA-RPN----2019CVPR论文解读
  9. JS仿iGoogle自定义首页模块拖拽效…
  10. 工业级路由器和家用路由器的区别_工业级路由器和家用路由器有何区别?
  11. html5 保存 搜索历史,前端实现搜索记录功能也就是天猫app历史记录存储方便浏览 - 今天的代码你撸了嘛...
  12. SpringBoot图片上传失败
  13. 区块链+跨境支付的应用及案例分析
  14. 华为路由器:WLAN直连式三层组网实验
  15. 解决申请 Googl e账号填写电话号码不能验证的问题
  16. SAP SD 自定义销售订单审批状态
  17. 云服务器迁移 (全网最省钱最详细攻略)
  18. 计算机网络:标准化工作及组织
  19. 工作汇报ppt案例_职场PPT实战:秒杀同事,老板爱看,汇报还得这么干
  20. java直接生成chm

热门文章

  1. 硕士android毕业答辩ppt,硕士研究生毕业答辩ppt全攻略
  2. FFS学习 (FTL)
  3. ESP32 之 ESP-IDF 实战(一)—— 物联网风力摆控制系统(①姿态解算部分)
  4. 5G物联网数据网关助力工业企业转型升级
  5. win10系统下JDK环境变量配置失败的原因
  6. STM32工程,Keil软件新建工程详细步骤
  7. 汉诺塔 java 递归_如何实现java汉诺塔递归算法
  8. C++实现双人对战五子棋(附源码)
  9. django models filter查询条件
  10. 肿么查找联想笔记本的序列号