PHP项目物联网网关如何对接PHP服务

wen PHP项目 29

本文目录导读:

PHP项目物联网网关如何对接PHP服务

  1. 整体架构设计
  2. 核心对接方案
  3. 数据协议设计
  4. 数据缓存与队列
  5. 安全性设计
  6. 监控与日志
  7. 配置管理
  8. 最佳实践建议

我来详细说明PHP项目物联网网关对接PHP服务的方法和架构设计。

整体架构设计

传感器/设备 → 物联网网关(PHP) → PHP服务端
     ↓              ↓               ↓
  MQTT/CoAP    协议转换     数据处理/存储
  HTTP/TCP    数据缓存      业务逻辑处理
  Modbus      安全认证      设备管理

核心对接方案

1 MQTT协议对接

<?php
// 使用phpMQTT库
require("phpMQTT.php");
class IoTGateway {
    private $mqtt;
    private $server;
    public function __construct() {
        $this->server = 'mqtt://broker-host:1883';
        $this->mqtt = new Bluerhinos\phpMQTT($this->server, "gateway-".uniqid());
    }
    // 连接MQTT Broker
    public function connect() {
        $this->mqtt->connect(true, NULL, "username", "password");
    }
    // 订阅设备主题
    public function subscribeDevice($deviceId) {
        $topic = "devices/{$deviceId}/data";
        $this->mqtt->subscribe($topic, function($topic, $msg) {
            $this->processDeviceData($deviceId, json_decode($msg, true));
        });
    }
    // 发布指令到设备
    public function sendCommand($deviceId, $command) {
        $topic = "devices/{$deviceId}/command";
        $this->mqtt->publish($topic, json_encode($command), 1);
    }
    // 处理设备上传数据
    private function processDeviceData($deviceId, $data) {
        // 数据验证
        if (!$this->validateData($data)) {
            return;
        }
        // 数据转换
        $transformedData = $this->transformData($data);
        // 发送到PHP服务端
        $this->sendToService($transformedData);
    }
}
?>

2 RESTful API对接

<?php
class DeviceAPI {
    private $baseUrl;
    private $apiKey;
    public function __construct() {
        $this->baseUrl = "http://your-php-server.com/api";
        $this->apiKey = "your-api-key";
    }
    // 设备数据上报
    public function reportDeviceData($deviceId, $data) {
        $ch = curl_init("{$this->baseUrl}/device/{$deviceId}/data");
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'X-API-Key: ' . $this->apiKey,
            'X-Timestamp: ' . time()
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        return [
            'code' => $httpCode,
            'data' => json_decode($response, true)
        ];
    }
    // 获取设备配置
    public function getDeviceConfig($deviceId) {
        $ch = curl_init("{$this->baseUrl}/device/{$deviceId}/config");
        curl_setopt($ch, CURLOPT_HTTPGET, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'X-API-Key: ' . $this->apiKey
        ]);
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response, true);
    }
}
?>

3 WebSocket实时对接

<?php
// 使用Ratchet WebSocket
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class IoTWebSocket implements MessageComponentInterface {
    protected $clients;
    protected $deviceMap;
    public function __construct() {
        $this->clients = new \SplObjectStorage;
        $this->deviceMap = [];
    }
    public function onOpen(ConnectionInterface $conn) {
        $this->clients->attach($conn);
        echo "New connection: {$conn->resourceId}\n";
    }
    public function onMessage(ConnectionInterface $from, $msg) {
        $data = json_decode($msg, true);
        switch ($data['type']) {
            case 'device_auth':
                $this->handleDeviceAuth($from, $data);
                break;
            case 'device_data':
                $this->handleDeviceData($from, $data);
                break;
            case 'heartbeat':
                $this->handleHeartbeat($from);
                break;
        }
    }
    // 处理设备认证
    private function handleDeviceAuth($conn, $data) {
        $deviceId = $data['device_id'];
        $token = $data['token'];
        // 验证设备身份
        if ($this->validateDevice($deviceId, $token)) {
            $this->deviceMap[$conn->resourceId] = $deviceId;
            $conn->send(json_encode([
                'type' => 'auth_response',
                'status' => 'success'
            ]));
        }
    }
    // 处理设备数据
    private function handleDeviceData($conn, $data) {
        $deviceId = $this->deviceMap[$conn->resourceId] ?? null;
        if (!$deviceId) return;
        $payload = [
            'device_id' => $deviceId,
            'timestamp' => time(),
            'data' => $data['payload']
        ];
        // 发送到PHP服务端处理
        $this->sendToService($payload);
    }
    public function onClose(ConnectionInterface $conn) {
        $this->clients->detach($conn);
        unset($this->deviceMap[$conn->resourceId]);
    }
    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "Error: {$e->getMessage()}\n";
        $conn->close();
    }
}
?>

数据协议设计

1 统一数据格式

<?php
class DataProtocol {
    // 设备上报数据格式
    const DATA_FORMAT = [
        'header' => [
            'version' => '1.0',
            'message_id' => 'string',
            'timestamp' => 'int',
            'device_id' => 'string'
        ],
        'body' => [
            'type' => 'string', // sensor/status/event
            'payload' => 'array'
        ],
        'signature' => 'string'
    ];
    // 数据封装
    public static function encode($deviceId, $type, $payload) {
        $message = [
            'header' => [
                'version' => '1.0',
                'message_id' => uniqid(),
                'timestamp' => time(),
                'device_id' => $deviceId
            ],
            'body' => [
                'type' => $type,
                'payload' => $payload
            ],
            'signature' => ''
        ];
        // 生成签名
        $message['signature'] = self::generateSignature($message);
        return $message;
    }
    // 生成签名
    private static function generateSignature($data) {
        $secretKey = 'your-secret-key';
        $stringToSign = json_encode($data['header']) . json_encode($data['body']);
        return hash_hmac('sha256', $stringToSign, $secretKey);
    }
    // 验证签名
    public static function verifySignature($data) {
        $expectedSignature = self::generateSignature($data);
        return hash_equals($expectedSignature, $data['signature']);
    }
}
?>

2 协议适配器

<?php
interface ProtocolAdapter {
    public function decode($rawData);
    public function encode($data);
    public function validate($data);
}
class MQTTAdapter implements ProtocolAdapter {
    public function decode($rawData) {
        $data = json_decode($rawData, true);
        // MQTT特定处理
        return $data;
    }
    public function encode($data) {
        return json_encode($data);
    }
    public function validate($data) {
        return isset($data['device_id']) && isset($data['payload']);
    }
}
class ModbusAdapter implements ProtocolAdapter {
    public function decode($rawData) {
        // Modbus协议解析
        $values = [];
        // 解析Modbus帧
        return $values;
    }
    public function encode($data) {
        // 编码为Modbus帧
        return $data;
    }
    public function validate($data) {
        return true;
    }
}
?>

数据缓存与队列

<?php
class DataQueue {
    private $redis;
    public function __construct() {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', 6379);
    }
    // 数据入队
    public function pushData($deviceId, $data) {
        $key = "device:data:{$deviceId}";
        $this->redis->lPush($key, json_encode($data));
        // 限制队列长度
        $this->redis->lTrim($key, 0, 999);
    }
    // 批量获取数据
    public function getBatchData($deviceId, $count = 100) {
        $key = "device:data:{$deviceId}";
        $data = $this->redis->lRange($key, 0, $count - 1);
        $this->redis->lTrim($key, $count, -1);
        return array_map(function($item) {
            return json_decode($item, true);
        }, $data);
    }
    // 数据批量提交到服务端
    public function batchSubmit() {
        $devices = $this->redis->keys("device:data:*");
        foreach ($devices as $key) {
            $deviceId = str_replace("device:data:", "", $key);
            $batchData = $this->getBatchData($deviceId);
            if (!empty($batchData)) {
                $this->submitToService($deviceId, $batchData);
            }
        }
    }
}
?>

安全性设计

<?php
class SecurityManager {
    private $tokenStore;
    // 设备认证
    public function authenticateDevice($deviceId, $credentials) {
        // JWT令牌验证
        $token = $credentials['token'] ?? '';
        try {
            $payload = JWT::decode($token, new Key($this->getSecretKey(), 'HS256'));
            return $payload->device_id === $deviceId;
        } catch (\Exception $e) {
            return false;
        }
    }
    // 生成设备令牌
    public function generateDeviceToken($deviceId) {
        $payload = [
            'device_id' => $deviceId,
            'iat' => time(),
            'exp' => time() + 86400 * 30 // 30天有效期
        ];
        return JWT::encode($payload, $this->getSecretKey(), 'HS256');
    }
    // 数据加密
    public function encryptData($data, $deviceId) {
        $key = $this->getDeviceKey($deviceId);
        $iv = openssl_random_pseudo_bytes(16);
        $encrypted = openssl_encrypt(
            json_encode($data),
            'AES-256-CBC',
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );
        return base64_encode($iv . $encrypted);
    }
    // 数据解密
    public function decryptData($encryptedData, $deviceId) {
        $data = base64_decode($encryptedData);
        $iv = substr($data, 0, 16);
        $encrypted = substr($data, 16);
        $key = $this->getDeviceKey($deviceId);
        return openssl_decrypt(
            $encrypted,
            'AES-256-CBC',
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );
    }
}
?>

监控与日志

<?php
class GatewayMonitor {
    private $logger;
    private $metrics;
    public function __construct() {
        $this->logger = new \Monolog\Logger('iot-gateway');
        $this->logger->pushHandler(new \Monolog\Handler\StreamHandler('gateway.log'));
        $this->metrics = new \Prometheus\CollectorRegistry(new \Prometheus\Storage\InMemory());
    }
    // 记录设备连接状态
    public function deviceConnection($deviceId, $status) {
        $this->logger->info("Device {$deviceId} connection: {$status}");
        // Prometheus指标
        $gauge = $this->metrics->getOrRegisterGauge('iot', 'device_connections', 'Device connections');
        $gauge->set($status === 'online' ? 1 : 0, ['device_id' => $deviceId]);
    }
    // 记录数据处理延迟
    public function recordLatency($deviceId, $processingTime) {
        $histogram = $this->metrics->getOrRegisterHistogram(
            'iot',
            'data_processing_seconds',
            'Data processing time',
            ['device_id'],
            [0.001, 0.01, 0.1, 0.5, 1, 5]
        );
        $histogram->observe($processingTime, ['device_id' => $deviceId]);
    }
    // 错误报警
    public function alertError($deviceId, $errorType, $message) {
        $this->logger->error("Device {$deviceId}: {$errorType} - {$message}");
        // 发送报警通知
        $this->sendAlert($deviceId, $errorType, $message);
    }
}
?>

配置管理

<?php
return [
    'gateway' => [
        'name' => 'IoT Gateway',
        'version' => '2.0.0',
        'max_connections' => 10000,
        'heartbeat_interval' => 30, // 秒
    ],
    'protocols' => [
        'mqtt' => [
            'host' => 'localhost',
            'port' => 1883,
            'ssl_port' => 8883,
            'keepalive' => 60,
            'clean_session' => true
        ],
        'websocket' => [
            'port' => 8080,
            'ssl_port' => 8443,
            'max_buffer_size' => 8192
        ]
    ],
    'service' => [
        'php_server' => [
            'base_url' => 'http://localhost:8000',
            'api_key' => 'your-api-key',
            'timeout' => 30,
            'retry_times' => 3
        ],
        'data_processing' => [
            'batch_size' => 100,
            'cache_timeout' => 300,
            'queue_type' => 'redis'
        ]
    ],
    'security' => [
        'jwt_secret' => 'your-jwt-secret',
        'token_expiry' => 86400,
        'rate_limit' => [
            'requests_per_second' => 100,
            'burst_size' => 200
        ]
    ]
];
?>

最佳实践建议

  1. 异步处理:使用消息队列(RabbitMQ/Kafka)解耦数据接收和处理
  2. 连接池:使用连接池管理数据库和外部服务连接
  3. 限流保护:实现令牌桶算法限制设备数据上报频率
  4. 数据压缩:对大数据量传输使用gzip压缩
  5. 断线重连:实现指数退避的重连策略
  6. 日志分级:使用结构化日志便于问题追踪
  7. 水平扩展:网关设计支持无状态水平扩展

这个架构设计提供了完整的物联网网关对接方案,可以根据实际需求选择适合的协议和组件。

抱歉,评论功能暂时关闭!