如何在域名/IP部署WebSocket服务器?生产环境连接失败求助
解决Ratchet WebSocket服务器生产环境无法外部连接及代码问题
一、核心问题:服务器仅监听本地回环地址
你的服务器当前仅监听127.0.0.1:6001,这意味着只有服务器本机可以建立连接,外部请求无法穿透到服务。解决方法是修改Ratchet服务器的监听地址为0.0.0.0(监听所有网卡):
原代码:
$server = new Ratchet\App('localhost', 6001);
修改为:
$server = new Ratchet\App('0.0.0.0', 6001);
修改后重启服务器,执行netstat -tulpn | grep 6001检查,监听地址应显示为0.0.0.0:6001,此时外部即可正常访问。
二、代码中的语法错误
代码存在属性访问语法错误:所有$this->$wclient写法错误,类属性访问不需要在属性名前加$,应改为$this->wclient,否则会触发变量解析异常。
错误示例:
$this->$wclient = new WebSocket\Client("wss://stream-testnet.bybit.com/contract/usdt/public/v3", ['timeout' => 3000]); $this->$wclient->text($json);
修正后:
$this->wclient = new WebSocket\Client("wss://stream-testnet.bybit.com/contract/usdt/public/v3", ['timeout' => 3000]); $this->wclient->text($json);
三、Bybit WebSocket连接优化
当前代码在每个客户端onOpen时都创建新的Bybit WebSocket连接,会导致大量重复连接、浪费资源。建议改为类初始化时创建一次共享连接,并处理自动重连逻辑:
class Chat implements MessageComponentInterface { protected $clients; protected $wclient; public function __construct() { $this->clients = new \SplObjectStorage; // 初始化Bybit连接 $this->initBybitConnection(); // 启动异步接收Bybit消息的循环 $this->startBybitMessageLoop(); } private function initBybitConnection() { try { $this->wclient = new WebSocket\Client("wss://stream-testnet.bybit.com/contract/usdt/public/v3", ['timeout' => 3000]); $subscribeJson = '{"req_id": "100001", "op": "subscribe" ,"args": [ "orderbook.1.BTCUSDT", "orderbook.1.ETHUSDT" ]}'; $this->wclient->text($subscribeJson); } catch (\Exception $e) { error_log("Bybit连接失败: " . $e->getMessage()); // 连接失败后延迟重连 sleep(5); $this->initBybitConnection(); } } private function startBybitMessageLoop() { $loop = \React\EventLoop\Loop::get(); $loop->addPeriodicTimer(0.001, function() { try { if ($this->wclient && $message = $this->wclient->receive()) { // 将Bybit推送的消息广播给所有在线客户端 foreach ($this->clients as $client) { $client->send($message); } } } catch (\Exception $e) { error_log("Bybit消息接收失败: " . $e->getMessage()); // 消息接收异常时重新初始化连接 $this->initBybitConnection(); } }); } public function onOpen(ConnectionInterface $conn) { $this->clients->attach($conn); echo "新客户端连接: {$conn->resourceId}\n"; } public function onClose(ConnectionInterface $conn) { $this->clients->detach($conn); echo "客户端断开连接: {$conn->resourceId}\n"; } public function onMessage(ConnectionInterface $from, $data) { // 处理客户端发送的消息(按需实现) echo "收到客户端{$from->resourceId}消息: {$data}\n"; $from->send("已收到消息: {$data}"); } public function onError(ConnectionInterface $conn, \Exception $e) { echo "客户端{$conn->resourceId}错误: {$e->getMessage()}\n"; $conn->close(); } } $server = new Ratchet\App('0.0.0.0', 6001); $server->route('/', new Chat, ['*']); $server->run();
四、验证步骤
- 重启修改后的WebSocket服务器:
php filename.php - 执行
netstat -tulpn | grep 6001确认监听地址为0.0.0.0:6001 - 外部客户端重新尝试连接,验证是否成功
内容的提问来源于stack exchange,提问作者Travis
相关产品推荐
相关产品推荐

