<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" /> <meta name="generator" content="AsciiDoc 8.6.9" /> <title>zmq_socket_monitor_versioned(3)</title> <style type="text/css"> /* Shared CSS for AsciiDoc xhtml11 and html5 backends */ /* Default font. */ body { font-family: Georgia,serif; } /* Title font. */ h1, h2, h3, h4, h5, h6, div.title, caption.title, thead, p.table.header, #toctitle, #author, #revnumber, #revdate, #revremark, #footer { font-family: Arial,Helvetica,sans-serif; } body { margin: 1em 5% 1em 5%; } a { color: blue; text-decoration: underline; } a:visited { color: fuchsia; } em { font-style: italic; color: navy; } strong { font-weight: bold; color: #083194; } h1, h2, h3, h4, h5, h6 { color: #527bbd; margin-top: 1.2em; margin-bottom: 0.5em; line-height: 1.3; } h1, h2, h3 { border-bottom: 2px solid silver; } h2 { padding-top: 0.5em; } h3 { float: left; } h3 + * { clear: left; } h5 { font-size: 1.0em; } div.sectionbody { margin-left: 0; } hr { border: 1px solid silver; } p { margin-top: 0.5em; margin-bottom: 0.5em; } ul, ol, li > p { margin-top: 0; } ul > li { color: #aaa; } ul > li > * { color: black; } .monospaced, code, pre { font-family: "Courier New", Courier, monospace; font-size: inherit; color: navy; padding: 0; margin: 0; } pre { white-space: pre-wrap; } #author { color: #527bbd; font-weight: bold; font-size: 1.1em; } #email { } #revnumber, #revdate, #revremark { } #footer { font-size: small; border-top: 2px solid silver; padding-top: 0.5em; margin-top: 4.0em; } #footer-text { float: left; padding-bottom: 0.5em; } #footer-badges { float: right; padding-bottom: 0.5em; } #preamble { margin-top: 1.5em; margin-bottom: 1.5em; } div.imageblock, div.exampleblock, div.verseblock, div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock, div.admonitionblock { margin-top: 1.0em; margin-bottom: 1.5em; } div.admonitionblock { margin-top: 2.0em; margin-bottom: 2.0em; margin-right: 10%; color: #606060; } div.content { /* Block element content. */ padding: 0; } /* Block element titles. */ div.title, caption.title { color: #527bbd; font-weight: bold; text-align: left; margin-top: 1.0em; margin-bottom: 0.5em; } div.title + * { margin-top: 0; } td div.title:first-child { margin-top: 0.0em; } div.content div.title:first-child { margin-top: 0.0em; } div.content + div.title { margin-top: 0.0em; } div.sidebarblock > div.content { background: #ffffee; border: 1px solid #dddddd; border-left: 4px solid #f0f0f0; padding: 0.5em; } div.listingblock > div.content { border: 1px solid #dddddd; border-left: 5px solid #f0f0f0; background: #f8f8f8; padding: 0.5em; } div.quoteblock, div.verseblock { padding-left: 1.0em; margin-left: 1.0em; margin-right: 10%; border-left: 5px solid #f0f0f0; color: #888; } div.quoteblock > div.attribution { padding-top: 0.5em; text-align: right; } div.verseblock > pre.content { font-family: inherit; font-size: inherit; } div.verseblock > div.attribution { padding-top: 0.75em; text-align: left; } /* DEPRECATED: Pre version 8.2.7 verse style literal block. */ div.verseblock + div.attribution { text-align: left; } div.admonitionblock .icon { vertical-align: top; font-size: 1.1em; font-weight: bold; text-decoration: underline; color: #527bbd; padding-right: 0.5em; } div.admonitionblock td.content { padding-left: 0.5em; border-left: 3px solid #dddddd; } div.exampleblock > div.content { border-left: 3px solid #dddddd; padding-left: 0.5em; } div.imageblock div.content { padding-left: 0; } span.image img { border-style: none; vertical-align: text-bottom; } a.image:visited { color: white; } dl { margin-top: 0.8em; margin-bottom: 0.8em; } dt { margin-top: 0.5em; margin-bottom: 0; font-style: normal; color: navy; } dd > *:first-child { margin-top: 0.1em; } ul, ol { list-style-position: outside; } ol.arabic { list-style-type: decimal; } ol.loweralpha { list-style-type: lower-alpha; } ol.upperalpha { list-style-type: upper-alpha; } ol.lowerroman { list-style-type: lower-roman; } ol.upperroman { list-style-type: upper-roman; } div.compact ul, div.compact ol, div.compact p, div.compact p, div.compact div, div.compact div { margin-top: 0.1em; margin-bottom: 0.1em; } tfoot { font-weight: bold; } td > div.verse { white-space: pre; } div.hdlist { margin-top: 0.8em; margin-bottom: 0.8em; } div.hdlist tr { padding-bottom: 15px; } dt.hdlist1.strong, td.hdlist1.strong { font-weight: bold; } td.hdlist1 { vertical-align: top; font-style: normal; padding-right: 0.8em; color: navy; } td.hdlist2 { vertical-align: top; } div.hdlist.compact tr { margin: 0; padding-bottom: 0; } .comment { background: yellow; } .footnote, .footnoteref { font-size: 0.8em; } span.footnote, span.footnoteref { vertical-align: super; } #footnotes { margin: 20px 0 20px 0; padding: 7px 0 0 0; } #footnotes div.footnote { margin: 0 0 5px 0; } #footnotes hr { border: none; border-top: 1px solid silver; height: 1px; text-align: left; margin-left: 0; width: 20%; min-width: 100px; } div.colist td { padding-right: 0.5em; padding-bottom: 0.3em; vertical-align: top; } div.colist td img { margin-top: 0.3em; } @media print { #footer-badges { display: none; } } #toc { margin-bottom: 2.5em; } #toctitle { color: #527bbd; font-size: 1.1em; font-weight: bold; margin-top: 1.0em; margin-bottom: 0.1em; } div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 { margin-top: 0; margin-bottom: 0; } div.toclevel2 { margin-left: 2em; font-size: 0.9em; } div.toclevel3 { margin-left: 4em; font-size: 0.9em; } div.toclevel4 { margin-left: 6em; font-size: 0.9em; } span.aqua { color: aqua; } span.black { color: black; } span.blue { color: blue; } span.fuchsia { color: fuchsia; } span.gray { color: gray; } span.green { color: green; } span.lime { color: lime; } span.maroon { color: maroon; } span.navy { color: navy; } span.olive { color: olive; } span.purple { color: purple; } span.red { color: red; } span.silver { color: silver; } span.teal { color: teal; } span.white { color: white; } span.yellow { color: yellow; } span.aqua-background { background: aqua; } span.black-background { background: black; } span.blue-background { background: blue; } span.fuchsia-background { background: fuchsia; } span.gray-background { background: gray; } span.green-background { background: green; } span.lime-background { background: lime; } span.maroon-background { background: maroon; } span.navy-background { background: navy; } span.olive-background { background: olive; } span.purple-background { background: purple; } span.red-background { background: red; } span.silver-background { background: silver; } span.teal-background { background: teal; } span.white-background { background: white; } span.yellow-background { background: yellow; } span.big { font-size: 2em; } span.small { font-size: 0.6em; } span.underline { text-decoration: underline; } span.overline { text-decoration: overline; } span.line-through { text-decoration: line-through; } div.unbreakable { page-break-inside: avoid; } /* * xhtml11 specific * * */ div.tableblock { margin-top: 1.0em; margin-bottom: 1.5em; } div.tableblock > table { border: 3px solid #527bbd; } thead, p.table.header { font-weight: bold; color: #527bbd; } p.table { margin-top: 0; } /* Because the table frame attribute is overriden by CSS in most browsers. */ div.tableblock > table[frame="void"] { border-style: none; } div.tableblock > table[frame="hsides"] { border-left-style: none; border-right-style: none; } div.tableblock > table[frame="vsides"] { border-top-style: none; border-bottom-style: none; } /* * html5 specific * * */ table.tableblock { margin-top: 1.0em; margin-bottom: 1.5em; } thead, p.tableblock.header { font-weight: bold; color: #527bbd; } p.tableblock { margin-top: 0; } table.tableblock { border-width: 3px; border-spacing: 0px; border-style: solid; border-color: #527bbd; border-collapse: collapse; } th.tableblock, td.tableblock { border-width: 1px; padding: 4px; border-style: solid; border-color: #527bbd; } table.tableblock.frame-topbot { border-left-style: hidden; border-right-style: hidden; } table.tableblock.frame-sides { border-top-style: hidden; border-bottom-style: hidden; } table.tableblock.frame-none { border-style: hidden; } th.tableblock.halign-left, td.tableblock.halign-left { text-align: left; } th.tableblock.halign-center, td.tableblock.halign-center { text-align: center; } th.tableblock.halign-right, td.tableblock.halign-right { text-align: right; } th.tableblock.valign-top, td.tableblock.valign-top { vertical-align: top; } th.tableblock.valign-middle, td.tableblock.valign-middle { vertical-align: middle; } th.tableblock.valign-bottom, td.tableblock.valign-bottom { vertical-align: bottom; } /* * manpage specific * * */ body.manpage h1 { padding-top: 0.5em; padding-bottom: 0.5em; border-top: 2px solid silver; border-bottom: 2px solid silver; } body.manpage h2 { border-style: none; } body.manpage div.sectionbody { margin-left: 3em; } @media print { body.manpage div#toc { display: none; } } </style> <script type="text/javascript"> /*<![CDATA[*/ var asciidoc = { // Namespace. ///////////////////////////////////////////////////////////////////// // Table Of Contents generator ///////////////////////////////////////////////////////////////////// /* Author: Mihai Bazon, September 2002 * http://students.infoiasi.ro/~mishoo * * Table Of Content generator * Version: 0.4 * * Feel free to use this script under the terms of the GNU General Public * License, as long as you do not remove or alter this notice. */ /* modified by Troy D. Hanson, September 2006. License: GPL */ /* modified by Stuart Rackham, 2006, 2009. License: GPL */ // toclevels = 1..4. toc: function (toclevels) { function getText(el) { var text = ""; for (var i = el.firstChild; i != null; i = i.nextSibling) { if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants. text += i.data; else if (i.firstChild != null) text += getText(i); } return text; } function TocEntry(el, text, toclevel) { this.element = el; this.text = text; this.toclevel = toclevel; } function tocEntries(el, toclevels) { var result = new Array; var re = new RegExp('[hH]([1-'+(toclevels+1)+'])'); // Function that scans the DOM tree for header elements (the DOM2 // nodeIterator API would be a better technique but not supported by all // browsers). var iterate = function (el) { for (var i = el.firstChild; i != null; i = i.nextSibling) { if (i.nodeType == 1 /* Node.ELEMENT_NODE */) { var mo = re.exec(i.tagName); if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") { result[result.length] = new TocEntry(i, getText(i), mo[1]-1); } iterate(i); } } } iterate(el); return result; } var toc = document.getElementById("toc"); if (!toc) { return; } // Delete existing TOC entries in case we're reloading the TOC. var tocEntriesToRemove = []; var i; for (i = 0; i < toc.childNodes.length; i++) { var entry = toc.childNodes[i]; if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") && entry.getAttribute("class").match(/^toclevel/)) tocEntriesToRemove.push(entry); } for (i = 0; i < tocEntriesToRemove.length; i++) { toc.removeChild(tocEntriesToRemove[i]); } // Rebuild TOC entries. var entries = tocEntries(document.getElementById("content"), toclevels); for (var i = 0; i < entries.length; ++i) { var entry = entries[i]; if (entry.element.id == "") entry.element.id = "_toc_" + i; var a = document.createElement("a"); a.href = "#" + entry.element.id; a.appendChild(document.createTextNode(entry.text)); var div = document.createElement("div"); div.appendChild(a); div.className = "toclevel" + entry.toclevel; toc.appendChild(div); } if (entries.length == 0) toc.parentNode.removeChild(toc); }, ///////////////////////////////////////////////////////////////////// // Footnotes generator ///////////////////////////////////////////////////////////////////// /* Based on footnote generation code from: * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html */ footnotes: function () { // Delete existing footnote entries in case we're reloading the footnodes. var i; var noteholder = document.getElementById("footnotes"); if (!noteholder) { return; } var entriesToRemove = []; for (i = 0; i < noteholder.childNodes.length; i++) { var entry = noteholder.childNodes[i]; if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote") entriesToRemove.push(entry); } for (i = 0; i < entriesToRemove.length; i++) { noteholder.removeChild(entriesToRemove[i]); } // Rebuild footnote entries. var cont = document.getElementById("content"); var spans = cont.getElementsByTagName("span"); var refs = {}; var n = 0; for (i=0; i<spans.length; i++) { if (spans[i].className == "footnote") { n++; var note = spans[i].getAttribute("data-note"); if (!note) { // Use [\s\S] in place of . so multi-line matches work. // Because JavaScript has no s (dotall) regex flag. note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1]; spans[i].innerHTML = "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n + "' title='View footnote' class='footnote'>" + n + "</a>]"; spans[i].setAttribute("data-note", note); } noteholder.innerHTML += "<div class='footnote' id='_footnote_" + n + "'>" + "<a href='#_footnoteref_" + n + "' title='Return to text'>" + n + "</a>. " + note + "</div>"; var id =spans[i].getAttribute("id"); if (id != null) refs["#"+id] = n; } } if (n == 0) noteholder.parentNode.removeChild(noteholder); else { // Process footnoterefs. for (i=0; i<spans.length; i++) { if (spans[i].className == "footnoteref") { var href = spans[i].getElementsByTagName("a")[0].getAttribute("href"); href = href.match(/#.*/)[0]; // Because IE return full URL. n = refs[href]; spans[i].innerHTML = "[<a href='#_footnote_" + n + "' title='View footnote' class='footnote'>" + n + "</a>]"; } } } }, install: function(toclevels) { var timerId; function reinstall() { asciidoc.footnotes(); if (toclevels) { asciidoc.toc(toclevels); } } function reinstallAndRemoveTimer() { clearInterval(timerId); reinstall(); } timerId = setInterval(reinstall, 500); if (document.addEventListener) document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false); else window.onload = reinstallAndRemoveTimer; } } asciidoc.install(); /*]]>*/ </script> </head> <body class="manpage"> <div id="header"> <h1> zmq_socket_monitor_versioned(3) Manual Page </h1> <h2>NAME</h2> <div class="sectionbody"> <p>zmq_socket_monitor_versioned - monitor socket events </p> </div> </div> <div id="content"> <div class="sect1"> <h2 id="_synopsis">SYNOPSIS</h2> <div class="sectionbody"> <div class="paragraph"><p><strong>int zmq_socket_monitor_versioned (void <em>*socket</em>, char <em>*endpoint</em>, uint64_t <em>events</em>, int <em>event_version</em>, int <em>type</em>);</strong></p></div> <div class="paragraph"><p><strong>int zmq_socket_monitor_pipes_stats (void <em>*socket</em>);</strong></p></div> </div> </div> <div class="sect1"> <h2 id="_description">DESCRIPTION</h2> <div class="sectionbody"> <div class="paragraph"><p>The <em>zmq_socket_monitor_versioned()</em> method lets an application thread track socket events (like connects) on a ZeroMQ socket. Each call to this method creates a <em>ZMQ_PAIR</em> socket and binds that to the specified inproc:// <em>endpoint</em>. To collect the socket events, you must create your own <em>ZMQ_PAIR</em> socket, and connect that to the endpoint.</p></div> <div class="paragraph"><p>The <em>events</em> argument is a bitmask of the socket events you wish to monitor, see <em>Supported events</em> below. To monitor all events for a version, use the event value ZMQ_EVENT_ALL_V<version>, e.g. ZMQ_EVENT_ALL_V1. For non-DRAFT event versions, this value will not change in the future, so new event types will only be added in new versions (note that this is a change over zmq_socket_monitor and the unversioned ZMQ_EVENT_ALL).</p></div> <div class="paragraph"><p>Note that event_version 2 is currently in DRAFT mode. The protocol may be changed at any time for event_versions in DRAFT.</p></div> <div class="paragraph"><p>ZMQ_CURRENT_EVENT_VERSION and ZMQ_CURRENT_EVENT_VERSION_DRAFT are always defined to the most recent stable or DRAFT event version, which are currently 1 resp. 2</p></div> <div class="paragraph"><p>This page describes the protocol for <em>event_version</em> 2 only. For the protocol used with <em>event_version</em> 1, please refer to <a href="zmq_socket_monitor.html">zmq_socket_monitor(3)</a>.</p></div> <div class="paragraph"><p>Each event is sent in multiple frames. The first frame contains an event number (64 bits). The number and content of further frames depend on this event number.</p></div> <div class="paragraph"><p>Unless it is specified differently, the second frame contains the number of value frames that will follow it as a 64 bits integer. The third frame to N-th frames contain an event value (64 bits) that provides additional data according to the event number. Each event type might have a different number of values. The second-to-last and last frames contain strings that specifies the affected connection or endpoint. The former frame contains a string denoting the local endpoint, while the latter frame contains a string denoting the remote endpoint. Either of these may be empty, depending on the event type and whether the connection uses a bound or connected local endpoint.</p></div> <div class="paragraph"><p>Note that the format of the second and further frames, and also the number of frames, may be different for events added in the future.</p></div> <div class="paragraph"><p>The <em>type</em> argument is used to specify the type of the monitoring socket. Supported types are <em>ZMQ_PAIR</em>, <em>ZMQ_PUB</em> and <em>ZMQ_PUSH</em>. Note that consumers of the events will have to be compatible with the socket type, for instance a monitoring socket of type <em>ZMQ_PUB</em> will require consumers of type <em>ZMQ_SUB</em>. In the case that the monitoring socket type is of <em>ZMQ_PUB</em>, the multipart message topic is the event number, thus consumers should subscribe to the events they want to receive.</p></div> <div class="paragraph"><p>The <em>zmq_socket_monitor_pipes_stats()</em> method triggers an event of type ZMQ_EVENT_PIPES_STATS for each connected peer of the monitored socket. NOTE: <em>zmq_socket_monitor_pipes_stats()</em> is in DRAFT state.</p></div> <div class="listingblock"> <div class="content"> <pre><code>Monitoring events are only generated by some transports: At the moment these are SOCKS, TCP, IPC, and TIPC. Note that it is not an error to call 'zmq_socket_monitor_versioned' on a socket that is connected or bound to some other transport, as this may not be known at the time 'zmq_socket_monitor_versioned' is called. Also, a socket can be connected/bound to multiple endpoints using different transports.</code></pre> </div></div> <div class="paragraph"><p>Supported events (v1)</p></div> <div class="listingblock"> <div class="content"> <pre><code>ZMQ_EVENT_CONNECTED ~~~~~~~~~~~~~~~~~~~ The socket has successfully connected to a remote peer. The event value is the file descriptor (FD) of the underlying network socket. Warning: there is no guarantee that the FD is still valid by the time your code receives this event. ZMQ_EVENT_CONNECT_DELAYED ~~~~~~~~~~~~~~~~~~~~~~~~~ A connect request on the socket is pending. The event value is unspecified. ZMQ_EVENT_CONNECT_RETRIED ~~~~~~~~~~~~~~~~~~~~~~~~~ A connect request failed, and is now being retried. The event value is the reconnect interval in milliseconds. Note that the reconnect interval is recalculated for each retry. ZMQ_EVENT_LISTENING ~~~~~~~~~~~~~~~~~~~ The socket was successfully bound to a network interface. The event value is the FD of the underlying network socket. Warning: there is no guarantee that the FD is still valid by the time your code receives this event. ZMQ_EVENT_BIND_FAILED ~~~~~~~~~~~~~~~~~~~~~ The socket could not bind to a given interface. The event value is the errno generated by the system bind call. ZMQ_EVENT_ACCEPTED ~~~~~~~~~~~~~~~~~~ The socket has accepted a connection from a remote peer. The event value is the FD of the underlying network socket. Warning: there is no guarantee that the FD is still valid by the time your code receives this event. ZMQ_EVENT_ACCEPT_FAILED ~~~~~~~~~~~~~~~~~~~~~~~ The socket has rejected a connection from a remote peer. The event value is the errno generated by the accept call. ZMQ_EVENT_CLOSED ~~~~~~~~~~~~~~~~ The socket was closed. The event value is the FD of the (now closed) network socket. ZMQ_EVENT_CLOSE_FAILED ~~~~~~~~~~~~~~~~~~~~~~ The socket close failed. The event value is the errno returned by the system call. Note that this event occurs only on IPC transports. ZMQ_EVENT_DISCONNECTED ~~~~~~~~~~~~~~~~~~~~~~ The socket was disconnected unexpectedly. The event value is the FD of the underlying network socket. Warning: this socket will be closed. ZMQ_EVENT_MONITOR_STOPPED ~~~~~~~~~~~~~~~~~~~~~~~~~ Monitoring on this socket ended. ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unspecified error during handshake. The event value is an errno. ZMQ_EVENT_HANDSHAKE_SUCCEEDED ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The ZMTP security mechanism handshake succeeded. The event value is unspecified. ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The ZMTP security mechanism handshake failed due to some mechanism protocol error, either between the ZMTP mechanism peers, or between the mechanism server and the ZAP handler. This indicates a configuration or implementation error in either peer resp. the ZAP handler. The event value is one of the ZMQ_PROTOCOL_ERROR_* values: 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The ZMTP security mechanism handshake failed due to an authentication failure. The event value is the status code returned by the ZAP handler (i.e. 300, 400 or 500).</code></pre> </div></div> <div class="paragraph"><p>Supported events (v2)</p></div> <div class="listingblock"> <div class="content"> <pre><code>ZMQ_EVENT_PIPE_STATS ~~~~~~~~~~~~~~~~~~~~ This event provides two values, the number of messages in each of the two queues associated with the returned endpoint (respectively egress and ingress). This event only triggers after calling the function _zmq_socket_monitor_pipes_stats()_. NOTE: this measurement is asynchronous, so by the time the message is received the internal state might have already changed. NOTE: when the monitored socket and the monitor are not used in a poll, the event might not be delivered until an API has been called on the monitored socket, like zmq_getsockopt for example (the option is irrelevant). NOTE: in DRAFT state, not yet available in stable releases. RETURN VALUE</code></pre> </div></div> <div class="paragraph"><p>The <em>zmq_socket_monitor()</em> and <em>zmq_socket_monitor_pipes_stats()</em> functions return a value of 0 or greater if successful. Otherwise they return <code>-1</code> and set <em>errno</em> to one of the values defined below.</p></div> </div> </div> <div class="sect1"> <h2 id="_errors_em_zmq_socket_monitor_em">ERRORS - <em>zmq_socket_monitor()</em></h2> <div class="sectionbody"> <div class="dlist"><dl> <dt class="hdlist1"> <strong>ETERM</strong> </dt> <dd> <p> The ØMQ <em>context</em> associated with the specified <em>socket</em> was terminated. </p> </dd> <dt class="hdlist1"> <strong>EPROTONOSUPPORT</strong> </dt> <dd> <p> The transport protocol of the monitor <em>endpoint</em> is not supported. Monitor sockets are required to use the inproc:// transport. </p> </dd> <dt class="hdlist1"> <strong>EINVAL</strong> </dt> <dd> <p> The monitor <em>endpoint</em> supplied does not exist or the specified socket <em>type</em> is not supported. </p> </dd> </dl></div> </div> </div> <div class="sect1"> <h2 id="_errors_em_zmq_socket_monitor_pipes_stats_em">ERRORS - <em>zmq_socket_monitor_pipes_stats()</em></h2> <div class="sectionbody"> <div class="dlist"><dl> <dt class="hdlist1"> <strong>ENOTSOCK</strong> </dt> <dd> <p> The <em>socket</em> parameter was not a valid ØMQ socket. </p> </dd> <dt class="hdlist1"> <strong>EINVAL</strong> </dt> <dd> <p> The socket did not have monitoring enabled. </p> </dd> <dt class="hdlist1"> <strong>EAGAIN</strong> </dt> <dd> <p> The monitored socket did not have any connections to monitor yet. </p> </dd> </dl></div> </div> </div> <div class="sect1"> <h2 id="_example">EXAMPLE</h2> <div class="sectionbody"> <div class="listingblock"> <div class="title">Monitoring client and server sockets</div> <div class="content"> <pre><code>// Read one event off the monitor socket; return values and addresses // by reference, if not null, and event number by value. Returns -1 // in case of error. static uint64_t get_monitor_event (void *monitor, uint64_t *value, char **local_address, char **remote_address) { // First frame in message contains event number 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)); uint64_t event; memcpy (&event, zmq_msg_data (&msg), sizeof (event)); zmq_msg_close (&msg); // Second frame in message contains the number of values zmq_msg_init (&msg); if (zmq_msg_recv (&msg, monitor, 0) == -1) return -1; // Interrupted, presumably assert (zmq_msg_more (&msg)); uint64_t value_count; memcpy (&value_count, zmq_msg_data (&msg), sizeof (value_count)); zmq_msg_close (&msg); for (uint64_t i = 0; i < value_count; ++i) { // Subsequent frames in message contain event values zmq_msg_init (&msg); if (zmq_msg_recv (&msg, monitor, 0) == -1) return -1; // Interrupted, presumably assert (zmq_msg_more (&msg)); if (value_ && value_ + i) memcpy (value_ + i, zmq_msg_data (&msg), sizeof (*value_)); zmq_msg_close (&msg); } // Second-to-last frame in message contains local address zmq_msg_init (&msg); if (zmq_msg_recv (&msg, monitor, 0) == -1) return -1; // Interrupted, presumably assert (zmq_msg_more (&msg)); if (local_address_) { uint8_t *data = (uint8_t *) zmq_msg_data (&msg); size_t size = zmq_msg_size (&msg); *local_address_ = (char *) malloc (size + 1); memcpy (*local_address_, data, size); (*local_address_)[size] = 0; } zmq_msg_close (&msg); // Last frame in message contains remote address zmq_msg_init (&msg); if (zmq_msg_recv (&msg, monitor, 0) == -1) return -1; // Interrupted, presumably assert (!zmq_msg_more (&msg)); if (remote_address_) { uint8_t *data = (uint8_t *) zmq_msg_data (&msg); size_t size = zmq_msg_size (&msg); *remote_address_ = (char *) malloc (size + 1); memcpy (*remote_address_, data, size); (*remote_address_)[size] = 0; } zmq_msg_close (&msg); 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_versioned (client, "tcp://127.0.0.1:9999", 0, 2); assert (rc == -1); assert (zmq_errno () == EPROTONOSUPPORT); // Monitor all events on client and server sockets rc = zmq_socket_monitor_versioned (client, "inproc://monitor-client", ZMQ_EVENT_ALL, 2); assert (rc == 0); rc = zmq_socket_monitor_versioned (server, "inproc://monitor-server", ZMQ_EVENT_ALL, 2); 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_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_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 ; }</code></pre> </div></div> </div> </div> <div class="sect1"> <h2 id="_see_also">SEE ALSO</h2> <div class="sectionbody"> <div class="paragraph"><p><a href="zmq.html">zmq(7)</a></p></div> </div> </div> <div class="sect1"> <h2 id="_authors">AUTHORS</h2> <div class="sectionbody"> <div class="paragraph"><p>This page was written by the ØMQ community. To make a change please read the ØMQ Contribution Policy at <a href="http://www.zeromq.org/docs:contributing">http://www.zeromq.org/docs:contributing</a>.</p></div> </div> </div> </div> <div id="footnotes"><hr /></div> <div id="footer"> <div id="footer-text"> ØMQ 4.3.2<br /> Last updated 2019-07-08 16:19:27 UTC </div> </div> </body> </html>