cmvr-es/src/main.cpp
2025-11-13 20:25:19 +08:00

225 lines
8.5 KiB
C++
Raw 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.

//
// Created by xtkuang on 2025/5/6.
//
#include <unistd.h>
#include <limits.h>
#include <libgen.h>
#include <iostream>
#include <glog/logging.h>
#include "device_manager/device_manager.h"
#include "monitor/monitor_manager.h"
#include "service/grpc_camera_service.h"
#include "service/grpc_system_service.h"
#include "service/grpc_speaker_service.h"
#include "service/grpc_microphone_service.h"
#include "service/grpc_dexhand_service.h"
#include "utils/base/logger.h"
#include "service/grpc_head_service.h"
#include "service/grpc_humanoid_robot_service.h"
#include "service/grpc_hlc_service.h"
#include "http/httpclient.h"
#include "json/json.h"
#include <grpcpp/ext/proto_server_reflection_plugin.h>
void runServer(const XmlNode &cfg){
using namespace cmvr::device;
using namespace cmvr::service;
using namespace cmvr::monitor;
if (!cfg.hasChild("DeviceManager")){
LOG(ERROR) << "Device Manager node not found";
return;
}
try {
// 🔥 关键!启用反射
grpc::reflection::InitProtoReflectionServerBuilderPlugin();
auto dmgr_cfg = cfg.getChild("DeviceManager");
DeviceManager::getInstance(dmgr_cfg);
auto mmgr_cfg = cfg.getChild("MonitorManager");
MonitorManager::getInstance(mmgr_cfg);
auto grpc_cfg = cfg.getChild("gRPCServer");
string port = grpc_cfg.getAttrDefault("port", "50051");
std::string address("0.0.0.0:" + port);
auto camera_service = gRPCCameraServiceImpl();
auto system_service = gRPCSystemServiceImpl();
auto speaker_service = gRPCSpeakerServiceImpl();
auto microphone_service = gRPCMicroPhoneServiceImpl();
auto dexhand_service = gRPCDexHandServiceImpl();
auto biohand_service = gRPCMBioHeadServiceImpl();
auto humanoid_robot_service = gRPCHumanoidRobotServiceImpl();
auto hlc_service = gRPCHlcServiceImpl();
grpc::ServerBuilder builder;
builder.AddListeningPort(address, grpc::InsecureServerCredentials());
builder.RegisterService(&camera_service);
builder.RegisterService(&system_service);
builder.RegisterService(&speaker_service);
builder.RegisterService(&microphone_service);
builder.RegisterService(&dexhand_service);
builder.RegisterService(&biohand_service);
builder.RegisterService(&humanoid_robot_service);
builder.RegisterService(&hlc_service);
// 🔥 关键!启用反射
//grpc::reflection::InitProtoReflectionServerBuilderPlugin();
const std::unique_ptr server(builder.BuildAndStart());
std::cout << "Server listening on " << address << std::endl;
server->Wait();
}
catch (std:: exception &e) {
LOG(FATAL) << e.what();
}
}
int test_httpclient() {
try {
std::cout << "HTTP Client Example" << std::endl;
std::cout << "===================" << std::endl;
// 创建HTTP客户端
cmvr::HttpClient client;
// 设置基础URL - 使用Reqres.in替代JSONPlaceholder
client.setBaseUrl("https://reqres.in/api");
// 设置超时时间为15秒增加超时时间以应对网络波动
client.setTimeout(15000);
// 示例1: GET请求 - 获取用户列表
std::cout << "\n=== Example 1: GET Request (List Users) ===" << std::endl;
cmvr::HttpResponse response = client.get("/users?page=1");
std::cout << "Status: " << response.statusCode << " " << response.statusText << std::endl;
std::cout << "Content-Type: " << response.headers["Content-Type"] << std::endl;
std::cout << "Response Body: " << std::endl << response.body << std::endl;
// 示例2: POST JSON请求 - 创建用户
std::cout << "\n=== Example 2: POST JSON Request (Create User) ===" << std::endl;
// 使用JsonCpp创建JSON数据
Json::Value postData;
postData["name"] = "John Doe";
postData["job"] = "Software Engineer";
// 将JSON转换为字符串
Json::StreamWriterBuilder writer;
std::string jsonString = Json::writeString(writer, postData);
response = client.postJson("/users", {}, jsonString);
std::cout << "Status: " << response.statusCode << " " << response.statusText << std::endl;
std::cout << "Content-Type: " << response.headers["Content-Type"] << std::endl;
std::cout << "Response Body: " << std::endl << response.body << std::endl;
// 示例3: 解析JSON响应 - 获取单个用户
std::cout << "\n=== Example 3: Parsing JSON Response (Single User) ===" << std::endl;
response = client.get("/users/2");
if (response.statusCode == 200) {
// 使用JsonCpp解析JSON字符串
Json::Value user;
Json::CharReaderBuilder reader;
std::string errors;
std::istringstream stream(response.body);
bool parsingSuccessful = Json::parseFromStream(reader, stream, &user, &errors);
if (parsingSuccessful) {
Json::Value data = user["data"];
std::cout << "User ID: " << data["id"].asInt() << std::endl;
std::cout << "Email: " << data["email"].asString() << std::endl;
std::cout << "First Name: " << data["first_name"].asString() << std::endl;
std::cout << "Last Name: " << data["last_name"].asString() << std::endl;
} else {
std::cerr << "Failed to parse JSON: " << errors << std::endl;
}
}
// 示例4: PUT请求 - 更新用户
std::cout << "\n=== Example 4: PUT Request (Update User) ===" << std::endl;
Json::Value updateData;
updateData["name"] = "Jane Doe";
updateData["job"] = "Senior Software Engineer";
std::string updateJson = Json::writeString(writer, updateData);
response = client.postJson("/users/2", {}, updateJson); // Reqres.in使用POST处理PUT请求
std::cout << "Status: " << response.statusCode << " " << response.statusText << std::endl;
std::cout << "Content-Type: " << response.headers["Content-Type"] << std::endl;
std::cout << "Response Body: " << std::endl << response.body << std::endl;
// 示例5: 测试HttpBin.org - 获取请求头信息
std::cout << "\n=== Example 5: HttpBin.org (Request Headers) ===" << std::endl;
// 切换到HttpBin.org
client.setBaseUrl("https://httpbin.org");
// 添加自定义请求头
client.clearHeaders();
client.addHeader("X-Test-Header", "Hello from HttpClient");
client.addHeader("Accept", "application/json");
response = client.get("/headers");
std::cout << "Status: " << response.statusCode << " " << response.statusText << std::endl;
std::cout << "Content-Type: " << response.headers["Content-Type"] << std::endl;
std::cout << "Response Body: " << std::endl << response.body << std::endl;
// 示例6: 测试超时与错误处理
std::cout << "\n=== Example 6: Timeout & Error Handling ===" << std::endl;
// 设置较短的超时时间
client.setTimeout(2000); // 2秒超时
try {
// 请求一个会延迟响应的端点
response = client.get("/delay/5"); // 服务器会延迟5秒响应
std::cout << "Status: " << response.statusCode << " " << response.statusText << std::endl;
} catch (const cmvr::HttpException& e) {
std::cout << "Error (Expected Timeout): " << e.what() << std::endl;
}
// 恢复正常超时
client.setTimeout(15000);
} catch (const cmvr::HttpException& e) {
std::cerr << "HTTP Error: " << e.what() << std::endl;
return 1;
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}
int main(int argc, char* argv[]) {
std::string config_path;
if(argc == 1) {
char exe_path[PATH_MAX] = {0};
ssize_t count = readlink("/proc/self/exe", exe_path, PATH_MAX);
if (count == -1) {
std::cerr << "Failed to read /proc/self/exe" << std::endl;
return 1;
}
std::string exe_dir = dirname(exe_path);
config_path = exe_dir + "/../config/cabin_robot.xml";
std::cout << "Using default config path: " << config_path << std::endl;
}
else if (argc == 2){
config_path = argv[1];
}
const XmlNode config(config_path);
initLogger(config.getChild("Logger"));
runServer(config);
google::ShutdownGoogleLogging();
return 0;
}