diff --git a/CMakeLists.txt b/CMakeLists.txt index bf9086b..5fadba3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,4 +22,6 @@ target_link_libraries(shifter add_executable(infoer Infoer.cpp -) \ No newline at end of file +) + +add_subdirectory(Practices) \ No newline at end of file diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..b5c81db --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,15 @@ +{ + "version": 2, + "configurePresets": [ + { + "name": "app", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/x64", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/resources/host.cmake", + "CMAKE_EXPORT_COMPILE_COMMANDS": true + }, + "environment": {} + } + ] +} \ No newline at end of file diff --git a/Practices/CMakeLists.txt b/Practices/CMakeLists.txt new file mode 100644 index 0000000..6f5db75 --- /dev/null +++ b/Practices/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(DeviceController + DeviceController.cpp +) \ No newline at end of file diff --git a/Practices/DeviceController.cpp b/Practices/DeviceController.cpp new file mode 100644 index 0000000..0a7d4ba --- /dev/null +++ b/Practices/DeviceController.cpp @@ -0,0 +1,275 @@ +#include +#include +#include +#include +#include +#include + +// 通信策略接口 +class ICommunicationStrategy { +public: + virtual ~ICommunicationStrategy() = default; + virtual void sendCommand(const std::string& command, int value) = 0; + virtual void connect() = 0; + virtual void disconnect() = 0; + virtual bool isConnected() const = 0; +}; + +// MQTT适配器 +class MQTTAdapter : public ICommunicationStrategy { +private: + std::string brokerUrl; + std::string clientId; + bool connected = false; + +public: + MQTTAdapter(const std::string& broker, const std::string& id) + : brokerUrl(broker), clientId(id) {} + + void connect() override { + // 实现MQTT连接逻辑 + std::cout << "Connecting to MQTT broker: " << brokerUrl << std::endl; + connected = true; + } + + void disconnect() override { + // 实现MQTT断开连接逻辑 + std::cout << "Disconnecting from MQTT broker" << std::endl; + connected = false; + } + + void sendCommand(const std::string& command, int value) override { + if (!connected) { + throw std::runtime_error("MQTT not connected"); + } + std::string topic = "terminal/control/" + command; + std::string payload = std::to_string(value); + std::cout << "MQTT Publish - Topic: " << topic << ", Payload: " << payload << std::endl; + // 实际的MQTT发布逻辑 + } + + bool isConnected() const override { + return connected; + } +}; + +// HTTP适配器 +class HTTPAdapter : public ICommunicationStrategy { +private: + std::string baseUrl; + bool connected = false; + +public: + HTTPAdapter(const std::string& url) : baseUrl(url) {} + + void connect() override { + std::cout << "Initializing HTTP client with base URL: " << baseUrl << std::endl; + connected = true; + } + + void disconnect() override { + std::cout << "Cleaning up HTTP client" << std::endl; + connected = false; + } + + void sendCommand(const std::string& command, int value) override { + if (!connected) { + throw std::runtime_error("HTTP client not initialized"); + } + std::string url = baseUrl + "/api/control/" + command; + std::cout << "HTTP POST - URL: " << url << ", Value: " << value << std::endl; + // 实际的HTTP POST请求逻辑 + } + + bool isConnected() const override { + return connected; + } +}; + +// WebSocket适配器 +class WebSocketAdapter : public ICommunicationStrategy { +private: + std::string wsUrl; + bool connected = false; + +public: + WebSocketAdapter(const std::string& url) : wsUrl(url) {} + + void connect() override { + std::cout << "Connecting to WebSocket: " << wsUrl << std::endl; + connected = true; + } + + void disconnect() override { + std::cout << "Disconnecting WebSocket" << std::endl; + connected = false; + } + + void sendCommand(const std::string& command, int value) override { + if (!connected) { + throw std::runtime_error("WebSocket not connected"); + } + std::string message = "{\"command\":\"" + command + "\",\"value\":" + std::to_string(value) + "}"; + std::cout << "WebSocket Send: " << message << std::endl; + // 实际的WebSocket发送逻辑 + } + + bool isConnected() const override { + return connected; + } +}; + +// TCP适配器 +class TCPAdapter : public ICommunicationStrategy { +private: + std::string host; + int port; + int socketFd = -1; + +public: + TCPAdapter(const std::string& h, int p) : host(h), port(p) {} + + void connect() override { + std::cout << "Connecting TCP to " << host << ":" << port << std::endl; + // 实际的TCP连接逻辑 + socketFd = 1; // 模拟连接成功 + } + + void disconnect() override { + std::cout << "Disconnecting TCP" << std::endl; + socketFd = -1; + } + + void sendCommand(const std::string& command, int value) override { + if (socketFd < 0) { + throw std::runtime_error("TCP not connected"); + } + std::string data = command + ":" + std::to_string(value) + "\n"; + std::cout << "TCP Send: " << data; + // 实际的TCP发送逻辑 + } + + bool isConnected() const override { + return socketFd >= 0; + } +}; + +// 配置结构体 +struct Config { + std::map params; +}; + +// 工厂类 +class CommunicationFactory { +public: + static std::unique_ptr createStrategy( + const std::string& type, + const Config& config) { + + if (type == "mqtt") { + auto it = config.params.find("broker"); + std::string broker = (it != config.params.end()) ? it->second : "tcp://localhost:1883"; + it = config.params.find("clientId"); + std::string clientId = (it != config.params.end()) ? it->second : "terminal_default"; + return std::make_unique(broker, clientId); + } + else if (type == "http") { + auto it = config.params.find("baseUrl"); + std::string baseUrl = (it != config.params.end()) ? it->second : "http://localhost:8080"; + return std::make_unique(baseUrl); + } + else if (type == "websocket") { + auto it = config.params.find("url"); + std::string url = (it != config.params.end()) ? it->second : "ws://localhost:8081"; + return std::make_unique(url); + } + else if (type == "tcp") { + auto it = config.params.find("host"); + std::string host = (it != config.params.end()) ? it->second : "localhost"; + it = config.params.find("port"); + int port = (it != config.params.end()) ? std::stoi(it->second) : 8082; + return std::make_unique(host, port); + } + else { + throw std::invalid_argument("Unsupported communication type: " + type); + } + } +}; + +// 终端控制器 +class TerminalController { +private: + std::unique_ptr strategy; + +public: + void setStrategy(std::unique_ptr newStrategy) { + if (strategy && strategy->isConnected()) { + strategy->disconnect(); + } + strategy = std::move(newStrategy); + if (strategy) { + strategy->connect(); + } + } + + void controlVolume(int volume) { + if (!strategy) { + throw std::runtime_error("No communication strategy set"); + } + strategy->sendCommand("volume", volume); + } + + void controlBrightness(int brightness) { + if (!strategy) { + throw std::runtime_error("No communication strategy set"); + } + strategy->sendCommand("brightness", brightness); + } +}; + +// 使用示例 +int main() { + try { + TerminalController controller; + + // 使用MQTT协议 + Config mqttConfig; + mqttConfig.params["broker"] = "tcp://mqtt.example.com:1883"; + mqttConfig.params["clientId"] = "terminal_001"; + + controller.setStrategy(CommunicationFactory::createStrategy("mqtt", mqttConfig)); + controller.controlVolume(80); + controller.controlBrightness(60); + + // 切换到HTTP协议 + Config httpConfig; + httpConfig.params["baseUrl"] = "http://192.168.1.100:8080"; + + controller.setStrategy(CommunicationFactory::createStrategy("http", httpConfig)); + controller.controlVolume(75); + controller.controlBrightness(70); + + // 切换到WebSocket协议 + Config wsConfig; + wsConfig.params["url"] = "ws://192.168.1.100:8081/ws"; + + controller.setStrategy(CommunicationFactory::createStrategy("websocket", wsConfig)); + controller.controlVolume(85); + controller.controlBrightness(65); + + // 切换到TCP协议 + Config tcpConfig; + tcpConfig.params["host"] = "192.168.1.100"; + tcpConfig.params["port"] = "8082"; + + controller.setStrategy(CommunicationFactory::createStrategy("tcp", tcpConfig)); + controller.controlVolume(90); + controller.controlBrightness(75); + + } catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + return 1; + } + + return 0; +} \ No newline at end of file diff --git a/resources/host.cmake b/resources/host.cmake new file mode 100644 index 0000000..da7d446 --- /dev/null +++ b/resources/host.cmake @@ -0,0 +1,8 @@ +set(3RDPARTY_ROOT /opt/3rdparty) +set(MbedTLS_DIR ${3RDPARTY_ROOT}/mbedtls-3.6.5/lib/cmake/MbedTLS) +set(nng_DIR ${3RDPARTY_ROOT}/nng-1.11/lib/cmake/nng) +set(BOOST_ROOT ${3RDPARTY_ROOT}/boost_1_90_0) + + +set(Qt6_DIR /opt/Qt/6.10.0/gcc_64/lib/cmake/Qt6) +set(QT_DIR ${Qt6_DIR}) \ No newline at end of file