initialize(); use Workerman\Worker; use Workerman\Connection\TcpConnection; // 日志目录 define('LOG_PATH', __DIR__ . '/runtime/logs/workerman/'); if (!is_dir(LOG_PATH)) { mkdir(LOG_PATH, 0755, true); } // ========== SSL 证书配置(WSS 必须) ========== // 宝塔证书默认文件名:fullchain.pem(证书)、privkey.pem(私钥) //$ssl_cert_path = '/www/wwwroot/api.myjie.cn/config/ssl/fullchain.pem'; // 证书文件 //$ssl_key_path = '/www/wwwroot/api.myjie.cn/config/ssl/privkey.pem'; // 私钥文件 $ssl_cert_path = '/www/server/panel/vhost/ssl/api.myjie.cn/fullchain.pem'; // 证书文件 $ssl_key_path = '/www/server/panel/vhost/ssl/api.myjie.cn/privkey.pem'; // 私钥文件 $context = []; if (file_exists($ssl_cert_path) && file_exists($ssl_key_path)) { $context = [ 'ssl' => [ 'local_cert' => $ssl_cert_path, 'local_pk' => $ssl_key_path, 'verify_peer' => false, ] ]; } // ============================================== // 创建 WebSocket 服务(带 SSL 上下文) $ws_worker = new Worker('websocket://0.0.0.0:2345', $context); // 启用 SSL 传输层(使 websocket:// 升级为 wss://) if (!empty($context)) { $ws_worker->transport = 'ssl'; } // 设置进程名称 $ws_worker->name = 'ChatWebSocket'; // 设置进程数 $ws_worker->count = 4; // 设置心跳(60秒无响应则断开) $ws_worker->pingInterval = 60; $ws_worker->pingNotResponseLimit = 1; // 当进程启动时 $ws_worker->onWorkerStart = function($worker) { echo "[Worker #{$worker->id}] started\n"; // 初始化 ChatService $chatService = new \app\services\workerman\chat\ChatService($worker); $worker->chatService = $chatService; }; // 当客户端连接时 $ws_worker->onConnect = function(TcpConnection $connection) { $addr = $connection->getRemoteAddress(); echo "[Connect] {$addr}\n"; }; // WebSocket 握手回调 - 解析 URL 查询参数(包括 to_uid)并自动登录 $ws_worker->onWebSocketConnect = function(TcpConnection $connection) use ($ws_worker) { // 从 URL 查询字符串解析参数 // 例如: wss://api.myjie.cn:2345?type=user&token=xxx&from=3&to_uid=456 $query = $_GET ?? []; $connection->type = $query['type'] ?? 'user'; $connection->token = $query['token'] ?? ''; $connection->form_type = $query['form_type'] ?? 3; $connection->to_uid = isset($query['to_uid']) ? intval($query['to_uid']) : 0; // 聊天对象UID // 自动登录:通过 token 验证用户 if ($connection->token) { $userInfo = \app\model\api\User::where('token', $connection->token)->find(); if ($userInfo) { $connection->user = (object)$userInfo->toArray(); $connection->chatToUid = $connection->to_uid; $ws_worker->chatService->setUser($connection); } } echo "[WebSocket Connect] type={$connection->type}, uid={$connection->user->uid ?? 0}, to_uid={$connection->to_uid}\n"; }; // 当收到客户端消息时 $ws_worker->onMessage = function(TcpConnection $connection, $data) use (&$chatService) { $chatService->onMessage($connection, $data); }; // 当客户端断开连接时 $ws_worker->onClose = function(TcpConnection $connection) use (&$chatService) { $chatService->onClose($connection); }; // 当连接出错时 $ws_worker->onError = function(TcpConnection $connection, $code, $msg) { echo "[Error] {$code}: {$msg}\n"; }; // 输出启动信息 $ssl_ok = !empty($context); echo "\n"; echo "========================================\n"; echo " Chat WebSocket Server (WSS)\n"; echo " Address: " . ($ssl_ok ? "wss" : "ws") . "://0.0.0.0:2345\n"; if (!$ssl_ok) { echo " [警告] SSL 证书未配置,运行在 ws 模式\n"; echo " 请将证书放到 config/ssl/cert.pem 和 config/ssl/key.pem\n"; } echo " PID: " . getmypid() . "\n"; echo "========================================\n\n"; // 运行 Worker::runAll();