chore: 删除多个客户端模块

移除以下未完成的客户端模块:
- C++ 客户端和 demo
- .NET 客户端和 demo
- Kotlin 客户端和 demo
- Lua 客户端和 demo
- PHP 客户端和 demo
- Ruby 客户端和 demo
- Rust 客户端和 demo

更新根目录 README.md,移除相关说明。
This commit is contained in:
2026-04-25 21:05:00 +08:00
parent 7efca9440a
commit b4b38fa0c7
36 changed files with 27 additions and 2278 deletions
-30
View File
@@ -1,30 +0,0 @@
<?php
namespace KenaitoConf;
class Cache
{
private string $cacheDir;
private const CACHE_FILE = 'config-cache.json';
public function __construct(string $cacheDir = '.')
{
$this->cacheDir = $cacheDir;
}
public function write(array $data): void
{
$path = $this->cacheDir . DIRECTORY_SEPARATOR . self::CACHE_FILE;
file_put_contents($path, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
}
public function read(): ?array
{
$path = $this->cacheDir . DIRECTORY_SEPARATOR . self::CACHE_FILE;
if (!file_exists($path)) {
return null;
}
$content = file_get_contents($path);
return json_decode($content, true);
}
}
-24
View File
@@ -1,24 +0,0 @@
<?php
namespace KenaitoConf;
class Config
{
public string $baseUrl = '';
public string $appName = '';
public string $env = 'dev';
public string $version = 'latest';
public string $token = '';
public int $syncInterval = 60;
public bool $ignoreGlobal = false;
public string $cacheDir = '.';
public function __construct(array $options = [])
{
foreach ($options as $key => $value) {
if (property_exists($this, $key)) {
$this->$key = $value;
}
}
}
}
@@ -1,179 +0,0 @@
<?php
namespace KenaitoConf;
class ConfigClient
{
private Config $config;
private Cache $cache;
private array $configs = [];
private int $lastTime = 0;
private bool $started = false;
private array $handlers = [];
private $timer = null;
public function __construct(Config $config)
{
$this->config = $config;
$this->cache = new Cache($config->cacheDir);
}
public function onChange(callable $handler): void
{
$this->handlers[] = $handler;
}
public function get(string $key): ?string
{
return $this->configs[$key] ?? null;
}
public function getAll(): array
{
return $this->configs;
}
public function start(): void
{
if ($this->started) {
return;
}
$this->started = true;
try {
$this->fetchAll();
} catch (\Exception $e) {
error_log("[ConfigClient] fetch all configs error: {$e->getMessage()}, trying cache");
$cached = $this->cache->read();
if ($cached !== null) {
$this->applyConfigs($cached);
error_log("[ConfigClient] loaded " . count($this->configs) . " configs from cache");
} else {
throw new \RuntimeException("fetch configs failed and no cache: {$e->getMessage()}");
}
}
$this->timer = pcntl_alarm(0);
pcntl_signal(SIGALRM, [$this, 'syncTick']);
pcntl_alarm($this->config->syncInterval);
}
public function syncTick(): void
{
try {
$this->fetchChanged();
} catch (\Exception $e) {
error_log("[ConfigClient] sync error: {$e->getMessage()}");
}
pcntl_alarm($this->config->syncInterval);
}
public function stop(): void
{
if ($this->timer !== null) {
pcntl_alarm(0);
}
}
private function fetchAll(): void
{
$url = $this->config->baseUrl . '/api/fetchAllConfigs';
$payload = [
'appName' => $this->config->appName,
'env' => $this->config->env,
'version' => $this->config->version,
'ignoreGlobal' => $this->config->ignoreGlobal,
'token' => $this->config->token,
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new \RuntimeException("HTTP {$httpCode}");
}
$data = json_decode($response, true);
if (isset($data['code']) && $data['code'] !== 0) {
throw new \RuntimeException("server error: " . ($data['msg'] ?? 'unknown'));
}
if (isset($data['latest.fetch.timestamp'])) {
$this->lastTime = (int)$data['latest.fetch.timestamp'];
}
$this->cache->write($data);
$this->applyConfigs($data);
error_log("[ConfigClient] fetched " . count($this->configs) . " configs");
}
private function fetchChanged(): void
{
$url = $this->config->baseUrl . '/api/fetchChangedConfigs';
$payload = [
'appName' => $this->config->appName,
'env' => $this->config->env,
'version' => $this->config->version,
'lastTime' => $this->lastTime,
'ignoreGlobal' => $this->config->ignoreGlobal,
'token' => $this->config->token,
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
if (!isset($result['code']) || $result['code'] !== 0) {
throw new \RuntimeException("server error code: " . ($result['code'] ?? 'unknown'));
}
$changedData = $result['data'] ?? [];
if (isset($changedData['latest.fetch.timestamp'])) {
$this->lastTime = (int)$changedData['latest.fetch.timestamp'];
unset($changedData['latest.fetch.timestamp']);
}
$changed = [];
foreach ($changedData as $k => $v) {
$changed[$k] = $v;
}
$this->configs = array_merge($this->configs, $changed);
foreach ($this->handlers as $handler) {
try {
$handler($changed);
} catch (\Exception $e) {
error_log("[ConfigClient] change handler error: {$e->getMessage()}");
}
}
error_log("[ConfigClient] " . count($changed) . " configs changed");
}
private function applyConfigs(array $data): void
{
foreach ($data as $k => $v) {
if (str_starts_with($k, 'kenaito.') || $k === 'latest.fetch.timestamp') {
continue;
}
if (!is_string($v)) {
continue;
}
$this->configs[$k] = $v;
}
}
}