使用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
答案 0 :(得分:4)
这可能是ZMQ的一个令人困惑的元素。您引用的元数据不是ZMQ消息本身的一部分,它是您收到该消息的连接的一部分。您可以作为该消息的属性访问它的事实是ZMQ有线协议的工件,数据如何从一个套接字传输到另一个套接字,接收套接字需要适当处理该消息的所有信息。 ZMQ消息本身没有“标题”,它只有“帧”,ZMQ套接字知道如何在包含元数据时处理这些帧。
因此,简短的回答是,套接字被提供协商曲线加密的详细信息,发送加密元数据以及消息和接收套接字,使用加密细节设置,知道如何处理该元数据。当您通过没有加密的“普通”套接字发送它时,该元数据被剥离。如果后端的套接字使用加密,它将不再具有应用于前端的元数据,它将具有应用于代理后端套接字的User-Id。
如果要将元数据添加到消息中以便将其发送回后端,则必须直接或在新的消息帧(多部分消息)和句柄中将其附加到消息数据中它本身,它将不再是元数据,它将成为一流的数据。