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/