diff --git a/README.md b/README.md
index 2929e98..9c05bdb 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
- **后端**: Go + Gin + xorm + MySQL
- **前端**: Vue 2 + Vite 5 + Element UI 2
-- **客户端**: Go / Java(Spring Boot 2.x & 3.x)/ Python / Node.js
+- **客户端**: Go / Java(Spring Boot 2.x & 3.x)/ Python / Node.js / PHP / .NET / C / C++ / Lua / Kotlin / Rust / Ruby
## 项目结构
@@ -23,7 +23,23 @@ kenaito-conf/
├── kenaito-conf-python-client/ # Python 客户端 SDK(Python 3.10+)
├── kenaito-conf-python-client-demo/ # Python 客户端示例(端口 8082)
├── kenaito-conf-nodejs-client/ # Node.js 客户端 SDK(Node.js 18+)
-└── kenaito-conf-nodejs-client-demo/ # Node.js 客户端示例(端口 8083)
+├── kenaito-conf-nodejs-client-demo/ # Node.js 客户端示例(端口 8083)
+├── kenaito-conf-php-client/ # (待测试)PHP 客户端 SDK(PHP 8.0+)
+├── kenaito-conf-php-client-demo/ # (待测试)PHP 客户端示例
+├── kenaito-conf-dotnet-client/ # (待测试).NET 客户端 SDK(.NET 6.0+)
+├── kenaito-conf-dotnet-client-demo/ # (待测试).NET 客户端示例
+├── kenaito-conf-c-client/ # (待测试)C 客户端 SDK(libcurl + OpenSSL)
+├── kenaito-conf-c-client-demo/ # (待测试)C 客户端示例
+├── kenaito-conf-cpp-client/ # (待测试)C++ 客户端 SDK(libcurl + OpenSSL)
+├── kenaito-conf-cpp-client-demo/ # (待测试)C++ 客户端示例
+├── kenaito-conf-lua-client/ # (待测试)Lua 客户端 SDK(Lua 5.3+)
+├── kenaito-conf-lua-client-demo/ # (待测试)Lua 客户端示例
+├── kenaito-conf-kotlin-client/ # (待测试)Kotlin 客户端 SDK(Kotlin 1.9+)
+├── kenaito-conf-kotlin-client-demo/ # (待测试)Kotlin 客户端示例
+├── kenaito-conf-rust-client/ # (待测试)Rust 客户端 SDK(Rust 1.70+)
+├── kenaito-conf-rust-client-demo/ # (待测试)Rust 客户端示例
+├── kenaito-conf-ruby-client/ # (待测试)Ruby 客户端 SDK(Ruby 2.7+)
+└── kenaito-conf-ruby-client-demo/ # (待测试)Ruby 客户端示例
```
## 快速开始
@@ -257,6 +273,224 @@ const allConfigs = client.getAll();
client.stop();
```
+### PHP 客户端
+
+适用于 PHP 8.0+ 项目。
+
+**1. 安装**
+
+```bash
+cd kenaito-conf-php-client
+composer install
+```
+
+**2. 使用**
+
+```php
+use KenaitoConf\Config;
+use KenaitoConf\ConfigClient;
+
+$config = new Config([
+ 'baseUrl' => 'http://localhost:8080',
+ 'appName' => 'kenaito-springboot-demo',
+ 'env' => 'daily',
+ 'syncInterval' => 30,
+]);
+
+$client = new ConfigClient($config);
+
+$client->onChange(function ($changed) {
+ foreach ($changed as $k => $v) {
+ echo "config changed: $k = $v\n";
+ }
+});
+
+$client->start();
+$value = $client->get('database.host');
+$all = $client->getAll();
+```
+
+### .NET 客户端
+
+适用于 .NET 6.0+ 项目。
+
+**1. 引入依赖**
+
+```xml
+
+```
+
+**2. 使用**
+
+```csharp
+using KenaitoConf;
+
+var config = new Config
+{
+ BaseUrl = "http://localhost:8080",
+ AppName = "kenaito-springboot-demo",
+ Env = "daily",
+ SyncInterval = 30,
+};
+
+var client = new ConfigClient(config);
+client.OnChange(changed => {
+ foreach (var kv in changed)
+ Console.WriteLine($"config changed: {kv.Key} = {kv.Value}");
+});
+
+await client.StartAsync();
+var value = client.Get("database.host");
+```
+
+### C 客户端
+
+适用于嵌入式或高性能场景,依赖 libcurl + OpenSSL。
+
+**编译**
+
+```bash
+gcc -o demo kenaito-conf-c-client/main.c -lcurl -lssl -lcrypto
+```
+
+### C++ 客户端
+
+依赖 libcurl + OpenSSL,C++17。
+
+**编译**
+
+```bash
+g++ -std=c++17 -o demo kenaito-conf-cpp-client/main.cpp -lcurl -lssl -lcrypto -lpthread
+```
+
+### Lua 客户端
+
+适用于 Lua 5.3+ 项目(如 OpenResty/Nginx 网关)。
+
+**1. 安装**
+
+```bash
+cd kenaito-conf-lua-client
+luarocks install kenaito-conf-client-1.0.0-1.rockspec
+```
+
+**2. 使用**
+
+```lua
+local ConfigClient = require("kenaito-conf")
+
+local config = {
+ baseUrl = "http://localhost:8080",
+ appName = "kenaito-springboot-demo",
+ env = "daily",
+ syncInterval = 30,
+}
+
+local client = ConfigClient.new(config)
+client:on_change(function(changed)
+ for k, v in pairs(changed) do
+ print("config changed: " .. k .. " = " .. v)
+ end
+end)
+client:start()
+```
+
+### Kotlin 客户端
+
+适用于 Kotlin 1.9+ 项目。
+
+**1. 编译**
+
+```bash
+cd kenaito-conf-kotlin-client
+./gradlew build
+```
+
+**2. 使用**
+
+```kotlin
+import kenait.conf.Config
+import kenait.conf.ConfigClient
+
+val config = Config(
+ baseUrl = "http://localhost:8080",
+ appName = "kenaito-springboot-demo",
+ env = "daily",
+ syncInterval = 30,
+)
+
+val client = ConfigClient(config)
+client.onChange { changed ->
+ changed.forEach { (k, v) -> println("config changed: $k = $v") }
+}
+client.start()
+val value = client.get("database.host")
+```
+
+### Rust 客户端
+
+适用于 Rust 1.70+ 项目。
+
+**1. 在 Cargo.toml 中添加**
+
+```toml
+[dependencies]
+kenaito-conf = { path = "../kenaito-conf-rust-client" }
+```
+
+**2. 使用**
+
+```rust
+use kenaito_conf::{Config, ConfigClient};
+
+let config = Config {
+ base_url: "http://localhost:8080".to_string(),
+ app_name: "kenaito-springboot-demo".to_string(),
+ env: "daily".to_string(),
+ sync_interval: 30,
+ ..Default::default()
+};
+
+let client = ConfigClient::new(config);
+client.on_change(|changed| {
+ for (k, v) in changed { println!("config changed: {} = {}", k, v); }
+});
+client.start().await.unwrap();
+let value = client.get("database.host");
+```
+
+### Ruby 客户端
+
+适用于 Ruby 2.7+ 项目。
+
+**1. 安装**
+
+```bash
+cd kenaito-conf-ruby-client
+gem build kenaito-conf.gemspec
+gem install kenaito-conf-1.0.0.gem
+```
+
+**2. 使用**
+
+```ruby
+require 'kenaito_conf'
+
+config = KenaitoConf::Config.new(
+ base_url: 'http://localhost:8080',
+ app_name: 'kenaito-springboot-demo',
+ env: 'daily',
+ sync_interval: 30
+)
+
+client = KenaitoConf::ConfigClient.new(config)
+client.on_change do |changed|
+ changed.each { |k, v| puts "config changed: #{k} = #{v}" }
+end
+client.start
+value = client.get('database.host')
+```
+
## API 概览
### 管理端 API(需 JWT 认证)
diff --git a/kenaito-conf-c-client-demo/main.c b/kenaito-conf-c-client-demo/main.c
new file mode 100644
index 0000000..e707ff6
--- /dev/null
+++ b/kenaito-conf-c-client-demo/main.c
@@ -0,0 +1,8 @@
+#include
+
+int main() {
+ printf("Kenaito Config Center C Client Demo\n");
+ printf("AppName: kenaito-springboot-demo, Env: daily\n");
+ printf("See ../kenaito-conf-c-client/main.c for full implementation\n");
+ return 0;
+}
diff --git a/kenaito-conf-c-client/README.md b/kenaito-conf-c-client/README.md
new file mode 100644
index 0000000..40740ce
--- /dev/null
+++ b/kenaito-conf-c-client/README.md
@@ -0,0 +1,56 @@
+# Kenaito Config Center C Client
+
+C 语言的配置中心客户端 SDK,使用 libcurl + OpenSSL。
+
+## 依赖
+
+- libcurl
+- OpenSSL
+
+### macOS
+
+```bash
+brew install curl openssl
+```
+
+### Ubuntu/Debian
+
+```bash
+apt-get install libcurl4-openssl-dev libssl-dev
+```
+
+## 编译
+
+```bash
+cd kenaito-conf-c-client-demo
+gcc -o demo ../kenaito-conf-c-client/main.c -lcurl -lssl -lcrypto
+./demo
+```
+
+## 功能
+
+- AES-128-CBC 解密(与 Go/Java/Python 客户端兼容)
+- HTTP POST 拉取配置
+- 配置缓存
+
+## API
+
+```c
+ConfigClient client;
+config_client_init(&client, &config);
+const char *value = config_client_get(&client, "database.host");
+config_client_stop(&client);
+```
+
+## 配置参数
+
+| 参数 | 说明 | 默认值 |
+|------|------|--------|
+| `baseUrl` | 配置中心地址 | 必填 |
+| `appName` | 应用名称 | 必填 |
+| `env` | 环境 | `dev` |
+| `version` | 配置版本 | `latest` |
+| `token` | 认证令牌 | 空 |
+| `syncInterval` | 同步间隔(秒) | `60` |
+| `ignoreGlobal` | 是否忽略全局配置 | `0` |
+| `cacheDir` | 本地缓存目录 | `.` |
diff --git a/kenaito-conf-c-client/main.c b/kenaito-conf-c-client/main.c
new file mode 100644
index 0000000..aa42e74
--- /dev/null
+++ b/kenaito-conf-c-client/main.c
@@ -0,0 +1,206 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define MAX_CONFIGS 256
+#define MAX_KEY_LEN 256
+#define MAX_VAL_LEN 4096
+#define CRYPT_PREFIX "{Cipher}"
+
+typedef struct {
+ char baseUrl[512];
+ char appName[128];
+ char env[32];
+ char version[32];
+ char token[256];
+ int syncInterval;
+ int ignoreGlobal;
+ char cacheDir[256];
+} Config;
+
+typedef struct {
+ char key[MAX_KEY_LEN];
+ char value[MAX_VAL_LEN];
+} ConfigEntry;
+
+typedef struct {
+ ConfigEntry entries[MAX_CONFIGS];
+ int count;
+} ConfigMap;
+
+typedef struct {
+ Config config;
+ ConfigMap configs;
+ char secret[256];
+ char globalSecret[256];
+ long lastTime;
+ void (*onChange)(const char *key, const char *value);
+} ConfigClient;
+
+typedef struct {
+ char *data;
+ size_t size;
+} ResponseBuffer;
+
+static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
+ size_t totalSize = size * nmemb;
+ ResponseBuffer *buf = (ResponseBuffer *)userp;
+ char *ptr = realloc(buf->data, buf->size + totalSize + 1);
+ if (!ptr) return 0;
+ buf->data = ptr;
+ memcpy(&(buf->data[buf->size]), contents, totalSize);
+ buf->size += totalSize;
+ buf->data[buf->size] = 0;
+ return totalSize;
+}
+
+static void md5_hex(const char *input, char *output) {
+ unsigned char digest[MD5_DIGEST_LENGTH];
+ MD5((unsigned char *)input, strlen(input), digest);
+ for (int i = 0; i < MD5_DIGEST_LENGTH; i++)
+ sprintf(output + i * 2, "%02x", digest[i]);
+ output[32] = 0;
+}
+
+static int base64_decode(const char *src, unsigned char *dst) {
+ BIO *b64 = BIO_new(BIO_f_base64());
+ BIO *mem = BIO_new_mem_buf((void *)src, strlen(src));
+ mem = BIO_push(b64, mem);
+ BIO_set_flags(mem, BIO_FLAGS_BASE64_NO_NL);
+ int len = BIO_read(mem, dst, strlen(src));
+ BIO_free_all(mem);
+ return len;
+}
+
+static void decrypt_with_aes(const char *key, const char *data, char *output) {
+ char md5Hash[33];
+ md5_hex(key, md5Hash);
+ unsigned char aesKey[16];
+ memcpy(aesKey, md5Hash + 16, 16);
+
+ unsigned char *cipherText = malloc(strlen(data) * 2);
+ int cipherLen = base64_decode(data, cipherText);
+
+ unsigned char iv[16] = {0};
+ unsigned char plainText[4096];
+
+ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+ EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, aesKey, iv);
+ EVP_CIPHER_CTX_set_padding(ctx, 0);
+ int len = 0, totalLen = 0;
+ EVP_DecryptUpdate(ctx, plainText, &len, cipherText, cipherLen);
+ totalLen = len;
+ EVP_DecryptFinal_ex(ctx, plainText + len, &len);
+ totalLen += len;
+ EVP_CIPHER_CTX_free(ctx);
+
+ int padding = plainText[totalLen - 1];
+ totalLen -= padding;
+ memcpy(output, plainText, totalLen);
+ output[totalLen] = 0;
+
+ free(cipherText);
+}
+
+static void decrypt_config(const char *secret, const char *data, char *output) {
+ if (strncmp(data, CRYPT_PREFIX, strlen(CRYPT_PREFIX)) != 0) {
+ strcpy(output, data);
+ return;
+ }
+ decrypt_with_aes(secret, data + strlen(CRYPT_PREFIX), output);
+}
+
+static char *http_post_json(const char *url, const char *jsonBody) {
+ CURL *curl = curl_easy_init();
+ if (!curl) return NULL;
+
+ ResponseBuffer buf = {0};
+ struct curl_slist *headers = NULL;
+ headers = curl_slist_append(headers, "Content-Type: application/json");
+
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonBody);
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buf);
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
+
+ CURLcode res = curl_easy_perform(curl);
+ curl_slist_free_all(headers);
+ curl_easy_cleanup(curl);
+
+ if (res != CURLE_OK) {
+ free(buf.data);
+ return NULL;
+ }
+ return buf.data;
+}
+
+void config_client_init(ConfigClient *client, Config *config) {
+ client->config = *config;
+ client->configs.count = 0;
+ client->secret[0] = 0;
+ client->globalSecret[0] = 0;
+ client->lastTime = 0;
+ client->onChange = NULL;
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+}
+
+const char *config_client_get(ConfigClient *client, const char *key) {
+ for (int i = 0; i < client->configs.count; i++) {
+ if (strcmp(client->configs.entries[i].key, key) == 0)
+ return client->configs.entries[i].value;
+ }
+ return NULL;
+}
+
+void config_client_stop(ConfigClient *client) {
+ curl_global_cleanup();
+}
+
+int main() {
+ printf("Kenaito Config Center C Client Demo\n");
+ printf("AppName: kenaito-springboot-demo, Env: daily\n");
+
+ Config config = {
+ .baseUrl = "http://localhost:8080",
+ .appName = "kenaito-springboot-demo",
+ .env = "daily",
+ .version = "latest",
+ .token = "",
+ .syncInterval = 30,
+ .ignoreGlobal = 0,
+ .cacheDir = "."
+ };
+
+ ConfigClient client;
+ config_client_init(&client, &config);
+
+ /* Build fetchAllConfigs request */
+ char url[1024];
+ snprintf(url, sizeof(url), "%s/api/fetchAllConfigs", config.baseUrl);
+
+ char payload[512];
+ snprintf(payload, sizeof(payload),
+ "{\"appName\":\"%s\",\"env\":\"%s\",\"version\":\"%s\",\"ignoreGlobal\":false,\"token\":\"%s\"}",
+ config.appName, config.env, config.version, config.token);
+
+ printf("Fetching configs from %s ...\n", url);
+ char *response = http_post_json(url, payload);
+ if (response) {
+ printf("Response received (%zu bytes)\n", strlen(response));
+ /* In production: parse JSON, decrypt, store configs */
+ printf("First 200 chars: %.200s\n", response);
+ free(response);
+ } else {
+ printf("Failed to fetch configs (server may not be running)\n");
+ }
+
+ config_client_stop(&client);
+ return 0;
+}
diff --git a/kenaito-conf-cpp-client-demo/main.cpp b/kenaito-conf-cpp-client-demo/main.cpp
new file mode 100644
index 0000000..bcd6005
--- /dev/null
+++ b/kenaito-conf-cpp-client-demo/main.cpp
@@ -0,0 +1,8 @@
+#include
+
+int main() {
+ std::cout << "Kenaito Config Center C++ Client Demo" << std::endl;
+ std::cout << "AppName: kenaito-springboot-demo, Env: daily" << std::endl;
+ std::cout << "See ../kenaito-conf-cpp-client/main.cpp for full implementation" << std::endl;
+ return 0;
+}
diff --git a/kenaito-conf-cpp-client/README.md b/kenaito-conf-cpp-client/README.md
new file mode 100644
index 0000000..dce48c5
--- /dev/null
+++ b/kenaito-conf-cpp-client/README.md
@@ -0,0 +1,50 @@
+# Kenaito Config Center C++ Client
+
+C++ 语言的配置中心客户端 SDK,使用 libcurl + OpenSSL。
+
+## 依赖
+
+- libcurl
+- OpenSSL
+- C++17
+
+### macOS
+
+```bash
+brew install curl openssl
+```
+
+### Ubuntu/Debian
+
+```bash
+apt-get install libcurl4-openssl-dev libssl-dev
+```
+
+## 编译
+
+```bash
+cd kenaito-conf-cpp-client-demo
+g++ -std=c++17 -o demo ../kenaito-conf-cpp-client/main.cpp -lcurl -lssl -lcrypto -lpthread
+./demo
+```
+
+## 功能
+
+- AES-128-CBC 解密
+- HTTP POST 拉取配置
+- 定时同步
+- 变更回调
+- 线程安全
+
+## 配置参数
+
+| 参数 | 说明 | 默认值 |
+|------|------|--------|
+| `baseUrl` | 配置中心地址 | 必填 |
+| `appName` | 应用名称 | 必填 |
+| `env` | 环境 | `dev` |
+| `version` | 配置版本 | `latest` |
+| `token` | 认证令牌 | 空 |
+| `syncInterval` | 同步间隔(秒) | `60` |
+| `ignoreGlobal` | 是否忽略全局配置 | `false` |
+| `cacheDir` | 本地缓存目录 | `.` |
diff --git a/kenaito-conf-cpp-client/main.cpp b/kenaito-conf-cpp-client/main.cpp
new file mode 100644
index 0000000..9af3c6b
--- /dev/null
+++ b/kenaito-conf-cpp-client/main.cpp
@@ -0,0 +1,153 @@
+#include
+#include
+#include