- Modified startup script to instantiate GameProcessServer separately
before wrapping in WsServer/HttpServer, allowing direct access to
set event loop after IoServer creation
- Implemented setLoop() method to set event loop after construction
- Added error handling for fwrite() to gracefully handle broken pipes
when process closes
- Suppressed fread() warnings with @ operator to avoid noise
- Simplified startOutputReader() since event loop polling is now
handled directly in onOpen()
- Added null checks for event loop before using in timers
- Server now properly starts with continuous 100ms output polling
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
85 lines
2.5 KiB
PHP
Executable File
85 lines
2.5 KiB
PHP
Executable File
#!/usr/bin/env php
|
||
<?php
|
||
/**
|
||
* 进程转发 WebSocket 服务器启动脚本
|
||
* 使用方法: php websocket-process-server.php
|
||
*
|
||
* 这个服务器为每个连接启动一个独立的 bin/game 进程
|
||
* 将进程的输出实时转发给WebSocket客户端
|
||
* 将客户端输入直接写入进程的STDIN
|
||
*/
|
||
|
||
// 自动加载
|
||
require_once __DIR__ . '/vendor/autoload.php';
|
||
|
||
use Ratchet\Server\IoServer;
|
||
use Ratchet\Http\HttpServer;
|
||
use Ratchet\WebSocket\WsServer;
|
||
use Game\Core\GameProcessServer;
|
||
|
||
// 分步骤创建应用栈,以便能访问 GameProcessServer 实例
|
||
echo "[初始化] 创建 GameProcessServer 实例...\n";
|
||
$gameServer = new GameProcessServer(null);
|
||
|
||
echo "[初始化] 创建 WsServer...\n";
|
||
$wsServer = new WsServer($gameServer);
|
||
|
||
echo "[初始化] 创建 HttpServer...\n";
|
||
$httpServer = new HttpServer($wsServer);
|
||
|
||
// 创建IO服务器(内部创建事件循环)
|
||
echo "[初始化] 创建 IO 服务器...\n";
|
||
$server = IoServer::factory($httpServer, 9002, '0.0.0.0');
|
||
echo "[初始化] IO 服务器创建成功\n";
|
||
|
||
// 现在获取事件循环并设置给 GameProcessServer 实例
|
||
$loop = $server->loop;
|
||
echo "[初始化] 获取事件循环成功\n";
|
||
|
||
$gameServer->setLoop($loop);
|
||
echo "[初始化] 为 GameProcessServer 设置了事件循环\n";
|
||
|
||
echo <<<'ASCII'
|
||
╔══════════════════════════════════════════╗
|
||
║ 凡人修仙传 - 进程转发 WebSocket 服务器 ║
|
||
╚══════════════════════════════════════════╝
|
||
|
||
⚡ WebSocket 服务器启动
|
||
📍 地址: 0.0.0.0:9002
|
||
🔗 客户端连接: ws://localhost:9002
|
||
|
||
📋 运作原理:
|
||
1. 为每个WebSocket连接启动一个 php bin/game 进程
|
||
2. 实时读取进程的STDOUT/STDERR
|
||
3. 通过WebSocket发送给客户端
|
||
4. 客户端输入直接写入进程的STDIN
|
||
|
||
💡 特点:
|
||
✓ 无需修改游戏代码
|
||
✓ 每个用户独立的游戏进程
|
||
✓ 实时输出(100ms轮询)
|
||
✓ 完整的ANSI颜色支持
|
||
✓ 实时交互
|
||
|
||
按 Ctrl+C 停止服务器...
|
||
|
||
ASCII;
|
||
|
||
ob_implicit_flush();
|
||
fflush(STDOUT);
|
||
|
||
echo "\n[启动] 准备启动事件循环...\n";
|
||
fflush(STDOUT);
|
||
|
||
try {
|
||
echo "[启动] 调用 \$loop->run()...\n";
|
||
fflush(STDOUT);
|
||
$loop->run();
|
||
echo "[启动] \$loop->run() 已返回\n";
|
||
} catch (Exception $e) {
|
||
echo "\n[错误] 事件循环异常: " . $e->getMessage() . "\n";
|
||
echo $e->getTraceAsString() . "\n";
|
||
exit(1);
|
||
}
|
||
|