NAME
zmq_socket_monitor - 监控套接字事件
SYNOPSIS
int zmq_socket_monitor (void '*socket', char '*endpoint', int 'events');
DESCRIPTION
zmq_socket_monitor() 方法允许应用程序线程跟踪 ZeroMQ 套接字上的套接字事件(例如连接)。每次调用此方法都会创建一个 'ZMQ_PAIR' 套接字,并将其绑定到指定的 inproc:// 'endpoint'。要收集套接字事件,你必须创建自己的 'ZMQ_PAIR' 套接字,并连接到该端点。
请注意,还有一个 DRAFT 函数 zmq_socket_monitor_versioned,它允许订阅提供更多信息的事件。调用 zmq_socket_monitor 等同于调用 'zmq_socket_monitor_versioned' 并将 'event_version' 参数设置为 1,错误情况除外。
'events' 参数是一个位掩码,表示你希望监控的套接字事件,参见下方的 'Supported events'。要监控所有事件,使用事件值 ZMQ_EVENT_ALL。注意:随着新事件的添加,此全选值将开始返回它们。依赖于严格固定事件顺序的应用程序不得使用 ZMQ_EVENT_ALL,以保证与未来版本的兼容性。
每个事件作为两个帧发送。第一个帧包含一个事件号(16 位)和一个事件值(32 位),它根据事件号提供额外数据。第二个帧包含一个字符串,它指定了受影响的端点。
The _zmq_socket_monitor()_ method supports only connection-oriented transports, that is, TCP, IPC, and TIPC.
支持的事件
ZMQ_EVENT_CONNECTED
套接字已成功连接到远程对等方。事件值是底层网络套接字的文件描述符 (FD)。警告:不能保证在你的代码收到此事件时,该 FD 仍然有效。
ZMQ_EVENT_CONNECT_DELAYED
套接字上的连接请求正在挂起。事件值未指定。
ZMQ_EVENT_CONNECT_RETRIED
连接请求失败,现在正在重试。事件值是重连间隔(毫秒)。请注意,重连间隔在每次重试时都会重新计算。
ZMQ_EVENT_LISTENING
套接字已成功绑定到网络接口。事件值是底层网络套接字的 FD。警告:不能保证在你的代码收到此事件时,该 FD 仍然有效。
ZMQ_EVENT_BIND_FAILED
套接字无法绑定到给定的接口。事件值是系统 bind 调用产生的 errno。
ZMQ_EVENT_ACCEPTED
套接字已接受来自远程对等方的连接。事件值是底层网络套接字的 FD。警告:不能保证在你的代码收到此事件时,该 FD 仍然有效。
ZMQ_EVENT_ACCEPT_FAILED
套接字拒绝了来自远程对等方的连接。事件值是 accept 调用产生的 errno。
ZMQ_EVENT_CLOSED
套接字已关闭。事件值是该(现已关闭的)网络套接字的 FD。
ZMQ_EVENT_CLOSE_FAILED
套接字关闭失败。事件值是系统调用返回的 errno。请注意,此事件仅在 IPC 传输上发生。
ZMQ_EVENT_DISCONNECTED
套接字意外断开连接。事件值是底层网络套接字的 FD。警告:此套接字将被关闭。
ZMQ_EVENT_MONITOR_STOPPED
此套接字上的监控已结束。
ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
握手期间发生未指定错误。事件值是一个 errno。
ZMQ_EVENT_HANDSHAKE_SUCCEEDED
ZMTP 安全机制握手成功。事件值未指定。
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL
ZMTP 安全机制握手因机制协议错误而失败,错误可能发生在 ZMTP 机制对等方之间,或者发生在机制服务器与 ZAP 处理器之间。这表明在对等方或 ZAP 处理器中存在配置或实现错误。事件值是以下 ZMQ_PROTOCOL_ERROR_* 值之一:ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA
ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
ZMTP 安全机制握手因认证失败而失败。事件值是 ZAP 处理器返回的状态码(例如 300、400 或 500)。
RETURN VALUE
zmq_socket_monitor() 函数成功时返回 0 或更大的值。否则返回 -1 并设置 'errno' 为下方定义的值之一。
ERRORS
- ETERM
-
与指定的 'socket' 关联的 0MQ 'context' 已终止。
- EPROTONOSUPPORT
-
请求的 'transport' 协议不受支持。监控套接字必须使用 inproc:// 传输。
- EINVAL
-
提供的端点无效。
EXAMPLE
// Read one event off the monitor socket; return value and address
// by reference, if not null, and event number by value. Returns -1
// in case of error.
static int
get_monitor_event (void *monitor, int *value, char **address)
{
// First frame in message contains event number and value
zmq_msg_t msg;
zmq_msg_init (&msg);
if (zmq_msg_recv (&msg, monitor, 0) == -1)
return -1; // Interrupted, presumably
assert (zmq_msg_more (&msg));
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
uint16_t event = *(uint16_t *) (data);
if (value)
*value = *(uint32_t *) (data + 2);
// Second frame in message contains event address
zmq_msg_init (&msg);
if (zmq_msg_recv (&msg, monitor, 0) == -1)
return -1; // Interrupted, presumably
assert (!zmq_msg_more (&msg));
if (address) {
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
size_t size = zmq_msg_size (&msg);
*address = (char *) malloc (size + 1);
memcpy (*address, data, size);
(*address)[size] = 0;
}
return event;
}
int main (void)
{
void *ctx = zmq_ctx_new ();
assert (ctx);
// We'll monitor these two sockets
void *client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);
void *server = zmq_socket (ctx, ZMQ_DEALER);
assert (server);
// Socket monitoring only works over inproc://
int rc = zmq_socket_monitor (client, "tcp://127.0.0.1:9999", 0);
assert (rc == -1);
assert (zmq_errno () == EPROTONOSUPPORT);
// Monitor all events on client and server sockets
rc = zmq_socket_monitor (client, "inproc://monitor-client", ZMQ_EVENT_ALL);
assert (rc == 0);
rc = zmq_socket_monitor (server, "inproc://monitor-server", ZMQ_EVENT_ALL);
assert (rc == 0);
// Create two sockets for collecting monitor events
void *client_mon = zmq_socket (ctx, ZMQ_PAIR);
assert (client_mon);
void *server_mon = zmq_socket (ctx, ZMQ_PAIR);
assert (server_mon);
// Connect these to the inproc endpoints so they'll get events
rc = zmq_connect (client_mon, "inproc://monitor-client");
assert (rc == 0);
rc = zmq_connect (server_mon, "inproc://monitor-server");
assert (rc == 0);
// Now do a basic ping test
rc = zmq_bind (server, "tcp://127.0.0.1:9998");
assert (rc == 0);
rc = zmq_connect (client, "tcp://127.0.0.1:9998");
assert (rc == 0);
bounce (client, server);
// Close client and server
close_zero_linger (client);
close_zero_linger (server);
// Now collect and check events from both sockets
int event = get_monitor_event (client_mon, NULL, NULL);
if (event == ZMQ_EVENT_CONNECT_DELAYED)
event = get_monitor_event (client_mon, NULL, NULL);
assert (event == ZMQ_EVENT_CONNECTED);
event = get_monitor_event (client_mon, NULL, NULL);
assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);
event = get_monitor_event (client_mon, NULL, NULL);
assert (event == ZMQ_EVENT_MONITOR_STOPPED);
// This is the flow of server events
event = get_monitor_event (server_mon, NULL, NULL);
assert (event == ZMQ_EVENT_LISTENING);
event = get_monitor_event (server_mon, NULL, NULL);
assert (event == ZMQ_EVENT_ACCEPTED);
event = get_monitor_event (server_mon, NULL, NULL);
assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);
event = get_monitor_event (server_mon, NULL, NULL);
assert (event == ZMQ_EVENT_CLOSED);
event = get_monitor_event (server_mon, NULL, NULL);
assert (event == ZMQ_EVENT_MONITOR_STOPPED);
// Close down the sockets
close_zero_linger (client_mon);
close_zero_linger (server_mon);
zmq_ctx_term (ctx);
return 0 ;
}
SEE ALSO
AUTHORS
此页面由 0MQ 社区编写。要进行修改,请阅读 0MQ 贡献政策:https://zeromq.cn/how-to-contribute/。