本书代码链接:
/alex1818/Learning-IoT-UPnP
/wenh77/Learning-IoT-CoAP
/newgogo/Learning-IoT-IoTPlatform
/tuksik/Learning-IoT-HTTP
/pojoba02/Learning-IoT-Gateway
/wrtcoder/Learning-IoT-MQTT
第一章 物联网项目准备
1.1 创建传感器项目
1.2 创建执行器
1.3 创建控制器
1.4 创建摄像头
1.5 总结
第二章 HTTP
2.1 HTTP基础
HTTP是一个无状态的请求/响应协议,客户端从服务器请求信息,然后服务器响应这些请求。一次请求基本是一种方法、一些报头和一些可选的内容组成的。一次响应是由一个三位状态码、一些报头和一些可选的内容组成的。
每个资源最初被认为是一个超文本文件或者HTML文档的集合,后来确定为统一资源定位符URL,客户端只需使用GET方法从响应的服务器请求一个资源。资源由路径、服务器和URL的授权部分确定,并在URL结构中说明。PUT和Delete方法允许客户端从服务器上传和删除内容,而POST方法允许它们将数据发到服务器上的源,如在web表单中。
HTTP定义一组报头,可用于将附加的元信息的请求和响应通过网络发送。这些报头是人能够识别的键值文本对,而键值文本对包含了如何编码、有效期多长、期望的文本类型等信息。内容的类型由content-type报头确定,它确定了要传输内容的类型。报头也提供一种从客户端到服务器的认证方法和一种引进HTTP状态的机制。通过引入cookie文本字符串,服务器可以要求客户端记住cookie,客户端可以将每个请求添加到服务器。
HTTP工作在IP的顶层,HTTP中,机器使用IP地址寻址,它让不同解决方案来实现不同局域网之间的通信成为可能,虽然最常见的以太网网络中更使用的MAC地址。HTTP通信随之完成客户端和服务器之间的TCP,tcp连接确保数据报不丢失并以发送的顺序接收。连接端点由相应的IP地址和端口号定义,默认指定的端口号是80,但也可以使用其他端口号,HTTP端口号8080比较常见。
加密可以通过SSL或者TLS来完成,加密之后,通常成为https。通信使用分离端口,端口号通常是443,。在这种情况下,常见的服务器或者客户端可以使用基于公钥构架PKI的X.509证书进行认证,任何访问该证书的公共部分可以对私有部分拥有者的数据进行加密,私有部门的信息需要解密。这些证书允许服务器域名或者客户端身份认证。它提供了一种方法来检查谁是发行人员以及当证书被撤销之后证书是否无效。
HTTP是面向服务架构SOA,而通过HTTP方式发布的服务成为web服务。有一种很重要的发布web服务的方式称为简单对象访问协议SOAP,SOAP将web方法、参数、返回值、绑定等编码为一种特殊的xml格式,然后使用网络服务描述余元WSDL进行记录。发布web服务的另一种常用方法使用表述性状态转移REST,这提供了一个更简单的,松散耦合体系结构,其中的方法是基于正常HTTP方法和url的查询参数来实现的,而不是使用xml中的SOAP编码。
基于使用HTTP的最新发展包括互联数据、重新抽象网络,任何类型的数据都可以通过统一资源标识符URI来识别。这些数据的语义表征被分为三元组和语义数据格式,例如资源描述框架RDF、机器可读或者简化的RDF三元组TURTLE等容易被人阅读。而基于HTTP的互联网资源的集合被称为web,其后web额进步更名为“语义web”。
2.2 让HTTP支持传感器
2.3 添加HTTP支持的执行器
2.4 为控制器添加HTTP支持
第三章 UPnP协议
通用即插即用UPnP是一个协议或者多协议架构,帮助自组织IP网络中的设备发现彼此,检测每个设备托管的服务并执行动作和报告事件。自组织网络没有预定义的拓扑结构或配置;这里,设备发现自己、适应周围的环境,UPnp很大程度上用于家庭或办公室环境中的消费电子。
3.1 UPnP介绍
UPnP是一个很常见的协议。它被用在家庭及办公室几乎所有拥有网络功能的消费电子产品上,正因为如此,它是数据生活网络联盟DLNA的重要组成部分。UPnP的标准机构是UPnP论坛()。UPnP主要是基于HTTP的应用程序,其中客户端和服务器都是参与者。虽然这里用的是HTTP,然而,扩展后,它还可以用在tcp以及udp上,其中均使用单播寻址HTTPU和多播寻址HTTPMU。在网络中发现设备使用的是简单服务发现协议SSDP,它是基于HTTP UDP(HTTP的UDP实现)的,且事件订阅和通知是基于通用事件通知结构GENA的。无论SSDP还是GENA都引入了新的http方法来进行时间搜索、通知、订阅和退订。设备依靠使用多播寻址和其他可用的服务来通知网络它们的存在找到对方。然而,它们也使用多播寻址在网络中搜索某些类型的设备和服务。这一服务行为被称为调用SOAP网络服务操作。
3.1.1 提供服务体系结构
UPnP定义符合UPnP标准的设备的对象层次。每一个设备包含一个根设备。每个根设备可以发布零个或更多的嵌入式设备和服务。每个嵌入式设备本身可以反复发布更多的服务和嵌入式设别。每个服务一次发布一组动作和状态变量。设备的操作是可以用SOAP网络服务方法调用服务的方法。操作需要一系列的参数。每个参数都有一个名字、方向和一个状态变量索引。从这个索引可以推断出参数的数据类型。状态变量定义了服务的当前状态,并且每一个状态变量都有一个名称、数据类型以及数量值。此外,状态变量可以是常量、时间触发变量和/或多播事件触发变量。当时间状态变量的值被改变时,他们通过时间消息传播到网络。通常情况下,时间触发状态变量只发给那些使用常规HTTP的订阅者。多播事件触发状态变量是通过使用HTTPMU Notify向多播地址的SSDP发送消息来传播的,但使用不同的端口号。我们并不需要订阅此类事件变量以保持更新的值。
3.1.2 设备和服务能力的文档变化
网络中的每个UPnP兼容设备都会被声明在一个设备描述文DDD中,设备本身持有XML文档。设备让网络知道它的存在时总是包含着这个文档的索引。有意者可以下载文档和任何索引材料,了解设备的类型以及如何与之交互。该文档包含了一些机器可以理解的基本信息,也包含了一些人机接口。最后,设备描述文档还包含了嵌入式设备的索引,如果允许的话,可以索引机器发布的所有服务。设备发布的每一项服务都被描述在一个单独的服务控制协议说明SCPD的文档中,设备海豹了每一个xml文档。即使是用SOAP来调用每一个服务的方法,UPnP兼容服务比正常的SOAP网络服务功能还是要少的多。SOAP和WSDL只是给了设备很多选择,但这也造成了互操作性问题。出于这个原因,我们使用一个简单的服务体系结构,替换掉用WSDL来描述服务的方法,直接使用scpd.xml来实现。
3.2 创建设备描述文档
3.3 创建服务描述文档
3.4 提供一个web接口
3.5 创建UPnP接口
3.6 实现静止图像服务
3.7 使用摄像头
3.8 总结
第四章 CoAP协议
对基于小资源受限设备间的资源受限的IP网络通信来说,HTTPU不是一个很实际的选择,因为它需要太多的资源和太多的带宽。一种特殊的情况是底层网络限制数据报文的大小时使用基于IPv6的低功耗无线个人区域网络6LoWPAN,6LowWPAN是一个基于IPv6的无线网络协议的最新版本。约束应用协议CoAP正在尝试解决这个问题。
4.1 生成HTTP二进制文件
CoAP和HTTPU的主要区别在于,CoAP用更紧凑的二进制头替换HTTPU中使用的文本头,而且它减少了头包含的可用选项的数目。优势在于这更易于编码和解析CoAP信息,CoAP也降低了可用方法集,它可以 让你有四种方法选择,GET、POST、PUT、Delete。此外在CoAP中,方法调用可以使用确认和不确认消息服务。当你收到可确认消息,接收方总是返回一个确认信号。反之,如果在给定的时间内没有收到确认应答信号,发送范会重新发送。响应代码的数量也已减少,使实现更简单。CoAP也脱离了在HTTP使用中的互联网媒体类型方案和其他协议并使用裁剪的内容格式集替代,其中每个格式由一个数而不是其对应的互联网媒体类型识别。分配到不同的选择、方法、状态码和内容格式中的CoAP所用的数字的详细列表可以在/assignments/core-parameters/找到。
除了保留的http请求、响应能力和裁剪的集方法和选项,CoAP还提供了一些新的特点。与HTTPU一样,CoAP也支持组播,正如我们在UPNP协议中看到的,这可用于通过防火墙检测设备或通信。CoAP还提供了一套有用的扩展,其中一个扩展提供了一个块传输算法,它允许你传输大容量数据(在受限网络中,大容量数据相比普通的家庭或办公室的IP网络可能是非常小的)。另外一种扩展可以让你有一个事件订阅和通知架构,即当时间发生时发出通知,并且观察到的资源可以订阅。CoAP还支持在单播的情况下通过使用数据传输安全DTLS进行加密。CoAP的未加密版本如下图所示。
4.1.1 寻找开发工具
由于CoAP是比较新的,针对这个协议的开发工具还是比较少。但是有一个Firefox插件可以允许查看并与CoAP资源进行交互,这个工具是Copper(Cu)。基于web的CoAP测试工具可以在http://coap.me/找到,一个CoAP交互服务器可以在http://vs0.inf.ehtz.ch/找到。
4.2 为传感器添加CoAP
4.3 为执行器添加CoAP
4.4 在控制器中使用CoAP
4.5总结
第五章 MQTT协议
我们看到无论HTTP、CoAP还是UPnP都会遇到一个主要问题,即如果穿过防火墙边界。防火墙不仅阻止了传入的连接尝试,它们还会将家庭或者办公网络隐藏在一个单一的IP地址的后面。除非防火墙阻止输出连接,但它只是在显示配置下才能做到这点,如果位于防火墙之外的对话中的所有节点都充当客户端的公用信息中间人broker,并因此允许任何人访问,那么我们就能穿过防火墙边界。消息中间人虽然仅仅作为一个服务器存在,但是它是所有客户端传递消息的中继。使用消息中间人的其中一个协议就是消息队列遥测传输MQTT。
5.1 发布和订阅
MQTT协议基于发布、订阅模式,而不是之前章节研究的请求’/响应模式、事件订阅模式。发布/订阅模式有三种类型的角色actor:
发布者Publisher:发布者的作用是连接消息中间人与发布内容。订阅者Subscriber:他们连接到相同的消息中间人并订阅他们感兴趣的内容。消息中间人Message Broker:用来确保发布的内容传达给了对此有兴趣的用户。
内容是由主题确定的。当发布内容时发布者可以选择是否将内容保留在服务器上。如果保留下来,每个订阅者订阅的时候将直接接收到最新发布的值。此外,主题会被排序成一个有关主题的树形结构,就像一个文件系统。斜杠“/”是在描述一个话题路径时用来作分隔符的。当订阅内容时,一个订阅者可以订阅一个由其路径提供的特定主题,或者使用散列通配符“#”的整个分支。还有一个单级通配符:加号字符“+”。举个例子,将Clayster/Learning/Sensor/Temperature主题发布我们的温度传感器测量值。订阅Clayster/+/Sensor/# 便将订阅所有以Clayster/开始的Sensor类的子分支,然后是所有子主题,接着将是Sensor/的子主题。
在发布内容的时候,MQTT有三个级别的服务质量(QoS)可以使用。最低级别是一个未知的服务,在这一级别中,所有的信息将至多一次传递给每个用户。下一个级别是已知服务,在这一级别中,每个收件人确认已经收到发布的消息。如果没有接收到任何确认收到的信息,该消息则将会被再次发送。这可以确保该消息至少被传递了一次。最高级别是保证服务。在这一级别中,消息不仅是需要确认的,而且是在两个步骤中发送的。首先,它被传播,然后递送。这中间的每一步都会被确认。这有可能确保该内容被准确地传递给每个订阅服务器。
在MQTT中用户认证的支持是比较弱的。虽然存在纯文本的用户名和密码认证,但是如果用户不托管在受控环境中,它便会提供个明显的风险。为了规避最明显的问题,MQTT可以使用SSL TIS加密连接。在这种情况下,对客户端来说最重要的是验证服务器证书,而用户证书则可以妥协。
其他方法,在MQTT协议本身中是没有定义的,包括使用客户端证书或者预共享密钥来识别客户端,而不是使用由协议提供的用户名和密码选项。使用专有的方法加密内容还可以确保只有具有足够凭据的接收器可以解密内容。尽管这种方法可靠,但是它减少了互操作性,并让每个设备增加了负载,这违反协议的既定目标。
MQTT协议本身是不考虑安全性的,对于开发人员来说自己考虑安全性是非常重要的。此外,用户凭证必须手动或者使用外带的专有方法来管理。
5.2 给传感器添加MQTT协议
5.3 给执行器添加MQTT协议
5.4 给控制器添加MQTT协议
5.5 总结
第六章 XMPP协议
在前面的章节中,我们看到了使用消息代理穿越防火墙边界的好处。但MQTT协议被限制在一个单一的通信模式:发布/订阅模式。在这种情况下是非常有用的,其中一件事只公布数据,并且其数据有不少消费者,数据是同质的,
并且大多数报告的数据项是实际用到的。如果单独定制消息、瞬时值、实时或双向通信是重要的,或者,如果相比与被更新的频率数据很少使用,其他的通信模式将更为合适。
在本章中,我们将介绍可扩展消息处理现场协议( Extensible Messaging and Presence protocol,XMPP)。XMPP还使用消息代理来绕过防火墙的屏障。但除了发布/订阅模式,它也支持其他通信模式,如点对点请求/响应和异步消息,这让你有更丰富的通信体验。你将了解:
6.1 XMPP基础知识
XMPP最初设计用于即时消息应用程序(或聊天)。它是一个开放的协议,由 Internet工程任务组(IETF)来进行标准化,因为是其HTTP和CoAP。由于其灵活性和通信模式的丰富性,即使它是第一个设计用于聊天的应用程序,其
本身也要好于其他应用,如那些用于loT的。在我们在项目中使用XMP之前,快速了解一下XMPP是一个好主意。
6.1.1联合全局的可扩展性
XMPP架构的巨大成功建立在简单邮件传输协议( Simple Mail Transfer Protocol,SMTP)的全局可扩展性之上。所不同的是,XMPP设计用于实时瞬时消息传送应用,其中越小的消息以尽可能少的延迟被发送,并且没有任何持久性XMPP使用XMPP服务器的联合网络作为消息代理,让独立防火墙后面的客户端相互通信。每个服务器控制着自己的域和域用户进行身份验证。客户端可以和其他域上的客户端通过运用安全方式进行通信,这种安全方式是服务器之间以安全的方式创建连接,在它们的域上进行信息交换。正是这种联合方式,
可让你有一个全局的可扩展架构。所有这一切都发生在服务器级别,所以没有什么需要客户端担心的。客户端只需要确保保持它们与各自的服务器的连接,并通过服务器,将有可能通过联合网络给其他客户端发送信息。这种联合架构可以让XMPP可扩展,并允许你在同一个联合网络做数十亿设备之间的相互通信.
图6-1显示了在一个联合网络中的防火墙后面的客户端如何(C1、C2、C3)连接到不同的服务器(Sl、S2、S3)进行交换消息。
6.1.2提供全局的身份标识
KMPP服务器除为客户端之间的消息传递之外还能做得更多,它们还为每一个客户端进行身份验证。如果在XMPP服务器的全局联合网络中是一个公共服务区,那么它就是一个全局身份。当客户端连接后,服务器确保客户通过提供其相应的客户端凭据,其中将包括一个用户名和密码进行身份验证。做这个认证是安全地使用基于简单的身份验证和安全层(SASL)的可扩展架构。该连接也可以被切换到传输层安全(TLS)通过在客户端和服务器之间的协商,加密它们之间的通信。客户端的身份通常被称为XMPP地址或 Jabber ID(JID)。
每个连接也绑定到一个特定的资源,通常是一个随机字符串。当连接中包含用户名、域名、资源时称为“全JID”,当连接中只包含用户名和域名时称为“裸JID”(见图6-2)。
6.1.3授权通信
对于使用XMPP服务器中继的通信而不是无服务器对等网络技术的另外个重要原因是,以确保只有被授权的客户端通信将会被中继。这个特性就派上用场了,特别是对于具有有限的决策能力的小型设备。服务器以通过确保全JID标识符只代替裸JD标识符,以与应用程序或设备背后进行通信。其原因有二:
首先,多个客户端可以在同一时间使用同一个账号。你需要为XMPP服务器提供全JD的部分资源才能够确定哪个连接相应的消息应被转发。只有此连接将收到消息。这使得实际客户端直接相互通信。其次,只有受信任的部分(或朋友)给定资源的权限,一旦事情或者应用连接。反过来,这意味着只有朋友能相互发消息,只要资源部分是足够长的和随机的,资源部分保持隐藏,不再其他地方发布。
6.1.4在线存在的感知
为了了解相应客户端的部分资源,可以给裸JD发送存在的订阅。如果被远程的客户端接收,每次接触状态都会发生改变,通知你是否是联机、脱机、远离、忙等。在这种存在的消息中,也可以接受连接的全JD。一旦存在的订阅被远程设备端接受,它可能发送自己的存在的订阅,你可以接受或者拒绝。如果双方都接受并订阅了对方的存在,那么双方就说是朋友。
在XMPP中,存在多个客户端使用相同的裸JID,这种情况下的解决方案,你需要追踪所有的全JID汇报给你的裸JID。但是在本书所有的例子中,我们假设所有的东西有它自己的JID,而且只有相应的东西会使用它的JID令在开发期间,如果你用另一个客户端激活的东西所使用的账户,你可能会困惑,在你的连接中它和它的朋友给所有的朋友发送存在的信息。因此,他们可能会直接与连接的最后一个应用程序的通信。当这个应用程序关闭,你将需要重新复位,重新连接,或者在相应的东西里为它的朋友重置存在的状态,更新与全JD的交流。
XMPP服务器为每一个和它相应的存在的订阅状态维护联系的列表。这个列表称为花名册。这些列表被称为花名册。客户端只需要连接,然后从服务器接收它的花名册。这使得有可能在物理平台移动应用程序和不必存储在物理设备中的联系人信息
6.1.5使用XML通信
XMPP通信包含XML片段的双向流。之所以使用XML一直争论不休,和以二进制作为选择相比,它对消息的大小为副作用,但也有很多积极的含义。这些可以如下所示
有固定的内容格式使得交换和复用数据更简单XML简单进行编码、解码和解析,使得数据电报被明确定义。使文本更容易被人阅读,让编写文档和调试更简单。XML有标准工具用于搜索验证和转换,这允许更加高级的操作和数据分析,不需要以前的消息格式的知识通过使用XML命名空间,消息可以在不同协议扩展之间分离,而且支持版本控制。
在这种情况下,消息的大小是很重要的,在XMPP中有一些方法使用有效的XML交换将XML压缩成非常高效的二进制消息。
6.1.6通信模式
XMP支持丰富的通信模式。它通过提供三种叫作节的通信原语做到这一点。我们已经提出了第一种,存在节,这是用来发送有关自己感兴趣的和授权方的信息。第二种是消息节,这是用来发送异步消息到一个给定的接收器。第三种是IQ节,短信息/查询,这是用来提供一个请求/响应通信模式。一个请求被发送到一个给定的接收器,它返回一个响应或错误。
有四种不同类型的节接收器。首先,你必须同行。为了对等通信,你要提供对等连接的全JID作为你的节的目的地址。然后,你有一台服务器。要直接与服务器通信,应使用服务器的域名作为目标地址。服务器可能托管各种服务器组件。这些可能是由外部的应用程序内部或外部元件托管。这些组件使用相应
的子域名标记地址,并且可以被动态地发现使用简单的请求到服务器。最后,你有联系。为和联系相互通信,(联系被服务器隐式地处理,并且处理联系的服务器取决于信息类型)你需要使用联系的裸JID作为地址。进一步的通信模式由XMPP服务器托管不同的服务器组件提供。这样的模式的例子包括发布/订阅模式(其中数据项被传播到用户)和多播模式(在XMPP,这就是所谓的多用户聊天,即消息被实时地传播给房间中的成员)。
6.1.7扩展XMPP
因此,通过使用XML,XMPP提供了一个协议,这个协议是开放的,易于使用的,可扩展的和灵活的。这导致了一系列扩展被创建。任何人都可以创建专有扩展到XMPP,但存在一个叫XMPP标准基金会( XMPP Standards Foundaion,xSF)的公开论坛,并且发布了一组可以在论坛中公开审查和进行讨论并免费供人使用的扩展。这些扩展被称为XMPP扩展协议( XMPP Extension prooodl,xXEP)。XSF发布这样的扩展以便促进互操作性。任何人都可以申请成为会员,从而努力促进新的或现有扩展的开发。
XSF管理扩展的列表、可用的服务器、客户端软件、客户端库等。XSF可以在/ extensions./找到。具体而言,所有的XMPP扩展都可在htp:// extensions/中找到。
为了发布而被接受的程序扩展通过三级验收。首先,有实验阶段,其中个扩展被识别为为重要用途提供方案(但仍在讨论中,并且可以在这个过程中进行显著改变)的因素。下一步是在起草阶段,其中扩展经历了广泛的讨论和技术审查。如果可能的话这个阶段为扩展在做的任何变化应当一直向后兼容。最后一个阶段就是不再做出变化。
在写这篇文章的时候,有一系列瞄准物联网的新的实验扩展被XSF公布。我们将在我们的例子中使用这些扩展。为了提高互操作性,实现这些扩展的源代码也被列人 Clayster. Library.loT库。这些扩展包括扩展与传感器数据或控制执行器进行通信,并发送基于用户特定的条件下的异步事件。它们还包括扩展注
册安全设备和提供服务的网络。此外我们所有的例子集中避免敏感信息的存储。相反数据将应要求提供,仅给被自己信任的各方。
6.1.8连接到服务器
有很多种可用的方法连接到XMPP服务器,最通用的是将在本书中作为例子使用的方法,即客户端通过一个正常的TCP套接字连接,连接到任何XMPP的客户服务,如果连接到 DNS-SRⅤ记录可用,或不是5222端口。然后XML片段在两个方向上传送,如RFC61206122所述。
如果服务器支持EⅪ压缩可以通过谈判通过此连接,一种替代的结合的方法是连接到xmp- client服务直接以避免从XML切换到个EⅪI压缩的XML。
连接到XMPP服务器的另一种方式是通过使用双向流过同步的HTTP(BOSH)。这允许客户也使用XMPP,只能访问HTTP。有些服务器还发布了XMPP网络套接字接口。这使得客户端有可能访问XMPP网络,如网络浏览器等。XMPP服务器还接收来自其他XMPP服务器的连接。这是XMPP的联合功能的一部分。这些服务器使用XMPP服务器的服务名称相互连接,如果 DNS-SRV记录都可用,或不是5269端口。最后一个值得一提的方法是通过一个特殊的服务器组件可以连接到的端口(5275)连接到服务器。此端口不能在互联网上公开,但可用于扩展XMPP服务器的功能,如先前所述。图6-3显示了相对于互联网架构的XMPP服务器的功能。
6.1.9附加安全的配置
在本节中我们将介绍几种新的通信模式,这在物联网中是有用的。一个这样的范式是建立身份,自己创造自己在网络上的身份。一旦它已经创造了网络上的身份,我们将介绍一种方法来注册的它,发现它,并安全地声称它的所有权。一旦所有权一直声称,我们就可以使用配置扩展委派信任到信任的第三方,配置服务器,我们将使用以控制谁可以连接到我们的设备和它们能做什么。
为了实现发现和配置,作为服务器组件,我们需要从承载这些组件的服务器获得支持。出于这个原因,我们将可在 thingk.me使用XMPP服务器。该服务器在htp:// thingk.me/上还具有WEB界面,用户可以控制他们声称的设备。
6.2 为对象添加XMPP
6.3 提供额外的安全层
6.4 为执行器添加XMPP支持
6.5 为摄像头添加XMPP支持
6.6 为控制器添加XMPP支持
6.7 串联全部
6.8 总结
第七章 使用物联网服务平台
7.1 选择物联网平台
7.2 使用XMPP接入我们的设备
7.3 创建我们的控制应用
7.4 总结
第八章 创建协议网关
8.1 理解协议桥接
8.2 使用抽象模型
8.3 Clayster抽象模型基础知识
8.4 理解CoAP网关架构
8.5 总结
第九章 安全和互操作性
9.1 理解风险
9.2 攻击模式
9.3 实现安全的工具
9.4 互操作的需要
9.5 总结