zeromq / zmqpp:使用消息转发元数据

时间:2016-03-23 14:32:06

标签: c++ zeromq

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

这是一个简单的例子,您可以看到元数据在转发后消失。我不确定:这个元数据是否已经消失了#39;一个bug或一个功能?有没有解决方法?

#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

1 个答案:

答案 0 :(得分:4)

这可能是ZMQ的一个令人困惑的元素。您引用的元数据不是ZMQ消息本身的一部分,它是您收到该消息的连接的一部分。您可以作为该消息的属性访问它的事实是ZMQ有线协议的工件,数据如何从一个套接字传输到另一个套接字,接收套接字需要适当处理该消息的所有信息。 ZMQ消息本身没有“标题”,它只有“帧”,ZMQ套接字知道如何在包含元数据时处理这些帧。

因此,简短的回答是,套接字被提供协商曲线加密的详细信息,发送加密元数据以及消息和接收套接字,使用加密细节设置,知道如何处理该元数据。当您通过没有加密的“普通”套接字发送它时,该元数据被剥离。如果后端的套接字使用加密,它将不再具有应用于前端的元数据,它将具有应用于代理后端套接字的User-Id。

如果要将元数据添加到消息中以便将其发送回后端,则必须直接或在新的消息帧(多部分消息)和句柄中将其附加到消息数据中它本身,它将不再是元数据,它将成为一流的数据。