Skip to content

NET_CommandHandler

SweerItTer edited this page Feb 21, 2026 · 1 revision

CommandHandler

概述

CommandHandler 是命令处理器,负责命令注册表的维护和命令分发逻辑。专注命令处理,与 TcpServer 通过 std::weak_ptr 解耦。

类定义

class CommandHandler {
public:
    CommandHandler() = default;
    ~CommandHandler() = default;

    // 禁止拷贝,允许移动
    CommandHandler(const CommandHandler&) = delete;
    CommandHandler& operator=(const CommandHandler&) = delete;
    CommandHandler(CommandHandler&& other) noexcept = default;
    CommandHandler& operator=(CommandHandler&& other) noexcept = default;

    // 命令管理
    bool registerCommand(const std::string& command,
                        CommandCallback callback,
                        const std::string& description = "");
    bool unregisterCommand(const std::string& command);

    // 命令执行
    std::string executeCommand(uint64_t clientId,
                               const std::string& command,
                               const std::string& params);

    // 查询接口
    bool hasCommand(const std::string& command) const;
    std::vector<std::string> listCommands() const;
    std::string getCommandDescription(const std::string& command) const;
    size_t getCommandCount() const;

    // 清除
    void clearAll();

private:
    struct CommandEntry {
        CommandCallback callback;
        std::string description;
    };

    mutable std::mutex registryMutex_;
    std::map<std::string, CommandEntry> commandRegistry_;
};

公共方法

构造/析构

CommandHandler()

描述: 构造命令处理器。

示例:

CommandHandler handler;

~CommandHandler()

描述: 析构函数,自动清理所有注册的命令。

命令管理

bool registerCommand(const std::string& command, CommandCallback callback, const std::string& description = "")

描述: 注册命令处理器。

参数:

  • command: 命令名称(如 "GET"、"POST"、"GETFILENAME")
  • callback: 命令回调函数
  • description: 命令描述(可选,用于日志和调试)

返回值:

  • true: 注册成功
  • false: 命令已存在

回调函数签名:

using CommandCallback = std::function<std::string(
    uint64_t clientId,      // 客户端 ID
    const std::string& command,  // 命令名称
    const std::string& params   // 命令参数
)>;

示例:

// 注册简单命令
handler.registerCommand("ECHO", [](uint64_t clientId, const std::string& command, const std::string& params) {
    return params;
});

// 注册带描述的命令
handler.registerCommand("GETFILENAME",
    [](uint64_t clientId, const std::string& command, const std::string& params) {
        std::string filename = params.empty() ? "default.txt" : params;
        // 处理文件请求
        return "OK " + filename;
    },
    "Get file content by filename"
);

bool unregisterCommand(const std::string& command)

描述: 注销命令处理器。

参数:

  • command: 命令名称

返回值:

  • true: 注销成功
  • false: 命令不存在

示例:

handler.unregisterCommand("ECHO");

命令执行

std::string executeCommand(uint64_t clientId, const std::string& command, const std::string& params)

描述: 执行命令。

参数:

  • clientId: 客户端 ID
  • command: 命令名称
  • params: 命令参数

返回值: 命令执行结果字符串,命令不存在时返回空字符串

示例:

auto result = handler.executeCommand(clientId, "ECHO", "Hello World");
// result = "Hello World"

查询接口

bool hasCommand(const std::string& command) const

描述: 检查命令是否已注册。

参数:

  • command: 命令名称

返回值:

  • true: 已注册
  • false: 未注册

示例:

if (handler.hasCommand("GET")) {
    // 命令存在
}

std::vectorstd::string listCommands() const

描述: 获取所有已注册的命令列表。

返回值: 命令名称列表

示例:

auto commands = handler.listCommands();
for (const auto& cmd : commands) {
    std::cout << cmd << std::endl;
}

std::string getCommandDescription(const std::string& command) const

描述: 获取命令描述。

参数:

  • command: 命令名称

返回值: 命令描述,命令不存在返回空字符串

示例:

std::string desc = handler.getCommandDescription("GETFILENAME");
// desc = "Get file content by filename"

size_t getCommandCount() const

描述: 获取已注册命令数量。

返回值: 命令数量

示例:

size_t count = handler.getCommandCount();
std::cout << "Registered commands: " << count << std::endl;

清除

void clearAll()

描述: 清除所有已注册的命令。

示例:

handler.clearAll();

命令格式

客户端命令格式

客户端发送的命令格式:

COMMAND PARAMS

示例:

GETFILENAME /path/to/file.txt
ECHO Hello World
TIME

服务器响应格式

服务器响应的格式由命令回调函数决定,通常为:

STATUS RESULT

示例:

OK /path/to/file.txt
ERROR File not found

使用示例

基本使用

#include "utils/net/commandHandler.h"

int main() {
    CommandHandler handler;

    // 注册命令
    handler.registerCommand("ECHO", [](uint64_t clientId, const std::string& command, const std::string& params) {
        return params;
    });

    handler.registerCommand("TIME", [](uint64_t clientId, const std::string& command, const std::string& params) {
        auto now = std::chrono::system_clock::now();
        auto time = std::chrono::system_clock::to_time_t(now);
        return std::string(ctime(&time));
    });

    // 执行命令
    auto result = handler.executeCommand(123, "ECHO", "Hello");
    std::cout << result << std::endl;  // 输出: Hello

    // 查询命令
    auto commands = handler.listCommands();
    std::cout << "Available commands: ";
    for (const auto& cmd : commands) {
        std::cout << cmd << " ";
    }
    std::cout << std::endl;

    return 0;
}

在 TcpServer 中使用

// 创建命令处理器
auto commandHandler = std::make_shared<CommandHandler>();

// 注册命令
commandHandler->registerCommand("GET", [](uint64_t clientId, const std::string& command, const std::string& params) {
    return "OK GET " + params;
});

commandHandler->registerCommand("SET", [](uint64_t clientId, const std::string& command, const std::string& params) {
    // 解析参数
    size_t space = params.find(' ');
    std::string key = params.substr(0, space);
    std::string value = params.substr(space + 1);
    // 处理 SET 操作
    return "OK SET " + key + "=" + value;
});

// 创建服务器并设置命令处理器
TcpServer server(config, commandHandler);
server.start();

动态注册/注销

auto commandHandler = std::make_shared<CommandHandler>();

// 动态注册
commandHandler->registerCommand("TEMP_CMD", [](uint64_t clientId, const std::string& command, const std::string& params) {
    return "Temporary command";
});

// 使用
auto result = commandHandler->executeCommand(123, "TEMP_CMD", "params");

// 注销
commandHandler->unregisterCommand("TEMP_CMD");

错误处理

auto result = commandHandler->executeCommand(clientId, command, params);

if (result.empty()) {
    // 命令不存在
    return "ERROR Command not found: " + command;
}

// 返回命令执行结果
return result;

常用命令示例

GETFILENAME

commandHandler->registerCommand("GETFILENAME",
    [](uint64_t clientId, const std::string& command, const std::string& params) {
        std::string filename = params.empty() ? "default.txt" : params;

        // 读取文件
        std::ifstream file(filename);
        if (!file.is_open()) {
            return "ERROR File not found: " + filename;
        }

        std::string content((std::istreambuf_iterator<char>(file)),
                           std::istreambuf_iterator<char>());
        file.close();

        return "OK " + content;
    },
    "Get file content by filename"
);

LISTFILES

commandHandler->registerCommand("LISTFILES",
    [](uint64_t clientId, const std::string& command, const std::string& params) {
        std::string path = params.empty() ? "." : params;

        DIR* dir = opendir(path.c_str());
        if (!dir) {
            return "ERROR Cannot open directory: " + path;
        }

        std::string result = "OK ";
        struct dirent* entry;
        while ((entry = readdir(dir)) != nullptr) {
            result += std::string(entry->d_name) + " ";
        }
        closedir(dir);

        return result;
    },
    "List files in directory"
);

STATUS

commandHandler->registerCommand("STATUS",
    [](uint64_t clientId, const std::string& command, const std::string& params) {
        return "OK Server is running";
    },
    "Get server status"
);

线程安全

CommandHandler 是线程安全的:

  • 互斥锁: 使用 std::mutex 保护命令注册表
  • 原子操作: 所有操作都是原子的
  • 并发安全: 支持多线程并发调用

注意事项:

  • 命令回调函数内部需要自行处理线程安全
  • 回调函数执行时间会影响整体性能

性能优化

  1. 快速查找: 使用 std::map 存储,查找复杂度 O(log n)
  2. 互斥锁优化: 细粒度锁,只保护必要区域
  3. 命令缓存: 可以在外部缓存常用命令描述

最佳实践

  1. 命令命名: 使用大写字母,语义清晰(GET、SET、DELETE)
  2. 参数格式: 使用空格分隔参数,简单直观
  3. 错误处理: 返回明确的错误信息(空字符串表示命令不存在,错误信息包含在返回字符串中)
  4. 性能考虑: 回调函数执行时间要短,避免阻塞
  5. 资源管理: 回调函数内管理资源,避免泄漏

相关类

主页

API 文档

DMA 模块

DRM 模块

NET 模块

V4L2 模块

V4L2Param 模块

RGA 模块

MPP 模块

Sys 模块

Mouse 模块

Utils 模块

Clone this wiki locally