initial commit

This commit is contained in:
2025-08-05 15:53:44 +08:00
commit 09dc02ae52
553 changed files with 137665 additions and 0 deletions

144
third_party/libhv/examples/consul/consul.cpp vendored Executable file
View File

@@ -0,0 +1,144 @@
#include "consul.h"
#include "HttpClient.h"
using namespace hv;
#include "json.hpp"
using json = nlohmann::json;
#define PROTOCOL "http://"
#define API_VERSION "v1"
static const char url_register[] = "/agent/service/register";
static const char url_deregister[] = "/agent/service/deregister";
static const char url_discover[] = "/catalog/service";
static std::string make_url(const char* ip, int port, const char* url) {
return asprintf(PROTOCOL "%s:%d/" API_VERSION "%s", ip, port, url);
}
static std::string make_ServiceID(consul_service_t* service) {
return asprintf("%s-%s:%d", service->name, service->ip, service->port);
}
/*
{
"ID": "redis1",
"Name": "redis",
"Tags": [
"primary",
"v1"
],
"Address": "127.0.0.1",
"Port": 8000,
"Meta": {
"redis_version": "4.0"
},
"EnableTagOverride": false,
"Check": {
"DeregisterCriticalServiceAfter": "90m",
"Args": ["/usr/local/bin/check_redis.py"],
"HTTP": "http://localhost:5000/health",
"Interval": "10s",
"TTL": "15s"
},
"Weights": {
"Passing": 10,
"Warning": 1
}
}
*/
int register_service(consul_node_t* node, consul_service_t* service, consul_health_t* health) {
HttpRequest req;
req.method = HTTP_PUT;
req.url = make_url(node->ip, node->port, url_register);
req.content_type = APPLICATION_JSON;
json jservice;
jservice["Name"] = service->name;
if (*service->ip) {
jservice["Address"] = service->ip;
}
jservice["Port"] = service->port;
jservice["ID"] = make_ServiceID(service);
json jcheck;
if (*health->url == '\0') {
snprintf(health->url, sizeof(health->url), "%s:%d", service->ip, service->port);
}
jcheck[health->protocol] = health->url;
jcheck["Interval"] = asprintf("%dms", health->interval);
jcheck["DeregisterCriticalServiceAfter"] = asprintf("%dms", health->interval * 3);
jservice["Check"] = jcheck;
req.body = jservice.dump();
printd("PUT %s\n", req.url.c_str());
printd("%s\n", req.body.c_str());
HttpResponse res;
int ret = http_client_send(&req, &res);
printd("%s\n", res.body.c_str());
return ret;
}
int deregister_service(consul_node_t* node, consul_service_t* service) {
std::string url = make_url(node->ip, node->port, url_deregister);
url += '/';
url += make_ServiceID(service);
HttpRequest req;
req.method = HTTP_PUT;
req.url = url;
req.content_type = APPLICATION_JSON;
printd("PUT %s\n", req.url.c_str());
HttpResponse res;
int ret = http_client_send(&req, &res);
printd("%s\n", res.body.c_str());
return ret;
}
int discover_services(consul_node_t* node, const char* service_name, std::vector<consul_service_t>& services) {
std::string url = make_url(node->ip, node->port, url_discover);
url += '/';
url += service_name;
HttpRequest req;
req.method = HTTP_GET;
req.url = url;
HttpResponse res;
printd("GET %s\n", req.url.c_str());
int ret = http_client_send(&req, &res);
if (ret != 0) return ret;
printd("%s\n", res.body.c_str());
json jroot = json::parse(res.body);
if (!jroot.is_array()) return -1;
if (jroot.size() == 0) return 0;
consul_service_t service;
std::string name, ip;
services.clear();
for (size_t i = 0; i < jroot.size(); ++i) {
auto jservice = jroot[i];
name = jservice["ServiceName"];
if (jservice.contains("Address")) {
ip = jservice["Address"];
} else if (jservice.contains("ServiceAddress")) {
ip = jservice["ServiceAddress"];
} else if (jservice.contains("ServiceAddress6")) {
ip = jservice["ServiceAddress6"];
} else {
continue;
}
int port = jservice["ServicePort"];
strncpy(service.name, name.c_str(), sizeof(service.name));
strncpy(service.ip, ip.c_str(), sizeof(service.ip));
service.port = port;
services.emplace_back(service);
}
return 0;
}

53
third_party/libhv/examples/consul/consul.h vendored Executable file
View File

@@ -0,0 +1,53 @@
#ifndef CONSUL_H_
#define CONSUL_H_
#include <vector>
#include <string.h>
typedef struct consul_node_s {
// node
char ip[64];
int port;
consul_node_s() {
strcpy(ip, "127.0.0.1");
port = 8500;
}
} consul_node_t;
typedef struct consul_service_s {
// service
char name[64];
char ip[64];
int port;
consul_service_s() {
name[0] = '\0';
strcpy(ip, "127.0.0.1");
port = 0;
}
} consul_service_t;
typedef struct consul_health_s {
// check
char protocol[32]; // TCP,HTTP
char url[256];
char status[32]; // any,passing,warning,critical
int interval; // ms
int timeout; // ms
consul_health_s() {
strcpy(protocol, "TCP");
url[0] = '\0';
strcpy(status, "passing");
interval = 10000;
timeout = 3000;
}
} consul_health_t;
int register_service(consul_node_t* node, consul_service_t* service, consul_health_t* health);
int deregister_service(consul_node_t* node, consul_service_t* service);
int discover_services(consul_node_t* node, const char* service_name, std::vector<consul_service_t>& services);
#endif // CONSUL_H_

67
third_party/libhv/examples/consul/main.cpp vendored Executable file
View File

@@ -0,0 +1,67 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "consul.h"
int main(int argc, char* argv[]) {
if (argc < 3) {
printf("Usage: consul_cli subcmd ServiceName [ServiceAddress ServicePort] [NodeIP NodePort]\n");
printf("subcmd=[register,deregister,discover]\n");
return -10;
}
const char* subcmd = argv[1];
const char* ServiceName = argv[2];
const char* ServiceAddress = "127.0.0.1";
int ServicePort = 0;
const char* NodeIP = "127.0.0.1";
int NodePort = 8500;
if (argc > 3) {
ServiceAddress = argv[3];
}
if (argc > 4) {
ServicePort = atoi(argv[4]);
}
if (argc > 5) {
NodeIP = argv[5];
}
if (argc > 6) {
NodePort = atoi(argv[6]);
}
consul_node_t node;
strncpy(node.ip, NodeIP, sizeof(node.ip));
node.port = NodePort;
consul_service_t service;
strncpy(service.name, ServiceName, sizeof(service.name));
strncpy(service.ip, ServiceAddress, sizeof(service.ip));
service.port = ServicePort;
consul_health_t health;
if (strcmp(subcmd, "register") == 0) {
int ret = register_service(&node, &service, &health);
printf("register_service retval=%d\n", ret);
goto discover;
}
else if (strcmp(subcmd, "deregister") == 0) {
int ret = deregister_service(&node, &service);
printf("deregister_service retval=%d\n", ret);
goto discover;
}
else if (strcmp(subcmd, "discover") == 0) {
discover:
std::vector<consul_service_t> services;
discover_services(&node, ServiceName, services);
for (auto& service : services) {
printf("name=%s ip=%s port=%d\n", service.name, service.ip, service.port);
}
}
else {
printf("subcmd error!\n");
return -20;
}
return 0;
}