creatcode / iotmonitor
用于IoT 协议拆包与数据库、Redis 连接管理组件的小工具
Requires
- php: >=7.2
- ext-redis: *
- workerman/workerman: ^4.0 || ^5.0
Suggests
- ext-event: 用于提升 Workerman 生产环境的事件处理性能。
README
面向 Workerman 常驻进程的 IoT 基础组件,统一处理协议拆包以及数据库、Redis 连接的探活和断线重连。
安装
composer require creatcode/iotmonitor
Webman 快速接入
在 Bootstrap 的 start() 中初始化。Webman 会在每个 Worker 进程启动后执行该方法:
use CreatCode\IotMonitor\Bridge\WebmanInitializer; WebmanInitializer::initialize();
需要自定义配置时,将包内 config/default.php 复制到项目配置目录后传入:
$configuration = require '/项目配置目录/iotmonitor.php'; WebmanInitializer::initialize($configuration, static function (string $message): void { error_log($message); });
配置和日志回调均可省略。不要直接修改 vendor 内的默认配置,Composer 更新会覆盖这些改动。
配置约定
config/default.php 同时是运行时默认配置和项目配置模板,包含以下配置:
database_ping_interval:数据库探活间隔,默认 30 秒。redis_ping_interval:Redis 探活间隔,默认 15 秒。protocol.rtu_crc_check:是否校验 Modbus RTU CRC。protocol.extra_packets:特殊包标识与完整包长。
顶层配置覆盖默认值,protocol 按配置项合并;一旦传入 extra_packets,会整体替换默认特殊包配置。
其它内置框架接入
ThinkPHP
在服务提供者的 boot() 中初始化:
use CreatCode\IotMonitor\Bridge\ThinkPHPInitializer; ThinkPHPInitializer::initialize($configuration ?? []);
初始化器兼容 think\facade 和旧版静态入口。第二个参数可传入自定义 Redis 连接工厂,第三个参数为日志回调。
Laravel
在 AppServiceProvider::boot() 中初始化:
use CreatCode\IotMonitor\Bridge\LaravelInitializer; LaravelInitializer::initialize($configuration ?? []);
第二个参数为日志回调。
自定义框架或连接器接入
没有内置初始化器时,无需编写适配器类。只需在每个工作进程启动后提供数据库和 Redis 连接工厂:
use CreatCode\IotMonitor\IotMonitor; IotMonitor::initialize( static function (bool $forceReconnect) { if ($forceReconnect) { // 清理框架缓存的旧数据库连接。 } return /* 数据库连接 */; }, static function (bool $forceReconnect) { if ($forceReconnect) { // 断开或重置框架缓存的旧 Redis 连接。 } return /* Redis 连接 */; }, $configuration ?? [], $logger ?? null );
统一约定如下:
$forceReconnect由组件传入,接入方不需要调用或维护。false表示正常获取连接,可以返回框架复用的连接。true表示原连接异常或进程发生 fork,必须返回新连接,或者重置底层连接后再返回。- 连接工厂只负责返回连接,不处理缓存、探活、重试和日志。
- 配置和日志回调均可省略,日志回调签名为
function (string $message): void。
组件默认通过数据库的 query() 或 select()、Redis 的 ping() 或 command('ping') 探活,并通过 close() 或 disconnect() 释放连接。
如果客户端不支持这些方法,只需补充探活和释放回调:
use CreatCode\IotMonitor\ConnectionProviderFactory; $databaseProvider = ConnectionProviderFactory::createDatabase( $databaseConnectionFactory, $databaseHealthCheck, $databaseDisconnect ); $redisProvider = ConnectionProviderFactory::createRedis( $redisConnectionFactory, $redisHealthCheck, $redisDisconnect ); IotMonitor::initializeWithProviders($databaseProvider, $redisProvider);
探活回调在连接不可用时应抛出异常,释放回调只负责关闭底层资源。组件会统一缓存、淘汰和重连。只有回调无法描述连接行为时,才需要实现 ConnectionProviderInterface;接口仅包含 getConnection()、ping() 和 disconnect()。
若需要为某个框架提供可复用适配器,只需将上述初始化代码封装到框架的 Worker 启动生命周期中,不需要继承包内类。适配器负责取得框架连接,连接生命周期仍由组件管理。
常驻进程生命周期
- 每个工作进程启动后调用一次框架初始化器或
IotMonitor::initialize()。 - 工作进程停止时可调用
IotMonitor::shutdown()主动释放连接。 - 不要在主进程 fork 前创建连接;组件也会通过 PID 检查阻止子进程复用父进程连接。
- 如需主动心跳,由宿主定时器调用
IotMonitor::healthCheck(),返回['database' => bool, 'redis' => bool]。
使用连接
初始化后无需重复注入连接:
$devices = \CreatCode\IotMonitor\DbManager::read(function ($db) { return $db->name('device')->select(); }); $value = \CreatCode\IotMonitor\RedisManager::read(function ($redis) { return $redis->get('key'); });
read() 用于可安全重试的只读操作,连接异常时最多重试一次。数据库写操作使用 DbManager::call(),Redis 写操作使用 RedisManager::call(),默认不重放业务回调。允许降级的辅助任务可使用 DbManager::safeRead()、DbManager::safeCall()、RedisManager::safeRead() 或 RedisManager::safeWrite()。
协议
内置 ModbusTcpProtocol、ModbusRtuProtocol、LoRaProtocol 和 TemperatureProtocol。初始化组件时会自动应用协议配置;仅使用协议模块时可调用 BaseProtocol::configure() 单独配置。
自定义协议需继承 BaseProtocol,实现 input()、decodePayload(),并声明非空的 PROTOCOL_NAME 常量。
许可证
MIT