xy 3 nedēļas atpakaļ
vecāks
revīzija
f49a2286e2
1 mainītis faili ar 26 papildinājumiem un 7 dzēšanām
  1. 26 7
      src/WebSocketClient.php

+ 26 - 7
src/WebSocketClient.php

@@ -7,21 +7,24 @@ use MsgID;
 
 require_once __DIR__ . '/../vendor/autoload.php';
 require_once './msg.php';
+
 class WebSocketClient 
 {
     private \WebSocket\Client $socket;
     private array $handlers = [];
     private bool $isRunning = false;
     private int $retryCount = 0;
+    private int $heartbeatInterval = 5; // 心跳间隔(秒)
 
     public function __construct(
         private string $url,
         private array $options = [
             'timeout' => 5,
-            'heartbeat_interval' => 30,
+            'heartbeat_interval' => 5, // 默认5秒
             'max_retries' => 10
         ]
     ) {
+        $this->heartbeatInterval = $this->options['heartbeat_interval'];
         $this->connect();
     }
 
@@ -48,7 +51,7 @@ class WebSocketClient
             $binData = $binMsgId . $data;
             $this->socket->binary($binData);
         } catch (\Exception $e) {
-            // $this->handleDisconnect($e);
+            $this->handleDisconnect($e);
         }
     }
 
@@ -60,24 +63,41 @@ class WebSocketClient
 
         $this->isRunning = true;
 
+        // 启动心跳子进程
+        $this->startHeartbeatProcess();
+
+        // 主进程持续监听消息
         while ($this->isRunning) {
             try {
-                $this->sendHeartbeat();
-                // 接收消息
                 $message = $this->socket->receive();
                 if ($message) {
                     $this->dispatchBinaryMessage($message);
                 }
-                usleep(5); // 5ms 避免CPU过高使用
+                usleep(1000); // 1ms 避免CPU过高使用
             } catch (\WebSocket\ConnectionException $e) {
                 error_log("ConnectionException 错误: " . $e->getMessage());
-                // $this->handleDisconnect($e);
+                $this->handleDisconnect($e);
             } catch (\Exception $e) {
                 error_log("Exception 错误: " . $e->getMessage());
             }
         }
     }
 
+    private function startHeartbeatProcess(): void
+    {
+        $pid = pcntl_fork();
+        if ($pid == -1) {
+            throw new \RuntimeException("无法创建心跳子进程");
+        } elseif ($pid == 0) {
+            // 子进程:定时发送心跳
+            while ($this->isRunning) {
+                $this->sendHeartbeat();
+                sleep($this->heartbeatInterval);
+            }
+            exit(0); // 子进程退出
+        }
+    }
+
     private function dispatchBinaryMessage(string $binary): void 
     {
         if (strlen($binary) < 2) {
@@ -104,7 +124,6 @@ class WebSocketClient
             $hearbeat = new ReqHeartBeat();
             $hearbeat->setMsg("ping");
             $binaryData = $hearbeat->serializeToString();
-            // 这里假设心跳消息ID为1,根据实际协议调整
             $this->sendBinary(MsgID::REQHEARTBEAT, $binaryData);
         } catch (\Exception $e) {
             error_log("心跳发送失败: " . $e->getMessage());