NAC_Blockchain/nac-quantum-browser/ws_server.php

118 lines
3.3 KiB
PHP
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env php
<?php
/**
* NAC 量子浏览器 WebSocket 服务
* 使用 Workerman 实现,监听端口 9553
* 每 3 秒轮询 Explorer API有新区块则广播给所有在线客户端
*
* 启动php ws_server.php start -d
* 停止php ws_server.php stop
* 重启php ws_server.php restart
*/
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use Workerman\Timer;
// Explorer API 地址(服务端调用,不暴露给前端)
define('EXPLORER_API', 'http://127.0.0.1:9551');
// WebSocket 服务,监听 9553 端口
$wsWorker = new Worker('websocket://0.0.0.0:9553');
$wsWorker->count = 1; // 单进程足够
$wsWorker->name = 'nac-quantum-ws';
$wsWorker->user = 'www';
// 记录最新区块高度
$latestBlock = 0;
/**
* 调用 Explorer API
*/
function callApi(string $path): ?array
{
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => EXPLORER_API . $path,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 3,
CURLOPT_CONNECTTIMEOUT => 2,
CURLOPT_HTTPHEADER => ['Accept: application/json'],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($body === false || $status < 200 || $status >= 300) {
return null;
}
$json = json_decode($body, true);
return is_array($json) ? $json : null;
}
$wsWorker->onWorkerStart = function ($worker) use (&$latestBlock) {
// 初始化最新区块高度
$res = callApi('/api/v1/blocks/latest');
if ($res && isset($res['data']['number'])) {
$latestBlock = (int) $res['data']['number'];
}
// 每 3 秒轮询一次
Timer::add(3, function () use ($worker, &$latestBlock) {
$res = callApi('/api/v1/blocks/latest');
if (!$res || !isset($res['data']['number'])) {
return;
}
$newHeight = (int) $res['data']['number'];
if ($newHeight <= $latestBlock) {
return;
}
// 有新区块,广播给所有在线客户端
$latestBlock = $newHeight;
$block = $res['data'];
$payload = json_encode([
'type' => 'new_block',
'block' => [
'number' => $block['number'] ?? 0,
'hash' => $block['hash'] ?? '',
'timestamp' => $block['timestamp'] ?? time(),
'txCount' => $block['txCount'] ?? 0,
'validator' => $block['validator'] ?? '',
'size' => $block['size'] ?? 0,
],
], JSON_UNESCAPED_UNICODE);
foreach ($worker->connections as $conn) {
$conn->send($payload);
}
});
};
$wsWorker->onConnect = function ($conn) {
// 新客户端连接时,发送当前最新区块高度
global $latestBlock;
$conn->send(json_encode([
'type' => 'connected',
'latestBlock' => $latestBlock,
'server' => 'NAC Quantum Browser WebSocket v1.0',
]));
};
$wsWorker->onMessage = function ($conn, $data) {
// 客户端可发送 ping服务端回 pong
if (trim($data) === 'ping') {
$conn->send('pong');
}
};
$wsWorker->onError = function ($conn, $code, $msg) {
// 静默处理连接错误
};
// 启动
Worker::runAll();