1ZBEACON(3) CZMQ Manual ZBEACON(3)
2
3
4
6 zbeacon - Class for LAN discovery and presence
7
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
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
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 * ZMQ_POLL_MSEC);
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 #if defined (__WINDOWS__)
192 zsys_shutdown();
193 #endif
194
195
197 The czmq manual was written by the authors in the AUTHORS file.
198
200 Main web site:
201
202 Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>
203
205 Copyright (c) the Contributors as noted in the AUTHORS file. This file
206 is part of CZMQ, the high-level C binding for 0MQ:
207 http://czmq.zeromq.org. This Source Code Form is subject to the terms
208 of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
209 distributed with this file, You can obtain one at
210 http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
211 distribution.
212
214 1. zeromq-dev@lists.zeromq.org
215 mailto:zeromq-dev@lists.zeromq.org
216
217
218
219CZMQ 4.1.1 07/24/2019 ZBEACON(3)