225 lines
8.5 KiB
C++
225 lines
8.5 KiB
C++
//
|
||
// 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(µ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;
|
||
}
|