在物联网(IoT)和智能充电桩领域,设备与云端平台保持稳定、双向的实时通信是核心需求。本文将深入探讨如何使用 PHP 配合 Workerman 框架,建立一个可靠的 TCP 长连接客户端,以对接云快充(CQRC)系统。

图示:系统对接流程示意图标
核心流程与类结构
我们通过一个核心事件处理类 CqrcEvent 来管理整个连接生命周期。它需要依赖 Redis 进行状态管理和消息订阅,并围绕设备编号(device_no)展开所有操作。
连接建立与认证 (onConnect)
当TCP连接建立时,系统首先会执行 onConnect 方法,完成设备身份的校验与初始化登录。
- 设备校验:根据
device_no 从数据库中查询设备信息。若设备不存在或不属于当前系统(cec_id=0),则从模拟设备列表中移除并关闭连接。
- 信息补全:检查并确保设备档案(
DeviceProfile)中存在唯一的ICCID(集成电路卡识别码),若不存在则随机生成一个并保存。
- 发送登录包:构造并发送协议规定的登录认证数据包(
PACKAGE_01)。包体包含了设备号、类型、回路数、版本号及ICCID等关键信息。
- 启动心跳与状态同步:设置一个定时器,周期性(例如每10秒)向服务器上报各充电接口(
DeviceLoop)的当前状态(PACKAGE_03),以维持连接活性并同步状态。
消息处理与业务分发 (onMessage)
服务器下发的所有指令和数据都通过 onMessage 方法接收。这里采用策略模式,根据不同的数据包类型(package_type)分发到对应的业务逻辑处理器。
<?php
namespace cgcore\gateways;
use app\admin\model\device\Device;
use app\admin\model\device\DeviceLoop;
use app\admin\model\device\DeviceProfile;
use cgcore\enums\CacheKeyEnum;
use cgcore\enums\CqrsEnum;
use cgcore\enums\DeviceStateEnum;
use cgcore\logics\CqrcGatewayLogic;
use Workerman\Timer;
use Workerman\Connection\TcpConnection;
//云快充客户端
class CqrcEvent
{
private $myRedis;
private $device_no;
public function __construct($myRedis, $device_no)
{
$this->myRedis = $myRedis;
$this->device_no = $device_no;
}
public function onMessage(TcpConnection $connection, $message)
{
$logic = new CqrcGatewayLogic($connection, $message);
extract($message, EXTR_PREFIX_ALL, 'pre');
switch (strtoupper($pre_package_type)) {
case CqrsEnum::PACKAGE_02:
$logic->loginAuthReply(); // 登录认证回复
break;
case CqrsEnum::PACKAGE_06:
$logic->rechargeModelCheckReply(); // 充电模式检查回复
break;
case CqrsEnum::PACKAGE_0A:
$logic->rechargeModelReply(); // 充电模式回复
break;
case CqrsEnum::PACKAGE_12:
$logic->realtime(); // 实时数据上报
break;
case CqrsEnum::PACKAGE_34:
$logic->openCharge(); // 开启充电
break;
case CqrsEnum::PACKAGE_36:
$logic->closeCharge(); // 关闭充电
break;
case CqrsEnum::PACKAGE_40:
$logic->closeOrderReply(); // 结束订单回复
break;
case CqrsEnum::PACKAGE_56:
$logic->synctime(); // 时间同步
break;
case CqrsEnum::PACKAGE_58:
$logic->updateChargeModel(); // 更新充电模式
break;
case CqrsEnum::PACKAGE_92:
$logic->restart(); // 设备重启
break;
case CqrsEnum::PACKAGE_F0:
$logic->qrcode(); // 二维码相关
break;
}
}
}
在大型PHP项目中,合理的依赖管理与 Composer 应用是保持代码清晰的基础。此处的 CqrcGatewayLogic 类封装了所有具体的协议解析与响应逻辑,使主事件类保持精简。
连接关闭与异常处理 (onClose / onError)
连接断开或发生错误时,必须进行严谨的清理工作,以确保系统状态一致性和资源释放。
- 清理连接与订阅:从全局连接池中移除当前设备连接,并取消对应的Redis频道订阅,避免消息堆积。
- 释放定时器资源:清除为该连接设置的所有定时器(如心跳定时器、实时数据上报定时器),防止内存泄漏。
- 更新设备状态:将数据库中该设备的状态标记为离线(
device_offline),并记录离线时间。这对于设备监控和运维至关重要。
关键技术点与优化建议
- 长连接保活:除了示例中的定时状态上报,还可以实现应用层的心包/乒乓包机制,并合理配置TCP层的Keep-Alive参数。
- 异步处理:对于耗时的业务操作(如订单处理、数据持久化),应避免在消息回调中同步执行,可以将其投递到异步任务队列(如Redis List),由后台进程处理,确保网络IO的及时响应。
- 状态同步:设备状态在连接中通过Redis进行管理,连接断开时的状态回写数据库操作需要保证幂等性,防止重复更新。可以利用 Redis 的原子操作和发布订阅功能来实现更优雅的分布式状态同步。

图示:连接生命周期管理示意
总结
对接云快充系统的核心在于实现一个健壮、可维护的TCP长连接客户端。通过 CqrcEvent 类清晰地划分连接生命周期各阶段的职责,并结合具体的业务逻辑处理器,能够高效、稳定地处理充电桩与平台间的各种交互指令。在实际开发中,还需重点关注连接的可靠性、异常恢复机制以及业务数据的准确性与一致性。
|