1ZBEACON(3)                        CZMQ Manual                       ZBEACON(3)
2
3
4

NAME

6       zbeacon - Class for LAN discovery and presence
7

SYNOPSIS

9       //  Create new zbeacon actor instance:
10       //
11       //      zactor_t *beacon = zactor_new (zbeacon, NULL);
12       //
13       //  Destroy zbeacon instance:
14       //
15       //      zactor_destroy (&beacon);
16       //
17       //  Enable verbose logging of commands and activity:
18       //
19       //      zstr_send (beacon, "VERBOSE");
20       //
21       //  Configure beacon to run on specified UDP port, and return the name of
22       //  the host, which can be used as endpoint for incoming connections. To
23       //  force the beacon to operate on a given interface, set the environment
24       //  variable ZSYS_INTERFACE, or call zsys_set_interface() before creating
25       //  the beacon. If the system does not support UDP broadcasts (lacking a
26       //  workable interface), returns an empty hostname:
27       //
28       //      //  Pictures: 's' = C string, 'i' = int
29       //      zsock_send (beacon, "si", "CONFIGURE", port_number);
30       //      char *hostname = zstr_recv (beacon);
31       //
32       //  Start broadcasting a beacon at a specified interval in msec. The beacon
33       //  data can be at most UDP_FRAME_MAX bytes; this constant is defined in
34       //  zsys.h to be 255:
35       //
36       //      //  Pictures: 'b' = byte * data + size_t size
37       //      zsock_send (beacon, "sbi", "PUBLISH", data, size, interval);
38       //
39       //  Stop broadcasting the beacon:
40       //
41       //      zstr_sendx (beacon, "SILENCE", NULL);
42       //
43       //  Start listening to beacons from peers. The filter is used to do a prefix
44       //  match on received beacons, to remove junk. Note that any received data
45       //  that is identical to our broadcast beacon_data is discarded in any case.
46       //  If the filter size is zero, we get all peer beacons:
47       //
48       //      zsock_send (beacon, "sb", "SUBSCRIBE", filter_data, filter_size);
49       //
50       //  Stop listening to other peers
51       //
52       //      zstr_sendx (beacon, "UNSUBSCRIBE", NULL);
53       //
54       //  Receive next beacon from a peer. Received beacons are always a 2-frame
55       //  message containing the ipaddress of the sender, and then the binary
56       //  beacon data as published by the sender:
57       //
58       //      zmsg_t *msg = zmsg_recv (beacon);
59       //
60       //  This is the zbeacon constructor as a zactor_fn:
61       CZMQ_EXPORT void
62           zbeacon (zsock_t *pipe, void *unused);
63
64       //  Self test of this class
65       CZMQ_EXPORT void
66           zbeacon_test (bool verbose);
67       Please add '@interface' section in './../src/zbeacon.c'.
68

DESCRIPTION

70       The zbeacon class implements a peer-to-peer discovery service for local
71       networks. A beacon can broadcast and/or capture service announcements
72       using UDP messages on the local area network. This implementation uses
73       IPv4 UDP broadcasts. You can define the format of your outgoing
74       beacons, and set a filter that validates incoming beacons. Beacons are
75       sent and received asynchronously in the background.
76
77       This class replaces zbeacon_v2, and is meant for applications that use
78       the CZMQ v3 API (meaning, zsock).
79

EXAMPLE

81       From zbeacon_test method.
82
83           //  Test 1 - two beacons, one speaking, one listening
84           //  Create speaker beacon to broadcast our service
85           zactor_t *speaker = zactor_new (zbeacon, NULL);
86           assert (speaker);
87           if (verbose)
88               zstr_sendx (speaker, "VERBOSE", NULL);
89
90           zsock_send (speaker, "si", "CONFIGURE", 9999);
91           char *hostname = zstr_recv (speaker);
92           if (!*hostname) {
93               printf ("OK (skipping test, no UDP broadcasting)\n");
94               zactor_destroy (&speaker);
95               freen (hostname);
96               return;
97           }
98           freen (hostname);
99
100           //  Create listener beacon on port 9999 to lookup service
101           zactor_t *listener = zactor_new (zbeacon, NULL);
102           assert (listener);
103           if (verbose)
104               zstr_sendx (listener, "VERBOSE", NULL);
105           zsock_send (listener, "si", "CONFIGURE", 9999);
106           hostname = zstr_recv (listener);
107           assert (*hostname);
108           freen (hostname);
109
110           //  We will broadcast the magic value 0xCAFE
111           byte announcement [2] = { 0xCA, 0xFE };
112           zsock_send (speaker, "sbi", "PUBLISH", announcement, 2, 100);
113           //  We will listen to anything (empty subscription)
114           zsock_send (listener, "sb", "SUBSCRIBE", "", 0);
115
116           //  Wait for at most 1/2 second if there's no broadcasting
117           zsock_set_rcvtimeo (listener, 500);
118           char *ipaddress = zstr_recv (listener);
119           if (ipaddress) {
120               zframe_t *content = zframe_recv (listener);
121               assert (zframe_size (content) == 2);
122               assert (zframe_data (content) [0] == 0xCA);
123               assert (zframe_data (content) [1] == 0xFE);
124               zframe_destroy (&content);
125               zstr_free (&ipaddress);
126               zstr_sendx (speaker, "SILENCE", NULL);
127           }
128           zactor_destroy (&listener);
129           zactor_destroy (&speaker);
130
131           //  Test subscription filter using a 3-node setup
132           zactor_t *node1 = zactor_new (zbeacon, NULL);
133           assert (node1);
134           zsock_send (node1, "si", "CONFIGURE", 5670);
135           hostname = zstr_recv (node1);
136           assert (*hostname);
137           freen (hostname);
138
139           zactor_t *node2 = zactor_new (zbeacon, NULL);
140           assert (node2);
141           zsock_send (node2, "si", "CONFIGURE", 5670);
142           hostname = zstr_recv (node2);
143           assert (*hostname);
144           freen (hostname);
145
146           zactor_t *node3 = zactor_new (zbeacon, NULL);
147           assert (node3);
148           zsock_send (node3, "si", "CONFIGURE", 5670);
149           hostname = zstr_recv (node3);
150           assert (*hostname);
151           freen (hostname);
152
153           zsock_send (node1, "sbi", "PUBLISH", "NODE/1", 6, 250);
154           zsock_send (node2, "sbi", "PUBLISH", "NODE/2", 6, 250);
155           zsock_send (node3, "sbi", "PUBLISH", "RANDOM", 6, 250);
156           zsock_send (node1, "sb", "SUBSCRIBE", "NODE", 4);
157
158           //  Poll on three API sockets at once
159           zpoller_t *poller = zpoller_new (node1, node2, node3, NULL);
160           assert (poller);
161           int64_t stop_at = zclock_mono () + 1000;
162           while (zclock_mono () < stop_at) {
163               long timeout = (long) (stop_at - zclock_mono ());
164               if (timeout < 0)
165                   timeout = 0;
166               void *which = zpoller_wait (poller, timeout);
167               if (which) {
168                   assert (which == node1);
169                   char *ipaddress, *received;
170                   zstr_recvx (node1, &ipaddress, &received, NULL);
171                   assert (streq (received, "NODE/2"));
172                   zstr_free (&ipaddress);
173                   zstr_free (&received);
174               }
175           }
176           zpoller_destroy (&poller);
177
178           //  Stop listening
179           zstr_sendx (node1, "UNSUBSCRIBE", NULL);
180
181           //  Stop all node broadcasts
182           zstr_sendx (node1, "SILENCE", NULL);
183           zstr_sendx (node2, "SILENCE", NULL);
184           zstr_sendx (node3, "SILENCE", NULL);
185
186           //  Destroy the test nodes
187           zactor_destroy (&node1);
188           zactor_destroy (&node2);
189           zactor_destroy (&node3);
190
191           //  Unset multicast
192           zsys_set_ipv4_mcast_address (NULL);
193
194           //  Test 1 - two beacons, one speaking, one listening
195           //  Create speaker beacon to broadcast our service
196           zactor_t *speaker = zactor_new (zbeacon, NULL);
197           assert (speaker);
198           if (verbose)
199               zstr_sendx (speaker, "VERBOSE", NULL);
200
201           zsock_send (speaker, "si", "CONFIGURE", 9999);
202           char *hostname = zstr_recv (speaker);
203           if (!*hostname) {
204               printf ("OK (skipping test, no UDP broadcasting)\n");
205               zactor_destroy (&speaker);
206               freen (hostname);
207               return;
208           }
209           freen (hostname);
210
211           //  Create listener beacon on port 9999 to lookup service
212           zactor_t *listener = zactor_new (zbeacon, NULL);
213           assert (listener);
214           if (verbose)
215               zstr_sendx (listener, "VERBOSE", NULL);
216           zsock_send (listener, "si", "CONFIGURE", 9999);
217           hostname = zstr_recv (listener);
218           assert (*hostname);
219           freen (hostname);
220
221           //  We will broadcast the magic value 0xCAFE
222           byte announcement [2] = { 0xCA, 0xFE };
223           zsock_send (speaker, "sbi", "PUBLISH", announcement, 2, 100);
224           //  We will listen to anything (empty subscription)
225           zsock_send (listener, "sb", "SUBSCRIBE", "", 0);
226
227           //  Wait for at most 1/2 second if there's no broadcasting
228           zsock_set_rcvtimeo (listener, 500);
229           char *ipaddress = zstr_recv (listener);
230           if (ipaddress) {
231               zframe_t *content = zframe_recv (listener);
232               assert (zframe_size (content) == 2);
233               assert (zframe_data (content) [0] == 0xCA);
234               assert (zframe_data (content) [1] == 0xFE);
235               zframe_destroy (&content);
236               zstr_free (&ipaddress);
237               zstr_sendx (speaker, "SILENCE", NULL);
238           }
239           zactor_destroy (&listener);
240           zactor_destroy (&speaker);
241
242           //  Test subscription filter using a 3-node setup
243           zactor_t *node1 = zactor_new (zbeacon, NULL);
244           assert (node1);
245           zsock_send (node1, "si", "CONFIGURE", 5670);
246           hostname = zstr_recv (node1);
247           assert (*hostname);
248           freen (hostname);
249
250           zactor_t *node2 = zactor_new (zbeacon, NULL);
251           assert (node2);
252           zsock_send (node2, "si", "CONFIGURE", 5670);
253           hostname = zstr_recv (node2);
254           assert (*hostname);
255           freen (hostname);
256
257           zactor_t *node3 = zactor_new (zbeacon, NULL);
258           assert (node3);
259           zsock_send (node3, "si", "CONFIGURE", 5670);
260           hostname = zstr_recv (node3);
261           assert (*hostname);
262           freen (hostname);
263
264           zsock_send (node1, "sbi", "PUBLISH", "NODE/1", 6, 250);
265           zsock_send (node2, "sbi", "PUBLISH", "NODE/2", 6, 250);
266           zsock_send (node3, "sbi", "PUBLISH", "RANDOM", 6, 250);
267           zsock_send (node1, "sb", "SUBSCRIBE", "NODE", 4);
268
269           //  Poll on three API sockets at once
270           zpoller_t *poller = zpoller_new (node1, node2, node3, NULL);
271           assert (poller);
272           int64_t stop_at = zclock_mono () + 1000;
273           while (zclock_mono () < stop_at) {
274               long timeout = (long) (stop_at - zclock_mono ());
275               if (timeout < 0)
276                   timeout = 0;
277               void *which = zpoller_wait (poller, timeout);
278               if (which) {
279                   assert (which == node1);
280                   char *ipaddress, *received;
281                   zstr_recvx (node1, &ipaddress, &received, NULL);
282                   assert (streq (received, "NODE/2"));
283                   zstr_free (&ipaddress);
284                   zstr_free (&received);
285               }
286           }
287           zpoller_destroy (&poller);
288
289           //  Stop listening
290           zstr_sendx (node1, "UNSUBSCRIBE", NULL);
291
292           //  Stop all node broadcasts
293           zstr_sendx (node1, "SILENCE", NULL);
294           zstr_sendx (node2, "SILENCE", NULL);
295           zstr_sendx (node3, "SILENCE", NULL);
296
297           //  Destroy the test nodes
298           zactor_destroy (&node1);
299           zactor_destroy (&node2);
300           zactor_destroy (&node3);
301
302           #if defined (__WINDOWS__)
303           zsys_shutdown();
304           #endif
305
306

AUTHORS

308       The czmq manual was written by the authors in the AUTHORS file.
309

RESOURCES

311       Main web site:
312
313       Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>
314
316       Copyright (c) the Contributors as noted in the AUTHORS file. This file
317       is part of CZMQ, the high-level C binding for 0MQ:
318       http://czmq.zeromq.org. This Source Code Form is subject to the terms
319       of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
320       distributed with this file, You can obtain one at
321       http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
322       distribution.
323

NOTES

325        1. zeromq-dev@lists.zeromq.org
326           mailto:zeromq-dev@lists.zeromq.org
327
328
329
330CZMQ 4.2.1                        07/20/2022                        ZBEACON(3)
Impressum