zeromq / zmqpp :转发带有消息的元数据

zeromq / zmqpp : Forward metadata with message

对于 zmq 和 zmqpp,我正在寻找一种方法来转发元数据及其所属的消息。目标是在拥有安全套接字的负载均衡器后面的工作人员中获得 'User-Id'。

这里是一个简单的例子,你可以看到转发后元数据消失了。我不确定:此元数据 'vanishment' 是错误还是功能?有什么解决方法吗?

#include "zmqpp/zmqpp.hpp"
#include "zmqpp/curve.hpp"

int main()
{
    zmqpp::curve::keypair client_keypair = zmqpp::curve::generate_keypair();
    zmqpp::curve::keypair server_keypair = zmqpp::curve::generate_keypair();

    std::cout << "Client Public Key: " << client_keypair.public_key << std::endl;
    std::cout << "Server Public Key: " << server_keypair.public_key << std::endl;

    zmqpp::context context;

    zmqpp::auth authenticator(context);
    authenticator.set_verbose(false);
    authenticator.configure_curve(client_keypair.public_key);

    zmqpp::socket curve_rep(context, zmqpp::socket_type::rep);
    curve_rep.set(zmqpp::socket_option::curve_server, true);
    curve_rep.set(zmqpp::socket_option::curve_secret_key, server_keypair.secret_key);
    curve_rep.bind("tcp://127.0.0.1:4242");

    zmqpp::socket curve_req(context, zmqpp::socket_type::req);
    curve_req.set(zmqpp::socket_option::curve_server_key, server_keypair.public_key);
    curve_req.set(zmqpp::socket_option::curve_public_key, client_keypair.public_key);
    curve_req.set(zmqpp::socket_option::curve_secret_key, client_keypair.secret_key);
    curve_req.connect("tcp://127.0.0.1:4242");

    zmqpp::socket internal_rep(context, zmqpp::socket_type::rep);
    internal_rep.bind("inproc://clear");

    zmqpp::socket internal_req(context, zmqpp::socket_type::req);
    internal_req.connect("inproc://clear");

    {
        zmqpp::message msg;
        msg << "Hello";
        curve_req.send(msg);
    }

    {
        zmqpp::message msg;
        curve_rep.receive(msg);

        // read User-Id
        std::string user_id;
        std::cout << "- Before forward: ";
        if (msg.get_property("User-Id", user_id))
            std::cout << user_id << std::endl;
        else
            std::cout << "No user id" << std::endl;

        // Forward message
        internal_req.send(msg);
    }

    {
        zmqpp::message msg;
        internal_rep.receive(msg);

        // read User-Id
        std::string user_id;
        std::cout << "- After forward: ";
        if (msg.get_property("User-Id", user_id))
            std::cout << user_id << std::endl;
        else
            std::cout << "No user id" << std::endl;

        std::string content;
        msg >> content;

        std::cout << "- Message: " << content << std::endl;
    }

    {
        zmqpp::message msg;
        msg << "world !";
        internal_rep.send(msg);
    }

    {
        zmqpp::message msg;
        internal_req.receive(msg);
        // Forward message
        curve_rep.send(msg);
    }

    {
        zmqpp::message msg;
        curve_req.receive(msg);
        std::cout << "- Message: " << msg.get<std::string>(0) << std::endl;
    }

    return 0;
}

输出:

Client Public Key: }-}3(fH/r!I/9*tJX0bN/TT]Y2Qd#{IqszYzBX.g
Server Public Key: !@kpBlDrmW@e3jW)q6FumkKGjv@7lU?y9mD(QWd8
auth: Starting ZAP Authentication Server
- Before forward: }-}3(fH/r!I/9*tJX0bN/TT]Y2Qd#{IqszYzBX.g
- After forward: No user id
- Message: Hello
- Message: world !
auth: Shutdown ZAP Authentication Server

这可能是 ZMQ 的一个令人困惑的元素。您所指的元数据不是 ZMQ 消息本身的一部分,它是您接收该消息的连接的一部分。您可以将其作为该消息的 属性 访问这一事实是 ZMQ 有线协议的产物,数据如何从一个套接字传输到另一个套接字以及接收套接字适当处理该消息所需的所有信息. ZMQ 消息本身没有 "headers",它只有 "frames",并且 ZMQ 套接字知道如何在包含元数据时处理这些帧。

所以,简短的回答是,套接字在获得协商 Curve 加密的详细信息后,将加密元数据与消息一起发送,而接收套接字则设置了加密详细信息,知道如何处理该元数据数据。当您通过 "normal" 没有加密的套接字发送它时,该元数据将被删除。如果后端套接字对使用加密,它将不再具有应用于前端的元数据,它将具有应用于代理后端套接字的用户 ID。

如果您想将元数据添加到消息中以便将其发送回后端,则必须将其直接附加到消息数据或在新的消息框架(多部分消息)中附加并自己处理,它将不再是元数据,而是第一个-class 数据。