// // Created by xtkuang on 2025/5/6. // #include #include #include #include #include #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 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(µphone_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; }