4

PHP 也能开发物联网应用程序

 3 years ago
source link: https://qq52o.me/2779.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

PHP 也能开发物联网应用程序

后端开发 / 更新于 2021年1月18日 / 2 条评论
simps-mqtt.png!blog

通过抓包的方式来介绍和学习 MQTT 协议,结合真实存在的网络字节,让 PHP 程序猿不存在学习压力,循序渐进的了解熟悉 MQTT 协议

在 5G 时代的背景下,我们也将迎来一个万物互联的时代,习惯了平常的 Web 应用开发,学习一下物联网相关技术也是对自己技术一大提升。

PHP 作为脚本语言,官方定位是一个适合 Web 开发的语言,那么如何使用 PHP 开发一个物联网应用?

首先我们需要知道物联网中常用的一些通讯协议,例如 MQTTModbusCoap 等等。

这里我就以 MQTT 协议为例,讲解 PHP 如何来开发一个物联网应用?

PHP(“PHP: Hypertext Preprocessor”,超文本预处理器的字母缩写)是一种被广泛应用的开放源代码的多用途脚本语言,它可嵌入到 HTML 中,尤其适合 web 开发。

这句话是来自 PHP 官网,可见 PHP 官方对自己的定位就是 web 开发,但是尽管 PHP 的开发是以服务端脚本为目的,但事实上其功能远不局限与此…

它不但可以作为服务端脚本,也可以作为命令行脚本,当你在使用 php -v 查看 PHP 版本或者 php -m 查看安装的扩展时,这时你就在操作命令行脚本了。

了解过 Swoole 的小伙伴应该都知道:Swoole 的大部分功能只适用于 CLI 模式,也就是命令行脚本,在使用时就需要通过在命令中执行 php index.php 这种方式来运行。

而且 PHP 还能编写桌面应用程序,关于如何编写桌面应用程序这里就不过多说明,感兴趣的可以去 GitHub 或者谷歌了解一下。

那么现在都已经到了 2021 年,你还仅仅使用 PHP 来进行 CRUD 吗?没有其他什么能做了?答案当然是不!

在 Swoole 的加持之下,PHP 现在可以开发:即时通信(IM)、实时视频语音(WebRTC)、网络游戏(斗地主、五子棋、魔兽世界、传奇 2)以及物联网(MQTT),这些项目都可以在 GitHub 上找到。

既然要开发一个物联网项目,那么说到底什么是物联网?

物联网其实是互联网的一个延伸,互联网的终端是计算机(PC、服务器),我们运行的所有程序,无非都是计算机和网络中的数据处理和数据传输,除了计算机外,没有涉及任何其他的终端(硬件)。

物联网的本质还是互联网,只不过终端不再是计算机(PC、服务器),而是嵌入式计算机系统及其配套的传感器。

这是计算机科技发展的必然结果,为人类服务的计算机呈现出各种形态,如穿戴设备、环境监控设备、虚拟现实设备等等。

只要有硬件或产品连上网,发生数据交互,就叫物联网,万物相连的互联网。

那么 PHP 应该如何去开发物联网应用程序?

最常规的,也是对 PHP 程序员来说最简单的,首先就是后台模块,开发物联网项目的管理系统

这里就用到了 PHP 的 CRUD,开发起来也是很快的,例如:数据管理、报表管理、开关控制、设备管理、充值缴费等等,这些应该对于 PHP 程序员来说应该已经是得心应手了。

都说到这里了,也应该说一下重点了,那就是 PHP 如何进行 MQTT 协议解析来进行设备通讯交互呢?什么是 MQTT 协议?

MQTT 是一种基于发布 / 订阅(publish/subscribe)模式的 "轻量级" 通讯协议。

MQTT 协议是轻量、简单、开放和易于实现的,由于物联网的环境是非常特别的,所以 MQTT 遵循以下设计原则:

  • 发布 / 订阅(Pub/Sub)模式,方便消息在传感器之间传递;
  • 允许用户动态创建主题,零运维成本;
  • 把传输量降到最低以提高传输效率;
  • 把低带宽、高延迟、不稳定的网络等因素考虑在内;

PHP 需要处理 MQTT 协议解析,这就要使用到 Swoole 扩展,它提供了一个选项:open_mqtt_protocol,启用后会解析 MQTT 包头,Worker 进程的 onReceive 事件每次会返回一个完整的 MQTT 数据包。

也可以使用原生 PHP 来自己进行解析包头包体,这里我们就直接基于 Swoole 来使用演示。

同时还会用到 PHP 内置的一些函数,例如:pack/unpackord/chr 以及位运算等

使用 pack/unpack 来封包和解包,使用 ord/chr 来转换 Ascii

在开始分析之前,推荐安装两个应用来方便我们进行测试:

一个是 Wireshark,用来进行网络分析、抓包,这样我们就可以明显的看到 MQTT 客户端发来的数据包;

另外一个是 MQTT 客户端,用来模拟硬件发送数据。

MQTT v3 的协议一共有 14 种报文类型,v5 有 15 种类型,增加了 AUTH 类型。

通过 MQTT 的协议文档我们可以了解到每个数据包的第一个字节就是协议类型,而第二字节则为剩余长度,那么我们就可以通过位运算和 ord 来获取每个包的报文类型和剩余长度

如果剩余长度又是一个变长的编码,没有超过 128 的话,我们还可以这样获取,但是超过以后这样获取到是错误的数据

通过协议文档中的 C 示例代码,就可以转为使用 PHP 编写的代码:

这样我们就能正确获得到 0268435455 之间的剩余长度。

下面接着以第一个数据包类型 CONNECT 来作为说明,毕竟我们必须要先进行连接。

根据协议,在 CONNECT 包中,我们可以获取到以下数据:

  • Protocol Name 协议名称
  • Protocol Level 协议等级
  • Connect Flags 连接标志
  • Keep Alive 保持连接
  • Client ID 客户端 ID
  • Will Topic 遗嘱 topic
  • Will Message 遗嘱消息
  • User Name 用户名
  • Password 密码

在 Connect Flags 包含了一些 Flag 位,用于表示是否设置了用户名密码、遗嘱消息、清除会话、QoS 等级等

我们来试着使用代码来获取一下这些信息,需要注意的是 MQTT 协议为大端序,即高位在前。

协议名称为 4 个字节,协议等级为 1 个字节

Connect Flags 的数据包为 1 个字节,8 个 bit

CONNECT 数据包的有效载荷包含一个或多个带前缀的字段,这些字段的存在由变量头中的标志确定。

这些字段(如果存在)必须按客户端标识符,遗嘱主题,遗嘱消息,用户名,密码的顺序出现。

因为它们都是 utf-8 的字符串,所以我们可以封装一个方法来统一调用,减少了一部分重复代码。

这样我们就完成了一次 CONNECT 数据包的解析,在解析的时候会用到 unpack 和 ord,反之在封包的时候就会用到 pack 和 chr。

和对应的协议文档对应起来,似乎 MQTT 协议并没有那么困难,所以不要有压力,说自己搞不定…

当然你也可以直接使用我写的代码:simps/mqtt ,适用于 PHP 的 MQTT 协议解析和协程客户端,而且还是首个支持 MQTT v5.0 协议的 PHP 库。

支持 MQTT 协议 3.1、3.1.1 和 5.0 版本,支持 QoS 0QoS 1QoS 2

以 CONNECT 数据包为例,证明 PHP 也可以使用 MQTT 协议来和设备通讯,当然不止这一个协议,Modbus 等也可以,并且也有 PHP 的实现库。

在这里也向大家介绍一个能让 PHP 支持嵌入式开发的工具:PHPoC

PHPoC (PHP on Chip):是一个编程语言和一个物联网硬件开发平台。

PHPoC 是基于泛用脚本语言 PHP 开发的可编程语言。

PHPoC 基本与 PHP 兼容,但为了嵌入式系统开发增加了 I/O, UART, I2C, SPI, ADC, TIMER/COUNTER, RTC 等支持硬件接口及硬件控制的新函数及功能。

这样我们就能基于它来编写嵌入式程序,这样就更加丰富了 PHP 的生态能力,感兴趣的可以了解一下。

本文正在参加腾讯云加社区技术创作 101 训练营,阅读 PDF 可以访问【技术创作 101 训练营】PHP 也能开发物联网应用程序

沈唁志 任何个人或团体,未经允许禁止转载本文:《PHP 也能开发物联网应用程序》,谢谢合作!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK