zmq 1.0 → 2.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/Makefile +181 -0
- data/{ext/zmq/extconf.rb → extconf.rb} +8 -12
- data/rbzmq.c +1365 -0
- metadata +34 -30
- data/COPYING +0 -674
- data/ChangeLog +0 -1
- data/README +0 -1
- data/ext/zmq/zmq.cpp +0 -200
- data/lib/zmq.rb +0 -1
- data/test/all_tests.rb +0 -3
- data/test/test_helper.rb +0 -7
- data/test/unit/zmq_tests.rb +0 -9
data/rbzmq.c
ADDED
@@ -0,0 +1,1365 @@
|
|
1
|
+
/*
|
2
|
+
Copyright (c) 2007-2010 iMatix Corporation
|
3
|
+
|
4
|
+
This file is part of 0MQ.
|
5
|
+
|
6
|
+
0MQ is free software; you can redistribute it and/or modify it under
|
7
|
+
the terms of the Lesser GNU General Public License as published by
|
8
|
+
the Free Software Foundation; either version 3 of the License, or
|
9
|
+
(at your option) any later version.
|
10
|
+
|
11
|
+
0MQ is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
Lesser GNU General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the Lesser GNU General Public License
|
17
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
*/
|
19
|
+
|
20
|
+
#include <assert.h>
|
21
|
+
#include <string.h>
|
22
|
+
#include <ruby.h>
|
23
|
+
#ifdef HAVE_RUBY_IO_H
|
24
|
+
#include <ruby/io.h>
|
25
|
+
#else
|
26
|
+
#include <rubyio.h>
|
27
|
+
#endif
|
28
|
+
#include <zmq.h>
|
29
|
+
|
30
|
+
#if defined _MSC_VER
|
31
|
+
#ifndef int8_t
|
32
|
+
typedef __int8 int8_t;
|
33
|
+
#endif
|
34
|
+
#ifndef int16_t
|
35
|
+
typedef __int16 int16_t;
|
36
|
+
#endif
|
37
|
+
#ifndef int32_t
|
38
|
+
typedef __int32 int32_t;
|
39
|
+
#endif
|
40
|
+
#ifndef int64_t
|
41
|
+
typedef __int64 int64_t;
|
42
|
+
#endif
|
43
|
+
#ifndef uint8_t
|
44
|
+
typedef unsigned __int8 uint8_t;
|
45
|
+
#endif
|
46
|
+
#ifndef uint16_t
|
47
|
+
typedef unsigned __int16 uint16_t;
|
48
|
+
#endif
|
49
|
+
#ifndef uint32_t
|
50
|
+
typedef unsigned __int32 uint32_t;
|
51
|
+
#endif
|
52
|
+
#ifndef uint64_t
|
53
|
+
typedef unsigned __int64 uint64_t;
|
54
|
+
#endif
|
55
|
+
#else
|
56
|
+
#include <stdint.h>
|
57
|
+
#endif
|
58
|
+
|
59
|
+
#define Check_Socket(__socket) \
|
60
|
+
do {\
|
61
|
+
if ((__socket) == NULL)\
|
62
|
+
rb_raise (rb_eIOError, "closed socket");\
|
63
|
+
} while(0)
|
64
|
+
|
65
|
+
VALUE socket_type;
|
66
|
+
|
67
|
+
/*
|
68
|
+
* Document-class: ZMQ
|
69
|
+
*
|
70
|
+
* Ruby interface to the zeromq messaging library.
|
71
|
+
*/
|
72
|
+
|
73
|
+
/*
|
74
|
+
* call-seq:
|
75
|
+
* ZMQ.version() -> [major, minor, patch]
|
76
|
+
*
|
77
|
+
* Returns the version of the zeromq library.
|
78
|
+
*/
|
79
|
+
static VALUE module_version (VALUE self_)
|
80
|
+
{
|
81
|
+
int major, minor, patch;
|
82
|
+
|
83
|
+
zmq_version(&major, &minor, &patch);
|
84
|
+
|
85
|
+
return rb_ary_new3 (3, INT2NUM (major), INT2NUM (minor), INT2NUM (patch));
|
86
|
+
}
|
87
|
+
|
88
|
+
/*
|
89
|
+
* Document-class: ZMQ::Context
|
90
|
+
*
|
91
|
+
* ZeroMQ library context.
|
92
|
+
*/
|
93
|
+
|
94
|
+
static void context_free (void *ctx)
|
95
|
+
{
|
96
|
+
if (ctx) {
|
97
|
+
int rc = zmq_term (ctx);
|
98
|
+
assert (rc == 0);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
static VALUE context_alloc (VALUE class_)
|
103
|
+
{
|
104
|
+
return rb_data_object_alloc (class_, NULL, 0, context_free);
|
105
|
+
}
|
106
|
+
|
107
|
+
/*
|
108
|
+
* Document-method: new
|
109
|
+
*
|
110
|
+
* call-seq:
|
111
|
+
* new(io_threads=1)
|
112
|
+
*
|
113
|
+
* Initializes a new 0MQ context. The io_threads argument specifies the size
|
114
|
+
* of the 0MQ thread pool to handle I/O operations. If your application is
|
115
|
+
* using only the _inproc_ transport for you may set this to zero; otherwise,
|
116
|
+
* set it to at least one.
|
117
|
+
*/
|
118
|
+
|
119
|
+
static VALUE context_initialize (int argc_, VALUE* argv_, VALUE self_)
|
120
|
+
{
|
121
|
+
VALUE io_threads;
|
122
|
+
rb_scan_args (argc_, argv_, "01", &io_threads);
|
123
|
+
|
124
|
+
assert (!DATA_PTR (self_));
|
125
|
+
void *ctx = zmq_init (NIL_P (io_threads) ? 1 : NUM2INT (io_threads));
|
126
|
+
if (!ctx) {
|
127
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ()));
|
128
|
+
return Qnil;
|
129
|
+
}
|
130
|
+
|
131
|
+
DATA_PTR (self_) = (void*) ctx;
|
132
|
+
return self_;
|
133
|
+
}
|
134
|
+
|
135
|
+
/*
|
136
|
+
* call-seq:
|
137
|
+
* zmq.close() -> nil
|
138
|
+
*
|
139
|
+
* Terminates the 0MQ context. If there are no longer any sockets open within
|
140
|
+
* context at the time zmq_term() is called then context shall be shut down and
|
141
|
+
* all associated resources shall be released immediately.
|
142
|
+
*
|
143
|
+
* Otherwise, the following applies:
|
144
|
+
* - The close() function shall return immediately.
|
145
|
+
* - Any blocking operations currently in progress on sockets open within
|
146
|
+
* context shall return immediately with an error code of ETERM.
|
147
|
+
* - With the exception of ZMQ::Socket#close(), any further operations on
|
148
|
+
* sockets open within context shall fail with an error code of ETERM.
|
149
|
+
* - The actual shutdown of context, and release of any associated resources, shall
|
150
|
+
* be delayed until the last socket within it is closed with ZMQ::Socket#close().
|
151
|
+
*/
|
152
|
+
static VALUE context_close (VALUE self_)
|
153
|
+
{
|
154
|
+
void * ctx = NULL;
|
155
|
+
Data_Get_Struct (self_, void, ctx);
|
156
|
+
|
157
|
+
if (ctx != NULL) {
|
158
|
+
int rc = zmq_term (ctx);
|
159
|
+
assert (rc == 0);
|
160
|
+
|
161
|
+
DATA_PTR (self_) = NULL;
|
162
|
+
}
|
163
|
+
|
164
|
+
return Qnil;
|
165
|
+
}
|
166
|
+
|
167
|
+
struct poll_state {
|
168
|
+
int event;
|
169
|
+
int nitems;
|
170
|
+
zmq_pollitem_t *items;
|
171
|
+
VALUE io_objects;
|
172
|
+
};
|
173
|
+
|
174
|
+
typedef VALUE(*iterfunc)(ANYARGS);
|
175
|
+
|
176
|
+
static VALUE poll_add_item(VALUE io_, void *ps_) {
|
177
|
+
struct poll_state *state = (struct poll_state *)ps_;
|
178
|
+
|
179
|
+
long i;
|
180
|
+
|
181
|
+
for (i = 0; i < RARRAY_LEN (state->io_objects); i++) {
|
182
|
+
if (RARRAY_PTR (state->io_objects)[i] == io_) {
|
183
|
+
#ifdef HAVE_RUBY_IO_H
|
184
|
+
state->items[i].events |= state->event;
|
185
|
+
return Qnil;
|
186
|
+
#else
|
187
|
+
if (CLASS_OF (io_) == socket_type) {
|
188
|
+
state->items[i].events |= state->event;
|
189
|
+
return Qnil;
|
190
|
+
}
|
191
|
+
|
192
|
+
OpenFile *fptr;
|
193
|
+
GetOpenFile (io_, fptr);
|
194
|
+
|
195
|
+
if (state->event == ZMQ_POLLOUT &&
|
196
|
+
GetWriteFile (fptr) != NULL &&
|
197
|
+
fileno (GetWriteFile (fptr)) != state->items[i].fd) {
|
198
|
+
break;
|
199
|
+
}
|
200
|
+
else {
|
201
|
+
state->items[i].events |= state->event;
|
202
|
+
return Qnil;
|
203
|
+
}
|
204
|
+
#endif
|
205
|
+
}
|
206
|
+
}
|
207
|
+
|
208
|
+
/* Not found in array. Add a new poll item. */
|
209
|
+
rb_ary_push (state->io_objects, io_);
|
210
|
+
|
211
|
+
zmq_pollitem_t *item = &state->items[state->nitems];
|
212
|
+
state->nitems++;
|
213
|
+
|
214
|
+
item->events = state->event;
|
215
|
+
|
216
|
+
if (CLASS_OF (io_) == socket_type) {
|
217
|
+
item->socket = DATA_PTR (io_);
|
218
|
+
item->fd = -1;
|
219
|
+
}
|
220
|
+
else {
|
221
|
+
item->socket = NULL;
|
222
|
+
|
223
|
+
#ifdef HAVE_RUBY_IO_H
|
224
|
+
rb_io_t *fptr;
|
225
|
+
|
226
|
+
GetOpenFile (io_, fptr);
|
227
|
+
item->fd = fileno (rb_io_stdio_file (fptr));
|
228
|
+
#else
|
229
|
+
OpenFile *fptr;
|
230
|
+
|
231
|
+
GetOpenFile (io_, fptr);
|
232
|
+
|
233
|
+
if (state->event == ZMQ_POLLIN && GetReadFile (fptr) != NULL) {
|
234
|
+
item->fd = fileno (GetReadFile (fptr));
|
235
|
+
}
|
236
|
+
else if (state->event == ZMQ_POLLOUT && GetWriteFile (fptr) != NULL) {
|
237
|
+
item->fd = fileno (GetWriteFile (fptr));
|
238
|
+
}
|
239
|
+
else if (state->event == ZMQ_POLLERR) {
|
240
|
+
if (GetReadFile(fptr) != NULL)
|
241
|
+
item->fd = fileno (GetReadFile (fptr));
|
242
|
+
else
|
243
|
+
item->fd = fileno (GetWriteFile (fptr));
|
244
|
+
}
|
245
|
+
#endif
|
246
|
+
}
|
247
|
+
|
248
|
+
return Qnil;
|
249
|
+
}
|
250
|
+
|
251
|
+
#ifdef HAVE_RUBY_INTERN_H
|
252
|
+
|
253
|
+
struct zmq_poll_args {
|
254
|
+
zmq_pollitem_t *items;
|
255
|
+
int nitems;
|
256
|
+
long timeout_usec;
|
257
|
+
int rc;
|
258
|
+
};
|
259
|
+
|
260
|
+
static VALUE zmq_poll_blocking (void* args_)
|
261
|
+
{
|
262
|
+
struct zmq_poll_args *poll_args = (struct zmq_poll_args *)args_;
|
263
|
+
|
264
|
+
poll_args->rc = zmq_poll (poll_args->items, poll_args->nitems, poll_args->timeout_usec);
|
265
|
+
|
266
|
+
return Qnil;
|
267
|
+
}
|
268
|
+
|
269
|
+
#endif
|
270
|
+
|
271
|
+
/*
|
272
|
+
* call-seq:
|
273
|
+
* ZMQ.select(in, out=[], err=[], timeout=nil) -> [in, out, err] | nil
|
274
|
+
*
|
275
|
+
* Like IO.select, but also works with 0MQ sockets.
|
276
|
+
*/
|
277
|
+
static VALUE module_select (int argc_, VALUE* argv_, VALUE self_)
|
278
|
+
{
|
279
|
+
VALUE readset, writeset, errset, timeout;
|
280
|
+
rb_scan_args (argc_, argv_, "13", &readset, &writeset, &errset, &timeout);
|
281
|
+
|
282
|
+
long timeout_usec;
|
283
|
+
int rc, nitems, i;
|
284
|
+
zmq_pollitem_t *items, *item;
|
285
|
+
|
286
|
+
if (!NIL_P (readset)) Check_Type (readset, T_ARRAY);
|
287
|
+
if (!NIL_P (writeset)) Check_Type (writeset, T_ARRAY);
|
288
|
+
if (!NIL_P (errset)) Check_Type (errset, T_ARRAY);
|
289
|
+
|
290
|
+
if (NIL_P (timeout))
|
291
|
+
timeout_usec = -1;
|
292
|
+
else
|
293
|
+
timeout_usec = (long)(NUM2DBL (timeout) * 1000000);
|
294
|
+
|
295
|
+
/* Conservative estimate for nitems before we traverse the lists. */
|
296
|
+
nitems = (NIL_P (readset) ? 0 : RARRAY_LEN (readset)) +
|
297
|
+
(NIL_P (writeset) ? 0 : RARRAY_LEN (writeset)) +
|
298
|
+
(NIL_P (errset) ? 0 : RARRAY_LEN (errset));
|
299
|
+
items = (zmq_pollitem_t*)ruby_xmalloc(sizeof(zmq_pollitem_t) * nitems);
|
300
|
+
|
301
|
+
struct poll_state ps;
|
302
|
+
ps.nitems = 0;
|
303
|
+
ps.items = items;
|
304
|
+
ps.io_objects = rb_ary_new ();
|
305
|
+
|
306
|
+
if (!NIL_P (readset)) {
|
307
|
+
ps.event = ZMQ_POLLIN;
|
308
|
+
rb_iterate(rb_each, readset, (iterfunc)poll_add_item, (VALUE)&ps);
|
309
|
+
}
|
310
|
+
|
311
|
+
if (!NIL_P (writeset)) {
|
312
|
+
ps.event = ZMQ_POLLOUT;
|
313
|
+
rb_iterate(rb_each, writeset, (iterfunc)poll_add_item, (VALUE)&ps);
|
314
|
+
}
|
315
|
+
|
316
|
+
if (!NIL_P (errset)) {
|
317
|
+
ps.event = ZMQ_POLLERR;
|
318
|
+
rb_iterate(rb_each, errset, (iterfunc)poll_add_item, (VALUE)&ps);
|
319
|
+
}
|
320
|
+
|
321
|
+
/* Reset nitems to the actual number of zmq_pollitem_t records we're sending. */
|
322
|
+
nitems = ps.nitems;
|
323
|
+
|
324
|
+
#ifdef HAVE_RUBY_INTERN_H
|
325
|
+
if (timeout_usec != 0) {
|
326
|
+
struct zmq_poll_args poll_args;
|
327
|
+
poll_args.items = items;
|
328
|
+
poll_args.nitems = nitems;
|
329
|
+
poll_args.timeout_usec = timeout_usec;
|
330
|
+
|
331
|
+
rb_thread_blocking_region (zmq_poll_blocking, (void*)&poll_args, NULL, NULL);
|
332
|
+
rc = poll_args.rc;
|
333
|
+
}
|
334
|
+
else
|
335
|
+
#endif
|
336
|
+
rc = zmq_poll (items, nitems, timeout_usec);
|
337
|
+
|
338
|
+
if (rc == -1) {
|
339
|
+
rb_raise(rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ()));
|
340
|
+
return Qnil;
|
341
|
+
}
|
342
|
+
else if (rc == 0)
|
343
|
+
return Qnil;
|
344
|
+
|
345
|
+
VALUE read_active = rb_ary_new ();
|
346
|
+
VALUE write_active = rb_ary_new ();
|
347
|
+
VALUE err_active = rb_ary_new ();
|
348
|
+
|
349
|
+
for (i = 0, item = &items[0]; i < nitems; i++, item++) {
|
350
|
+
if (item->revents != 0) {
|
351
|
+
VALUE io = RARRAY_PTR (ps.io_objects)[i];
|
352
|
+
|
353
|
+
if (item->revents & ZMQ_POLLIN)
|
354
|
+
rb_ary_push (read_active, io);
|
355
|
+
if (item->revents & ZMQ_POLLOUT)
|
356
|
+
rb_ary_push (write_active, io);
|
357
|
+
if (item->revents & ZMQ_POLLERR)
|
358
|
+
rb_ary_push (err_active, io);
|
359
|
+
}
|
360
|
+
}
|
361
|
+
|
362
|
+
ruby_xfree (items);
|
363
|
+
|
364
|
+
return rb_ary_new3 (3, read_active, write_active, err_active);
|
365
|
+
}
|
366
|
+
|
367
|
+
|
368
|
+
static void socket_free (void *s)
|
369
|
+
{
|
370
|
+
if (s) {
|
371
|
+
int rc = zmq_close (s);
|
372
|
+
assert (rc == 0);
|
373
|
+
}
|
374
|
+
}
|
375
|
+
|
376
|
+
/*
|
377
|
+
* Document-method: socket
|
378
|
+
*
|
379
|
+
* call-seq:
|
380
|
+
* zmq.socket(socket_type)
|
381
|
+
*
|
382
|
+
* Creates a new 0MQ socket. The socket_type argument specifies the socket
|
383
|
+
* type, which determines the semantics of communication over the socket.
|
384
|
+
*
|
385
|
+
* The newly created socket is initially unbound, and not associated with any
|
386
|
+
* endpoints. In order to establish a message flow a socket must first be
|
387
|
+
* connected to at least one endpoint with connect(), or at least one
|
388
|
+
* endpoint must be created for accepting incoming connections with
|
389
|
+
* bind().
|
390
|
+
*
|
391
|
+
* For a description of the various socket types, see ZMQ::Socket.
|
392
|
+
*/
|
393
|
+
static VALUE context_socket (VALUE self_, VALUE type_)
|
394
|
+
{
|
395
|
+
void * c = NULL;
|
396
|
+
Data_Get_Struct (self_, void, c);
|
397
|
+
void * s = zmq_socket (c, NUM2INT (type_));
|
398
|
+
if (!s) {
|
399
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ()));
|
400
|
+
return Qnil;
|
401
|
+
}
|
402
|
+
|
403
|
+
return Data_Wrap_Struct(socket_type, 0, socket_free, s);
|
404
|
+
}
|
405
|
+
|
406
|
+
/*
|
407
|
+
* Document-class: ZMQ::Socket
|
408
|
+
*
|
409
|
+
* ZeroMQ message socket.
|
410
|
+
*
|
411
|
+
* = Description
|
412
|
+
* == Key differences to conventional sockets
|
413
|
+
* Generally speaking, conventional sockets present a _synchronous_ interface
|
414
|
+
* to either connection-oriented reliable byte streams (SOCK_STREAM), or
|
415
|
+
* connection-less unreliable datagrams (SOCK_DGRAM). In comparison, 0MQ
|
416
|
+
* sockets present an abstraction of an asynchronous <em>message queue</em>, with the
|
417
|
+
* exact queueing semantics depending on the socket type in use. Where
|
418
|
+
* conventional sockets transfer streams of bytes or discrete datagrams, 0MQ
|
419
|
+
* sockets transfer discrete _messages_.
|
420
|
+
*
|
421
|
+
* 0MQ sockets being _asynchronous_ means that the timings of the physical
|
422
|
+
* connection setup and teardown, reconnect and effective delivery are
|
423
|
+
* transparent to the user and organized by 0MQ itself. Further, messages
|
424
|
+
* may be _queued_ in the event that a peer is unavailable to receive them.
|
425
|
+
*
|
426
|
+
* Conventional sockets allow only strict one-to-one (two peers),
|
427
|
+
* many-to-one (many clients, one server), or in some cases one-to-many
|
428
|
+
* (multicast) relationships. With the exception of ZMQ::PAIR, 0MQ sockets
|
429
|
+
* may be connected <b>to multiple endpoints</b> using connect(), while
|
430
|
+
* simultaneously accepting incoming connections <b>from multiple endpoints</b>
|
431
|
+
* bound to the socket using bind(), thus allowing many-to-many relationships.
|
432
|
+
*
|
433
|
+
* == Socket Types
|
434
|
+
*
|
435
|
+
* The following sections present the socket types defined by 0MQ, grouped by
|
436
|
+
* the general <em>messaging pattern</em> which is built from related
|
437
|
+
* socket types.
|
438
|
+
*
|
439
|
+
* = Request-reply pattern
|
440
|
+
* The request-reply pattern is used for sending requests from a _client_ to one
|
441
|
+
* or more instances of a _service_, and receiving subsequent replies to each
|
442
|
+
* request sent.
|
443
|
+
*
|
444
|
+
* == ZMQ::REQ
|
445
|
+
* A socket of type ZMQ::REQ is used by a _client_ to send requests to and receive
|
446
|
+
* replies from a _service_. This socket type allows only an alternating sequence
|
447
|
+
* of send(request) and subsequent recv(reply) calls. Each request sent
|
448
|
+
* is load-balanced among all _services_, and each reply received is matched with
|
449
|
+
* the last issued request.
|
450
|
+
*
|
451
|
+
* When a ZMQ::REQ socket enters an exceptional state due to having reached the
|
452
|
+
* high water mark for all _services_, or if there are no _services_ at all, then
|
453
|
+
* any send() operations on the socket shall block until the exceptional
|
454
|
+
* state ends or at least one _service_ becomes available for sending; messages
|
455
|
+
* are not discarded.
|
456
|
+
*
|
457
|
+
* === Summary of ZMQ::REQ characteristics
|
458
|
+
* [Compatible peer sockets] ZMQ::REP
|
459
|
+
* [Direction] Bidirectional
|
460
|
+
* [Send/receive pattern] Send, Receive, Send, Receive, ...
|
461
|
+
* [Outgoing routing strategy] Load-balanced
|
462
|
+
* [Incoming routing strategy] Last peer
|
463
|
+
* [ZMQ::HWM option action] Block
|
464
|
+
*
|
465
|
+
* == ZMQ::REP
|
466
|
+
* A socket of type ZMQ::REP is used by a _service_ to receive requests from and
|
467
|
+
* send replies to a _client_. This socket type allows only an alternating
|
468
|
+
* sequence of recv(request) and subsequent send(reply) calls. Each
|
469
|
+
* request received is fair-queued from among all _clients_, and each reply sent
|
470
|
+
* is routed to the _client_ that issued the last request.
|
471
|
+
*
|
472
|
+
* When a ZMQ::REP socket enters an exceptional state due to having reached the
|
473
|
+
* high water mark for a _client_, then any replies sent to the _client_ in
|
474
|
+
* question shall be dropped until the exceptional state ends.
|
475
|
+
*
|
476
|
+
* === Summary of ZMQ::REP characteristics
|
477
|
+
* [Compatible peer sockets] ZMQ::REQ
|
478
|
+
* [Direction] Bidirectional
|
479
|
+
* [Send/receive pattern] Receive, Send, Receive, Send, ...
|
480
|
+
* [Incoming routing strategy] Fair-queued
|
481
|
+
* [Outgoing routing stratagy] Last peer
|
482
|
+
* [ZMQ::HWM option action] Drop
|
483
|
+
*
|
484
|
+
*
|
485
|
+
* = Publish-subscribe pattern
|
486
|
+
* The publish-subscribe pattern is used for one-to-many distribution of data
|
487
|
+
* from a single _publisher_ to multiple _subscribers_ in a fanout fashion.
|
488
|
+
*
|
489
|
+
* == ZMQ::PUB
|
490
|
+
* A socket of type ZMQ::PUB is used by a publisher to distribute data. Messages
|
491
|
+
* sent are distributed in a fanout fashion to all connected peers. The
|
492
|
+
* recv() function is not implemented for this socket type.
|
493
|
+
*
|
494
|
+
* When a ZMQ::PUB socket enters an exceptional state due to having reached the
|
495
|
+
* high water mark for a _subscriber_, then any messages that would be sent to the
|
496
|
+
* subscriber in question shall instead be dropped until the exceptional state
|
497
|
+
* ends.
|
498
|
+
*
|
499
|
+
* === Summary of ZMQ::PUB characteristics
|
500
|
+
* [Compatible peer sockets] ZMQ::SUB
|
501
|
+
* [Direction] Unidirectional
|
502
|
+
* [Send/receive pattern] Send only
|
503
|
+
* [Incoming routing strategy] N/A
|
504
|
+
* [Outgoing routing strategy] Fanout
|
505
|
+
* [ZMQ::HWM option action] Drop
|
506
|
+
*
|
507
|
+
* == ZMQ::SUB
|
508
|
+
*
|
509
|
+
* A socket of type ZMQ::SUB is used by a _subscriber_ to subscribe to data
|
510
|
+
* distributed by a _publisher_. Initially a ZMQ::SUB socket is not subscribed to
|
511
|
+
* any messages, use the ZMQ::SUBSCRIBE option of setsockopt() to specify which
|
512
|
+
* messages to subscribe to. The send() function is not implemented for this
|
513
|
+
* socket type.
|
514
|
+
*
|
515
|
+
* === Summary of ZMQ::SUB characteristics
|
516
|
+
* [Compatible peer sockets] ZMQ::PUB
|
517
|
+
* [Direction] Unidirectional
|
518
|
+
* [Send/receive pattern] Receive only
|
519
|
+
* [Incoming routing strategy] Fair-queued
|
520
|
+
* [Outgoing routing strategy] N/A
|
521
|
+
* [ZMQ::HWM option action] N/A
|
522
|
+
*
|
523
|
+
* = Pipeline pattern
|
524
|
+
* The pipeline pattern is used for distributing data to _nodes_ arranged in a
|
525
|
+
* pipeline. Data always flows down the pipeline, and each stage of the pipeline
|
526
|
+
* is connected to at least one _node_. When a pipeline stage is connected to
|
527
|
+
* multiple _nodes_ data is load-balanced among all connected _nodes_.
|
528
|
+
*
|
529
|
+
* == ZMQ::DOWNSTREAM
|
530
|
+
*
|
531
|
+
* A socket of type ZMQ::DOWNSTREAM is used by a pipeline node to send messages to downstream pipeline nodes. Messages are load-balanced to all connected downstream nodes. The ZMQ::recv() function is not implemented for this socket type.
|
532
|
+
*
|
533
|
+
* When a ZMQ::DOWNSTREAM socket enters an exceptional state due to having
|
534
|
+
* reached the high water mark for all downstream _nodes_, or if there are no
|
535
|
+
* downstream _nodes_ at all, then any send() operations on the socket shall
|
536
|
+
* block until the exceptional state ends or at least one downstream _node_
|
537
|
+
* becomes available for sending; messages are not discarded.
|
538
|
+
*
|
539
|
+
* === Summary of ZMQ::DOWNSTREAM characteristics
|
540
|
+
* [Compatible peer sockets] ZMQ::UPSTREAM
|
541
|
+
* [Direction] Unidirectional
|
542
|
+
* [Send/receive pattern] Send only
|
543
|
+
* [Incoming routing strategy] N/A
|
544
|
+
* [Outgoing routing strategy] Load-balanced
|
545
|
+
* [ZMQ::HWM option action] Block
|
546
|
+
*
|
547
|
+
* == ZMQ::UPSTREAM
|
548
|
+
*
|
549
|
+
* A socket of type ZMQ::UPSTREAM is used by a pipeline _node_ to receive messages
|
550
|
+
* from upstream pipeline _nodes_. Messages are fair-queued from among all
|
551
|
+
* connected upstream nodes. The send() function is not implemented for
|
552
|
+
* this socket type.
|
553
|
+
*
|
554
|
+
* === Summary of ZMQ::UPSTREAM characteristics
|
555
|
+
* [Compatible peer sockets] ZMQ::DOWNSTREAM
|
556
|
+
* [Direction] Unidirectional
|
557
|
+
* [Send/receive pattern] Receive only
|
558
|
+
* [Incoming routing strategy] Fair-queued
|
559
|
+
* [Outgoing routing strategy] N/A
|
560
|
+
* [ZMQ::HWM option action] N/A
|
561
|
+
*
|
562
|
+
* = Exclusive pair pattern
|
563
|
+
*
|
564
|
+
* The exclusive pair is an advanced pattern used for communicating exclusively
|
565
|
+
* between two peers.
|
566
|
+
*
|
567
|
+
* == ZMQ::PAIR
|
568
|
+
*
|
569
|
+
* A socket of type ZMQ::PAIR can only be connected to a single peer at any one
|
570
|
+
* time. No message routing or filtering is performed on messages sent over a
|
571
|
+
* ZMQ::PAIR socket.
|
572
|
+
*
|
573
|
+
* When a ZMQ::PAIR socket enters an exceptional state due to having reached the
|
574
|
+
* high water mark for the connected peer, or if no peer is connected, then any
|
575
|
+
* send() operations on the socket shall block until the peer becomes
|
576
|
+
* available for sending; messages are not discarded.
|
577
|
+
*
|
578
|
+
* *NOTE* ZMQ_PAIR sockets are experimental, and are currently missing several features such as auto-reconnection.
|
579
|
+
*
|
580
|
+
* === Summary of ZMQ::PAIR characteristics
|
581
|
+
* [Compatible peer sockets] ZMQ::PAIR
|
582
|
+
* [Direction] Bidirectional
|
583
|
+
* [Send/receive pattern] Unrestricted
|
584
|
+
* [Incoming routing strategy] N/A
|
585
|
+
* [Outcoming routing strategy] N/A
|
586
|
+
* [ZMQ::HWM option action] Block
|
587
|
+
*/
|
588
|
+
|
589
|
+
/*
|
590
|
+
* call-seq:
|
591
|
+
* socket.getsockopt(option)
|
592
|
+
*
|
593
|
+
* Retrieves the value of the specified 0MQ socket option.
|
594
|
+
*
|
595
|
+
* The following options can be retrievesd with the getsockopt() function:
|
596
|
+
*
|
597
|
+
* == ZMQ::RCVMORE: More message parts to follow
|
598
|
+
* The ZMQ::RCVMORE option shall return a boolean value indicating if the
|
599
|
+
* multi-part message currently being read from the specified socket has more
|
600
|
+
* message parts to follow. If there are no message parts to follow or if the
|
601
|
+
* message currently being read is not a multi-part message a value of false
|
602
|
+
* shall be returned. Otherwise, a value of true shall be returned.
|
603
|
+
*
|
604
|
+
* Refer to send() and recv() for a detailed description of sending/receiving
|
605
|
+
* multi-part messages.
|
606
|
+
*
|
607
|
+
* [Option value type] Boolean
|
608
|
+
* [Option value unit] N/A
|
609
|
+
* [Default value] N/A
|
610
|
+
* [Applicable socket types] all
|
611
|
+
*
|
612
|
+
* == ZMQ::HWM: Retrieve high water mark
|
613
|
+
* The ZMQ::HWM option shall retrieve the high water mark for the specified
|
614
|
+
* _socket_. The high water mark is a hard limit on the maximum number of
|
615
|
+
* outstanding messages 0MQ shall queue in memory for any single peer that the
|
616
|
+
* specified _socket_ is communicating with.
|
617
|
+
*
|
618
|
+
* If this limit has been reached the socket shall enter an exceptional state
|
619
|
+
* and depending on the socket type, 0MQ shall take appropriate action such as
|
620
|
+
* blocking or dropping sent messages. Refer to the individual socket
|
621
|
+
* descriptions in ZMQ::Socket for details on the exact action taken for each
|
622
|
+
* socket type.
|
623
|
+
*
|
624
|
+
* The default ZMQ::HWM value of zero means "no limit".
|
625
|
+
*
|
626
|
+
* [Option value type] Integer
|
627
|
+
* [Option value unit] messages
|
628
|
+
* [Default value] 0
|
629
|
+
* [Applicable socket types] all
|
630
|
+
*
|
631
|
+
* == ZMQ::SWAP: Retrieve disk offload size
|
632
|
+
* The ZMQ::SWAP option shall retrieve the disk offload (swap) size for the
|
633
|
+
* specified _socket_. A socket which has ZMQ::SWAP set to a non-zero value may
|
634
|
+
* exceed it’s high water mark; in this case outstanding messages shall be
|
635
|
+
* offloaded to storage on disk rather than held in memory.
|
636
|
+
*
|
637
|
+
* The value of ZMQ::SWAP defines the maximum size of the swap space in bytes.
|
638
|
+
*
|
639
|
+
* [Option value type] Integer
|
640
|
+
* [Option value unit] bytes
|
641
|
+
* [Default value] 0
|
642
|
+
* [Applicable socket types] all
|
643
|
+
*
|
644
|
+
* == ZMQ::AFFINITY: Retrieve I/O thread affinity
|
645
|
+
* The ZMQ::AFFINITY option shall retrieve the I/O thread affinity for newly
|
646
|
+
* created connections on the specified _socket_.
|
647
|
+
*
|
648
|
+
* Affinity determines which threads from the 0MQ I/O thread pool associated
|
649
|
+
* with the socket’s _context_ shall handle newly created connections. A value of
|
650
|
+
* zero specifies no affinity, meaning that work shall be distributed fairly
|
651
|
+
* among all 0MQ I/O threads in the thread pool. For non-zero values, the lowest
|
652
|
+
* bit corresponds to thread 1, second lowest bit to thread 2 and so on. For
|
653
|
+
* example, a value of 3 specifies that subsequent connections on _socket_ shall
|
654
|
+
* be handled exclusively by I/O threads 1 and 2.
|
655
|
+
*
|
656
|
+
* See also ZMQ::Context#new for details on allocating the number of
|
657
|
+
* I/O threads for a specific _context_.
|
658
|
+
*
|
659
|
+
* [Option value type] Integer
|
660
|
+
* [Option value unit] N/A (bitmap)
|
661
|
+
* [Default value] 0
|
662
|
+
* [Applicable socket types] all
|
663
|
+
*
|
664
|
+
* == ZMQ::IDENTITY: Retrieve socket identity
|
665
|
+
* The ZMQ::IDENTITY option shall retrieve the identity of the specified _socket_.
|
666
|
+
* Socket identity determines if existing 0MQ infastructure (<em>message queues</em>,
|
667
|
+
* <em>forwarding devices</em>) shall be identified with a specific application and
|
668
|
+
* persist across multiple runs of the application.
|
669
|
+
*
|
670
|
+
* If the socket has no identity, each run of an application is completely
|
671
|
+
* separate from other runs. However, with identity set the socket shall re-use
|
672
|
+
* any existing 0MQ infrastructure configured by the previous run(s). Thus the
|
673
|
+
* application may receive messages that were sent in the meantime, <em>message
|
674
|
+
* queue</em> limits shall be shared with previous run(s) and so on.
|
675
|
+
*
|
676
|
+
* Identity can be at least one byte and at most 255 bytes long. Identities
|
677
|
+
* starting with binary zero are reserved for use by 0MQ infrastructure.
|
678
|
+
*
|
679
|
+
* [Option value type] String
|
680
|
+
* [Option value unit] N/A
|
681
|
+
* [Default value] nil
|
682
|
+
* [Applicable socket types] all
|
683
|
+
*
|
684
|
+
* == ZMQ::RATE: Retrieve multicast data rate
|
685
|
+
*
|
686
|
+
* The ZMQ::Rate option shall retrieve the maximum send or receive data
|
687
|
+
* rate for multicast transports using the specified _socket_.
|
688
|
+
*
|
689
|
+
* [Option value type] Integer
|
690
|
+
* [Option value unit] kilobits per second
|
691
|
+
* [Default value] 100
|
692
|
+
* [Applicable socket types] all, when using multicast transports
|
693
|
+
*
|
694
|
+
* == ZMQ::RECOVERY_IVL: Get multicast recovery interval
|
695
|
+
*
|
696
|
+
* The ZMQ::RECOVERY_IVL option shall retrieve the recovery interval for
|
697
|
+
* multicast transports using the specified _socket_. The recovery interval
|
698
|
+
* determines the maximum time in seconds that a receiver can be absent from a
|
699
|
+
* multicast group before unrecoverable data loss will occur.
|
700
|
+
*
|
701
|
+
* [Option value type] Integer
|
702
|
+
* [Option value unit] seconds
|
703
|
+
* [Default value] 10
|
704
|
+
* [Applicable socket types] all, when using multicast transports
|
705
|
+
*
|
706
|
+
* == ZMQ::MCAST_LOOP: Control multicast loopback
|
707
|
+
* The ZMQ::MCAST_LOOP option controls whether data sent via multicast transports
|
708
|
+
* can also be received by the sending host via loopback. A value of zero
|
709
|
+
* indicates that the loopback functionality is disabled, while the default
|
710
|
+
* value of 1 indicates that the loopback functionality is enabled. Leaving
|
711
|
+
* multicast loopback enabled when it is not required can have a negative impact
|
712
|
+
* on performance. Where possible, disable ZMQ::MCAST_LOOP in production
|
713
|
+
* environments.
|
714
|
+
*
|
715
|
+
* [Option value type] Boolean
|
716
|
+
* [Option value unit] N/A
|
717
|
+
* [Default value] true
|
718
|
+
* [Applicable socket types] all, when using multicast transports
|
719
|
+
*
|
720
|
+
* == ZMQ::SNDBUF: Retrieve kernel transmit buffer size
|
721
|
+
* The ZMQ::SNDBUF option shall retrieve the underlying kernel transmit buffer
|
722
|
+
* size for the specified _socket_. A value of zero means that the OS default is
|
723
|
+
* in effect. For details refer to your operating system documentation for the
|
724
|
+
* SO_SNDBUF socket option.
|
725
|
+
*
|
726
|
+
* [Option value type] Integer
|
727
|
+
* [Option value unit] bytes
|
728
|
+
* [Default value] 0
|
729
|
+
* [Applicable socket types] all
|
730
|
+
*
|
731
|
+
* == ZMQ::RCVBUF: Retrieve kernel receive buffer size
|
732
|
+
* The ZMQ::RCVBUF option shall retrieve the underlying kernel receive buffer
|
733
|
+
* size for the specified _socket_. A value of zero means that the OS default is
|
734
|
+
* in effect. For details refer to your operating system documentation for the
|
735
|
+
* SO_RCVBUF socket option.
|
736
|
+
*
|
737
|
+
* [Option value type] Integer
|
738
|
+
* [Option value unit] bytes
|
739
|
+
* [Default value] 0
|
740
|
+
* [Applicable socket types] all
|
741
|
+
*
|
742
|
+
*/
|
743
|
+
static VALUE socket_getsockopt (VALUE self_, VALUE option_)
|
744
|
+
{
|
745
|
+
int rc = 0;
|
746
|
+
VALUE retval;
|
747
|
+
void * s;
|
748
|
+
|
749
|
+
Data_Get_Struct (self_, void, s);
|
750
|
+
Check_Socket (s);
|
751
|
+
|
752
|
+
switch (NUM2INT (option_)) {
|
753
|
+
case ZMQ_RCVMORE:
|
754
|
+
case ZMQ_HWM:
|
755
|
+
case ZMQ_SWAP:
|
756
|
+
case ZMQ_AFFINITY:
|
757
|
+
case ZMQ_RATE:
|
758
|
+
case ZMQ_RECOVERY_IVL:
|
759
|
+
case ZMQ_MCAST_LOOP:
|
760
|
+
case ZMQ_SNDBUF:
|
761
|
+
case ZMQ_RCVBUF:
|
762
|
+
{
|
763
|
+
int64_t optval;
|
764
|
+
size_t optvalsize = sizeof(optval);
|
765
|
+
|
766
|
+
rc = zmq_getsockopt (s, NUM2INT (option_), (void *)&optval,
|
767
|
+
&optvalsize);
|
768
|
+
|
769
|
+
if (rc != 0) {
|
770
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ()));
|
771
|
+
return Qnil;
|
772
|
+
}
|
773
|
+
|
774
|
+
if (NUM2INT (option_) == ZMQ_RCVMORE)
|
775
|
+
retval = optval ? Qtrue : Qfalse;
|
776
|
+
else
|
777
|
+
retval = INT2NUM (optval);
|
778
|
+
}
|
779
|
+
break;
|
780
|
+
case ZMQ_IDENTITY:
|
781
|
+
{
|
782
|
+
char identity[255];
|
783
|
+
size_t optvalsize = sizeof (identity);
|
784
|
+
|
785
|
+
rc = zmq_getsockopt (s, NUM2INT (option_), (void *)identity,
|
786
|
+
&optvalsize);
|
787
|
+
|
788
|
+
if (rc != 0) {
|
789
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ()));
|
790
|
+
return Qnil;
|
791
|
+
}
|
792
|
+
|
793
|
+
if (optvalsize > sizeof (identity))
|
794
|
+
optvalsize = sizeof (identity);
|
795
|
+
|
796
|
+
retval = rb_str_new (identity, optvalsize);
|
797
|
+
}
|
798
|
+
break;
|
799
|
+
default:
|
800
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (EINVAL));
|
801
|
+
return Qnil;
|
802
|
+
}
|
803
|
+
|
804
|
+
return retval;
|
805
|
+
}
|
806
|
+
|
807
|
+
/*
|
808
|
+
* call-seq:
|
809
|
+
* socket.setsockopt(option, value) -> nil
|
810
|
+
*
|
811
|
+
* Sets the value of a 0MQ socket option.
|
812
|
+
*
|
813
|
+
* The following socket options can be set with the setsockopt() function:
|
814
|
+
*
|
815
|
+
* == ZMQ::HWM: Set high water mark
|
816
|
+
* The ZMQ::HWM option shall set the high water mark for the specified _socket_.
|
817
|
+
* The high water mark is a hard limit on the maximum number of outstanding
|
818
|
+
* messages 0MQ shall queue in memory for any single peer that the specified
|
819
|
+
* _socket_ is communicating with.
|
820
|
+
*
|
821
|
+
* If this limit has been reached the socket shall enter an exceptional state
|
822
|
+
* and depending on the socket type, 0MQ shall take appropriate action such as
|
823
|
+
* blocking or dropping sent messages. Refer to the individual socket
|
824
|
+
* descriptions in ZMQ::Socket for details on the exact action taken for each
|
825
|
+
* socket type.
|
826
|
+
*
|
827
|
+
* The default ZMQ::HWM value of zero means "no limit".
|
828
|
+
*
|
829
|
+
* [Option value type] Integer
|
830
|
+
* [Option value unit] messages
|
831
|
+
* [Default value] 0
|
832
|
+
* [Applicable socket types] all
|
833
|
+
*
|
834
|
+
* == ZMQ::SWAP: Set disk offload size
|
835
|
+
* The ZMQ::SWAP option shall set the disk offload (swap) size for the specified
|
836
|
+
* socket. A socket which has ZMQ::SWAP set to a non-zero value may exceed it’s
|
837
|
+
* high water mark; in this case outstanding messages shall be offloaded to
|
838
|
+
* storage on disk rather than held in memory.
|
839
|
+
*
|
840
|
+
* The value of ZMQ::SWAP defines the maximum size of the swap space in bytes.
|
841
|
+
*
|
842
|
+
* [Option value type] Integer
|
843
|
+
* [Option value unit] bytes
|
844
|
+
* [Default value] 0
|
845
|
+
* [Applicable socket types] all
|
846
|
+
*
|
847
|
+
* == ZMQ::AFFINITY: Set I/O thread affinity
|
848
|
+
* The ZMQ::AFFINITY option shall set the I/O thread affinity for newly created
|
849
|
+
* connections on the specified socket.
|
850
|
+
*
|
851
|
+
* Affinity determines which threads from the 0MQ I/O thread pool associated
|
852
|
+
* with the socket’s _context_ shall handle newly created connections. A value of
|
853
|
+
* zero specifies no affinity, meaning that work shall be distributed fairly
|
854
|
+
* among all 0MQ I/O threads in the thread pool. For non-zero values, the lowest
|
855
|
+
* bit corresponds to thread 1, second lowest bit to thread 2 and so on. For
|
856
|
+
* example, a value of 3 specifies that subsequent connections on socket shall
|
857
|
+
* be handled exclusively by I/O threads 1 and 2.
|
858
|
+
*
|
859
|
+
* See also ZMQ::Context#new for details on allocating the number of I/O threads
|
860
|
+
* for a specific _context_.
|
861
|
+
*
|
862
|
+
* [Option value type] Integer
|
863
|
+
* [Option value unit] N/A (bitmap)
|
864
|
+
* [Default value] 0
|
865
|
+
* [Applicable socket types] all
|
866
|
+
*
|
867
|
+
* == ZMQ::IDENTITY: Set socket identity
|
868
|
+
* The ZMQ::IDENTITY option shall set the identity of the specified socket.
|
869
|
+
* Socket identity determines if existing 0MQ infastructure (<em>message queues</em>,
|
870
|
+
* <em>forwarding devices</em>) shall be identified with a specific application and
|
871
|
+
* persist across multiple runs of the application.
|
872
|
+
*
|
873
|
+
* If the socket has no identity, each run of an application is completely
|
874
|
+
* separate from other runs. However, with identity set the socket shall re-use
|
875
|
+
* any existing 0MQ infrastructure configured by the previous run(s). Thus the
|
876
|
+
* application may receive messages that were sent in the meantime, <em>message
|
877
|
+
* queue</em> limits shall be shared with previous run(s) and so on.
|
878
|
+
*
|
879
|
+
* Identity should be at least one byte and at most 255 bytes long. Identities
|
880
|
+
* starting with binary zero are reserved for use by 0MQ infrastructure.
|
881
|
+
*
|
882
|
+
* [Option value type] String
|
883
|
+
* [Option value unit] N/A
|
884
|
+
* [Default value] nil
|
885
|
+
* [Applicable socket types] all
|
886
|
+
*
|
887
|
+
* ZMQ::SUBSCRIBE: Establish message filter
|
888
|
+
* The ZMQ::SUBSCRIBE option shall establish a new message filter on a ZMQ::SUB
|
889
|
+
* socket. Newly created ZMQ::SUB sockets shall filter out all incoming messages,
|
890
|
+
* therefore you should call this option to establish an initial message filter.
|
891
|
+
*
|
892
|
+
* An empty _value_ of length zero shall subscribe to all incoming messages. A
|
893
|
+
* non-empty _value_ shall subscribe to all messages beginning with the
|
894
|
+
* specified prefix. Mutiple filters may be attached to a single ZMQ::SUB socket,
|
895
|
+
* in which case a message shall be accepted if it matches at least one filter.
|
896
|
+
*
|
897
|
+
* [Option value type] String
|
898
|
+
* [Option value unit] N/A
|
899
|
+
* [Default value] N/A
|
900
|
+
* [Applicable socket types] ZMQ::SUB
|
901
|
+
*
|
902
|
+
* == ZMQ::UNSUBSCRIBE: Remove message filter
|
903
|
+
* The ZMQ::UNSUBSCRIBE option shall remove an existing message filter on a
|
904
|
+
* ZMQ::SUB socket. The filter specified must match an existing filter
|
905
|
+
* previously established with the ZMQ::SUBSCRIBE option. If the socket has
|
906
|
+
* several instances of the same filter attached the ZMQ::UNSUBSCRIBE option
|
907
|
+
* shall remove only one instance, leaving the rest in place and functional.
|
908
|
+
*
|
909
|
+
* [Option value type] String
|
910
|
+
* [Option value unit] N/A
|
911
|
+
* [Default value] nil
|
912
|
+
* [Applicable socket types] all
|
913
|
+
*
|
914
|
+
* == ZMQ::RATE: Set multicast data rate
|
915
|
+
* The ZMQ::RATE option shall set the maximum send or receive data rate for
|
916
|
+
* multicast transports such as _pgm_ using the specified socket.
|
917
|
+
*
|
918
|
+
* [Option value type] Integer
|
919
|
+
* [Option value unit] kilobits per second
|
920
|
+
* [Default value] 100
|
921
|
+
* [Applicable socket types] all, when using multicast transports
|
922
|
+
*
|
923
|
+
* == ZMQ::RECOVERY_IVL: Set multicast recovery interval
|
924
|
+
* The ZMQ::RECOVERY_IVL option shall set the recovery interval for multicast
|
925
|
+
* transports using the specified _socket_. The recovery interval determines the
|
926
|
+
* maximum time in seconds that a receiver can be absent from a multicast group
|
927
|
+
* before unrecoverable data loss will occur.
|
928
|
+
*
|
929
|
+
* <b>Caution:</b> Exercise care when setting large recovery intervals as the data needed for recovery will be held in memory. For example, a 1 minute recovery interval at a data rate of 1Gbps requires a 7GB in-memory buffer.
|
930
|
+
*
|
931
|
+
* [Option value type] Integer
|
932
|
+
* [Option value unit] seconds
|
933
|
+
* [Default value] 10
|
934
|
+
* [Applicable socket types] all, when using multicast transports
|
935
|
+
*
|
936
|
+
* == ZMQ::MCAST_LOOP: Control multicast loopback
|
937
|
+
* The ZMQ::MCAST_LOOP option shall control whether data sent via multicast
|
938
|
+
* transports using the specified _socket_ can also be received by the sending
|
939
|
+
* host via loopback. A value of zero disables the loopback functionality, while
|
940
|
+
* the default value of 1 enables the loopback functionality. Leaving multicast
|
941
|
+
* loopback enabled when it is not required can have a negative impact on
|
942
|
+
* performance. Where possible, disable ZMQ::MCAST_LOOP in production
|
943
|
+
* environments.
|
944
|
+
*
|
945
|
+
* [Option value type] Boolean
|
946
|
+
* [Option value unit] N/A
|
947
|
+
* [Default value] true
|
948
|
+
* [Applicable socket types] all, when using multicast transports
|
949
|
+
*
|
950
|
+
* == ZMQ::SNDBUF: Set kernel transmit buffer size
|
951
|
+
* The ZMQ::SNDBUF option shall set the underlying kernel transmit buffer size
|
952
|
+
* for the socket to the specified size in bytes. A value of zero means leave
|
953
|
+
* the OS default unchanged. For details please refer to your operating system
|
954
|
+
* documentation for the SO_SNDBUF socket option.
|
955
|
+
*
|
956
|
+
* [Option value type] Integer
|
957
|
+
* [Option value unit] bytes
|
958
|
+
* [Default value] 0
|
959
|
+
* [Applicable socket types] all
|
960
|
+
*
|
961
|
+
* == ZMQ::RCVBUF: Set kernel receive buffer size
|
962
|
+
* The ZMQ::RCVBUF option shall set the underlying kernel receive buffer size
|
963
|
+
* for the socket to the specified size in bytes. A value of zero means leave
|
964
|
+
* the OS default unchanged. For details refer to your operating system
|
965
|
+
* documentation for the SO_RCVBUF socket option.
|
966
|
+
*
|
967
|
+
* [Option value type] Integer
|
968
|
+
* [Option value unit] bytes
|
969
|
+
* [Default value] 0
|
970
|
+
* [Applicable socket types] all
|
971
|
+
*
|
972
|
+
*/
|
973
|
+
static VALUE socket_setsockopt (VALUE self_, VALUE option_,
|
974
|
+
VALUE optval_)
|
975
|
+
{
|
976
|
+
|
977
|
+
int rc = 0;
|
978
|
+
void * s;
|
979
|
+
|
980
|
+
Data_Get_Struct (self_, void, s);
|
981
|
+
Check_Socket (s);
|
982
|
+
|
983
|
+
switch (NUM2INT (option_)) {
|
984
|
+
case ZMQ_HWM:
|
985
|
+
case ZMQ_SWAP:
|
986
|
+
case ZMQ_AFFINITY:
|
987
|
+
case ZMQ_RATE:
|
988
|
+
case ZMQ_RECOVERY_IVL:
|
989
|
+
case ZMQ_MCAST_LOOP:
|
990
|
+
case ZMQ_SNDBUF:
|
991
|
+
case ZMQ_RCVBUF:
|
992
|
+
{
|
993
|
+
uint64_t optval = FIX2LONG (optval_);
|
994
|
+
|
995
|
+
// Forward the code to native 0MQ library.
|
996
|
+
rc = zmq_setsockopt (s, NUM2INT (option_),
|
997
|
+
(void*) &optval, sizeof (optval));
|
998
|
+
}
|
999
|
+
break;
|
1000
|
+
|
1001
|
+
case ZMQ_IDENTITY:
|
1002
|
+
case ZMQ_SUBSCRIBE:
|
1003
|
+
case ZMQ_UNSUBSCRIBE:
|
1004
|
+
|
1005
|
+
// Forward the code to native 0MQ library.
|
1006
|
+
rc = zmq_setsockopt (s, NUM2INT (option_),
|
1007
|
+
(void *) StringValueCStr (optval_), RSTRING_LEN (optval_));
|
1008
|
+
break;
|
1009
|
+
|
1010
|
+
default:
|
1011
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (EINVAL));
|
1012
|
+
return Qnil;
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
if (rc != 0) {
|
1016
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ()));
|
1017
|
+
return Qnil;
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
return self_;
|
1021
|
+
}
|
1022
|
+
|
1023
|
+
/*
|
1024
|
+
* call-seq:
|
1025
|
+
* socket.bind(endpoint) -> nil
|
1026
|
+
*
|
1027
|
+
* Creates an endpoint for accepting connections and binds it to the socket.
|
1028
|
+
*
|
1029
|
+
* The _endpoint_ argument is a string consisting of two parts as follows:
|
1030
|
+
* _transport://address_. The _transport_ part specifies the underlying
|
1031
|
+
* transport protocol to use. The meaning of the _address_ part is specific
|
1032
|
+
* to the underlying transport protocol selected.
|
1033
|
+
*
|
1034
|
+
* The following transports are defined:
|
1035
|
+
*
|
1036
|
+
* [_inproc_] local in-process (inter-thread) communication transport
|
1037
|
+
* [_ipc_] local inter-process communication transport
|
1038
|
+
* [_tcp_] unicast transport using TCP
|
1039
|
+
* [_pgm_, _epgm_] reliable multicast transport using PGM
|
1040
|
+
*
|
1041
|
+
* With the exception of ZMQ:PAIR sockets, a single socket may be connected to
|
1042
|
+
* multiple endpoints using connect(), while simultaneously accepting
|
1043
|
+
* incoming connections from multiple endpoints bound to the socket using
|
1044
|
+
* bind(). Refer to ZMQ::Socket for a description of the exact semantics
|
1045
|
+
* involved when connecting or binding a socket to multiple endpoints.
|
1046
|
+
*/
|
1047
|
+
static VALUE socket_bind (VALUE self_, VALUE addr_)
|
1048
|
+
{
|
1049
|
+
void * s;
|
1050
|
+
Data_Get_Struct (self_, void, s);
|
1051
|
+
Check_Socket (s);
|
1052
|
+
|
1053
|
+
int rc = zmq_bind (s, rb_string_value_cstr (&addr_));
|
1054
|
+
if (rc != 0) {
|
1055
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ()));
|
1056
|
+
return Qnil;
|
1057
|
+
}
|
1058
|
+
|
1059
|
+
return Qnil;
|
1060
|
+
}
|
1061
|
+
|
1062
|
+
/*
|
1063
|
+
* call-seq:
|
1064
|
+
* socket.connect(endpoint) -> nil
|
1065
|
+
*
|
1066
|
+
* Connects the socket to the endpoint specified by the _endpoint_ argument.
|
1067
|
+
*
|
1068
|
+
* The _endpoint_ argument is a string consisting of two parts as follows:
|
1069
|
+
* _transport://address_. The _transport_ part specifies the underlying
|
1070
|
+
* transport protocol to use. The meaning of the _address_ part is specific
|
1071
|
+
* to the underlying transport protocol selected.
|
1072
|
+
*
|
1073
|
+
* The following transports are defined:
|
1074
|
+
*
|
1075
|
+
* [_inproc_] local in-process (inter-thread) communication transport
|
1076
|
+
* [_ipc_] local inter-process communication transport
|
1077
|
+
* [_tcp_] unicast transport using TCP
|
1078
|
+
* [_pgm_, _epgm_] reliable multicast transport using PGM
|
1079
|
+
*
|
1080
|
+
* With the exception of ZMQ:PAIR sockets, a single socket may be connected to
|
1081
|
+
* multiple endpoints using connect(), while simultaneously accepting
|
1082
|
+
* incoming connections from multiple endpoints bound to the socket using
|
1083
|
+
* bind(). Refer to ZMQ::Socket for a description of the exact semantics
|
1084
|
+
* involved when connecting or binding a socket to multiple endpoints.
|
1085
|
+
*
|
1086
|
+
* <b>NOTE:</b> The connection will not be performed immediately, but as needed by
|
1087
|
+
* 0MQ. Thus, a successful invocation of connect() does not indicate that
|
1088
|
+
* a physical connection was or can actually be established.
|
1089
|
+
*/
|
1090
|
+
static VALUE socket_connect (VALUE self_, VALUE addr_)
|
1091
|
+
{
|
1092
|
+
void * s;
|
1093
|
+
Data_Get_Struct (self_, void, s);
|
1094
|
+
Check_Socket (s);
|
1095
|
+
|
1096
|
+
int rc = zmq_connect (s, rb_string_value_cstr (&addr_));
|
1097
|
+
if (rc != 0) {
|
1098
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ()));
|
1099
|
+
return Qnil;
|
1100
|
+
}
|
1101
|
+
|
1102
|
+
return Qnil;
|
1103
|
+
}
|
1104
|
+
|
1105
|
+
#ifdef HAVE_RUBY_INTERN_H
|
1106
|
+
struct zmq_send_recv_args {
|
1107
|
+
void *socket;
|
1108
|
+
zmq_msg_t *msg;
|
1109
|
+
int flags;
|
1110
|
+
int rc;
|
1111
|
+
};
|
1112
|
+
|
1113
|
+
static VALUE zmq_send_blocking (void* args_)
|
1114
|
+
{
|
1115
|
+
struct zmq_send_recv_args *send_args = (struct zmq_send_recv_args *)args_;
|
1116
|
+
|
1117
|
+
send_args->rc = zmq_send(send_args->socket, send_args->msg, send_args->flags);
|
1118
|
+
|
1119
|
+
return Qnil;
|
1120
|
+
}
|
1121
|
+
#endif
|
1122
|
+
|
1123
|
+
/*
|
1124
|
+
* call-seq:
|
1125
|
+
* socket.send(message, flags=0) -> true | false
|
1126
|
+
*
|
1127
|
+
* Queue the message referenced by the _msg_ argument to be send to the
|
1128
|
+
* _socket_. The _flags_ argument is a combination of the flags defined
|
1129
|
+
* below:
|
1130
|
+
*
|
1131
|
+
* [ZMQ::NOBLOCK] Specifies that the operation should be performed in non-blocking mode. If the message cannot be queued on the _socket_, the function shall fail and return _false_.
|
1132
|
+
* [ZMQ::SNDMORE] Specifies that the message being sent is a multi-part message, and that further message parts are to follow. Refer to the section regarding multi-part messages below for a detailed description.
|
1133
|
+
*
|
1134
|
+
* <b>NOTE:</b> A successful invocation of send() does not indicate that the
|
1135
|
+
* message has been transmitted to the network, only that it has been queued on
|
1136
|
+
* the socket and 0MQ has assumed responsibility for the message.
|
1137
|
+
*
|
1138
|
+
* == Multi-part messages
|
1139
|
+
* A 0MQ message is composed of 1 or more message parts. 0MQ ensures atomic
|
1140
|
+
* delivery of messages; peers shall receive either all <em>message parts</em> of a
|
1141
|
+
* message or none at all.
|
1142
|
+
*
|
1143
|
+
* The total number of message parts is unlimited.
|
1144
|
+
*
|
1145
|
+
* An application wishing to send a multi-part message does so by specifying the
|
1146
|
+
* ZMQ::SNDMORE flag to send(). The presence of this flag indicates to 0MQ
|
1147
|
+
* that the message being sent is a multi-part message and that more message
|
1148
|
+
* parts are to follow. When the application wishes to send the final message
|
1149
|
+
* part it does so by calling send() without the ZMQ::SNDMORE flag; this
|
1150
|
+
* indicates that no more message parts are to follow.
|
1151
|
+
*
|
1152
|
+
* This function returns _true_ if successful, _false_ if not.
|
1153
|
+
*/
|
1154
|
+
static VALUE socket_send (int argc_, VALUE* argv_, VALUE self_)
|
1155
|
+
{
|
1156
|
+
VALUE msg_, flags_;
|
1157
|
+
|
1158
|
+
rb_scan_args (argc_, argv_, "11", &msg_, &flags_);
|
1159
|
+
|
1160
|
+
void * s;
|
1161
|
+
Data_Get_Struct (self_, void, s);
|
1162
|
+
Check_Socket (s);
|
1163
|
+
|
1164
|
+
Check_Type (msg_, T_STRING);
|
1165
|
+
|
1166
|
+
int flags = NIL_P (flags_) ? 0 : NUM2INT (flags_);
|
1167
|
+
|
1168
|
+
zmq_msg_t msg;
|
1169
|
+
int rc = zmq_msg_init_size (&msg, RSTRING_LEN (msg_));
|
1170
|
+
if (rc != 0) {
|
1171
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ()));
|
1172
|
+
return Qnil;
|
1173
|
+
}
|
1174
|
+
memcpy (zmq_msg_data (&msg), RSTRING_PTR (msg_), RSTRING_LEN (msg_));
|
1175
|
+
|
1176
|
+
#ifdef HAVE_RUBY_INTERN_H
|
1177
|
+
if (!(flags & ZMQ_NOBLOCK)) {
|
1178
|
+
struct zmq_send_recv_args send_args;
|
1179
|
+
send_args.socket = s;
|
1180
|
+
send_args.msg = &msg;
|
1181
|
+
send_args.flags = flags;
|
1182
|
+
rb_thread_blocking_region (zmq_send_blocking, (void*) &send_args, NULL, NULL);
|
1183
|
+
rc = send_args.rc;
|
1184
|
+
}
|
1185
|
+
else
|
1186
|
+
#endif
|
1187
|
+
rc = zmq_send (s, &msg, flags);
|
1188
|
+
if (rc != 0 && zmq_errno () == EAGAIN) {
|
1189
|
+
rc = zmq_msg_close (&msg);
|
1190
|
+
assert (rc == 0);
|
1191
|
+
return Qfalse;
|
1192
|
+
}
|
1193
|
+
|
1194
|
+
if (rc != 0) {
|
1195
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ()));
|
1196
|
+
rc = zmq_msg_close (&msg);
|
1197
|
+
assert (rc == 0);
|
1198
|
+
return Qnil;
|
1199
|
+
}
|
1200
|
+
|
1201
|
+
rc = zmq_msg_close (&msg);
|
1202
|
+
assert (rc == 0);
|
1203
|
+
return Qtrue;
|
1204
|
+
}
|
1205
|
+
|
1206
|
+
#ifdef HAVE_RUBY_INTERN_H
|
1207
|
+
static VALUE zmq_recv_blocking (void* args_)
|
1208
|
+
{
|
1209
|
+
struct zmq_send_recv_args *recv_args = (struct zmq_send_recv_args *)args_;
|
1210
|
+
|
1211
|
+
recv_args->rc = zmq_recv(recv_args->socket, recv_args->msg, recv_args->flags);
|
1212
|
+
|
1213
|
+
return Qnil;
|
1214
|
+
}
|
1215
|
+
#endif
|
1216
|
+
|
1217
|
+
/*
|
1218
|
+
* call-seq:
|
1219
|
+
* socket.recv(flags=0) -> message | nil
|
1220
|
+
*
|
1221
|
+
* Receives a message from the _socket_. If there are no messages available
|
1222
|
+
* on the _socket_, the recv() function shall block until the request can be
|
1223
|
+
* satisfied. The _flags_ argument is a combination of the flags defined
|
1224
|
+
* below:
|
1225
|
+
*
|
1226
|
+
* [ZMQ::NOBLOCK] Specifies that the operation should be performed in non-blocking mode. If there are no messages available on the _socket_, the recv() function shall fail and return _nil_.
|
1227
|
+
*
|
1228
|
+
* == Multi-part messages
|
1229
|
+
* A 0MQ message is composed of 1 or more message parts. 0MQ ensures atomic
|
1230
|
+
* delivery of messages; peers shall receive either all <em>message parts</em> of a
|
1231
|
+
* message or none at all.
|
1232
|
+
*
|
1233
|
+
* The total number of message parts is unlimited.
|
1234
|
+
*
|
1235
|
+
* An application wishing to determine if a message is composed of multiple
|
1236
|
+
* parts does so by retrieving the value of the ZMQ::RCVMORE socket option on the
|
1237
|
+
* socket it is receiving the message from, using getsockopt(). If there are no
|
1238
|
+
* message parts to follow, or if the message is not composed of multiple parts,
|
1239
|
+
* ZMQ::RCVMORE shall report a value of false. Otherwise, ZMQ::RCVMORE shall
|
1240
|
+
* report a value of true, indicating that more message parts are to follow.
|
1241
|
+
*/
|
1242
|
+
static VALUE socket_recv (int argc_, VALUE* argv_, VALUE self_)
|
1243
|
+
{
|
1244
|
+
VALUE flags_;
|
1245
|
+
|
1246
|
+
rb_scan_args (argc_, argv_, "01", &flags_);
|
1247
|
+
|
1248
|
+
void * s;
|
1249
|
+
Data_Get_Struct (self_, void, s);
|
1250
|
+
Check_Socket (s);
|
1251
|
+
|
1252
|
+
int flags = NIL_P (flags_) ? 0 : NUM2INT (flags_);
|
1253
|
+
|
1254
|
+
zmq_msg_t msg;
|
1255
|
+
int rc = zmq_msg_init (&msg);
|
1256
|
+
assert (rc == 0);
|
1257
|
+
|
1258
|
+
#ifdef HAVE_RUBY_INTERN_H
|
1259
|
+
if (!(flags & ZMQ_NOBLOCK)) {
|
1260
|
+
struct zmq_send_recv_args recv_args;
|
1261
|
+
recv_args.socket = s;
|
1262
|
+
recv_args.msg = &msg;
|
1263
|
+
recv_args.flags = flags;
|
1264
|
+
rb_thread_blocking_region (zmq_recv_blocking, (void*) &recv_args, NULL, NULL);
|
1265
|
+
rc = recv_args.rc;
|
1266
|
+
}
|
1267
|
+
else
|
1268
|
+
#endif
|
1269
|
+
rc = zmq_recv (s, &msg, flags);
|
1270
|
+
if (rc != 0 && zmq_errno () == EAGAIN) {
|
1271
|
+
rc = zmq_msg_close (&msg);
|
1272
|
+
assert (rc == 0);
|
1273
|
+
return Qnil;
|
1274
|
+
}
|
1275
|
+
|
1276
|
+
if (rc != 0) {
|
1277
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ()));
|
1278
|
+
rc = zmq_msg_close (&msg);
|
1279
|
+
assert (rc == 0);
|
1280
|
+
return Qnil;
|
1281
|
+
}
|
1282
|
+
|
1283
|
+
VALUE message = rb_str_new ((char*) zmq_msg_data (&msg),
|
1284
|
+
zmq_msg_size (&msg));
|
1285
|
+
rc = zmq_msg_close (&msg);
|
1286
|
+
assert (rc == 0);
|
1287
|
+
return message;
|
1288
|
+
}
|
1289
|
+
|
1290
|
+
/*
|
1291
|
+
* call-seq:
|
1292
|
+
* socket.close() -> nil
|
1293
|
+
*
|
1294
|
+
* Destroys the 0MQ socket. All active connections on the socket shall be
|
1295
|
+
* terminated, and resources associated with the socket shall be released.
|
1296
|
+
* Any outstanding messages sent with send() but not yet physically sent
|
1297
|
+
* to the network shall be dropped. Likewise, any outstanding messages
|
1298
|
+
* physically received from the network but not yet received by the
|
1299
|
+
* application with recv() shall also be dropped.
|
1300
|
+
*/
|
1301
|
+
static VALUE socket_close (VALUE self_)
|
1302
|
+
{
|
1303
|
+
void * s = NULL;
|
1304
|
+
Data_Get_Struct (self_, void, s);
|
1305
|
+
if (s != NULL) {
|
1306
|
+
int rc = zmq_close (s);
|
1307
|
+
if (rc != 0) {
|
1308
|
+
rb_raise (rb_eRuntimeError, "%s", zmq_strerror (zmq_errno ()));
|
1309
|
+
return Qnil;
|
1310
|
+
}
|
1311
|
+
|
1312
|
+
DATA_PTR (self_) = NULL;
|
1313
|
+
}
|
1314
|
+
return Qnil;
|
1315
|
+
}
|
1316
|
+
|
1317
|
+
void Init_zmq ()
|
1318
|
+
{
|
1319
|
+
VALUE zmq_module = rb_define_module ("ZMQ");
|
1320
|
+
rb_define_singleton_method (zmq_module, "version", module_version, 0);
|
1321
|
+
rb_define_singleton_method (zmq_module, "select", module_select, -1);
|
1322
|
+
|
1323
|
+
VALUE context_type = rb_define_class_under (zmq_module, "Context",
|
1324
|
+
rb_cObject);
|
1325
|
+
rb_define_alloc_func (context_type, context_alloc);
|
1326
|
+
rb_define_method (context_type, "initialize", context_initialize, -1);
|
1327
|
+
rb_define_method (context_type, "socket", context_socket, 1);
|
1328
|
+
rb_define_method (context_type, "close", context_close, 0);
|
1329
|
+
|
1330
|
+
socket_type = rb_define_class_under (zmq_module, "Socket", rb_cObject);
|
1331
|
+
rb_undef_alloc_func(socket_type);
|
1332
|
+
rb_define_method (socket_type, "getsockopt", socket_getsockopt, 1);
|
1333
|
+
rb_define_method (socket_type, "setsockopt", socket_setsockopt, 2);
|
1334
|
+
rb_define_method (socket_type, "bind", socket_bind, 1);
|
1335
|
+
rb_define_method (socket_type, "connect", socket_connect, 1);
|
1336
|
+
rb_define_method (socket_type, "send", socket_send, -1);
|
1337
|
+
rb_define_method (socket_type, "recv", socket_recv, -1);
|
1338
|
+
rb_define_method (socket_type, "close", socket_close, 0);
|
1339
|
+
|
1340
|
+
rb_define_const (zmq_module, "HWM", INT2NUM (ZMQ_HWM));
|
1341
|
+
rb_define_const (zmq_module, "SWAP", INT2NUM (ZMQ_SWAP));
|
1342
|
+
rb_define_const (zmq_module, "AFFINITY", INT2NUM (ZMQ_AFFINITY));
|
1343
|
+
rb_define_const (zmq_module, "IDENTITY", INT2NUM (ZMQ_IDENTITY));
|
1344
|
+
rb_define_const (zmq_module, "SUBSCRIBE", INT2NUM (ZMQ_SUBSCRIBE));
|
1345
|
+
rb_define_const (zmq_module, "UNSUBSCRIBE", INT2NUM (ZMQ_UNSUBSCRIBE));
|
1346
|
+
rb_define_const (zmq_module, "RATE", INT2NUM (ZMQ_RATE));
|
1347
|
+
rb_define_const (zmq_module, "RECOVERY_IVL", INT2NUM (ZMQ_RECOVERY_IVL));
|
1348
|
+
rb_define_const (zmq_module, "MCAST_LOOP", INT2NUM (ZMQ_MCAST_LOOP));
|
1349
|
+
rb_define_const (zmq_module, "SNDBUF", INT2NUM (ZMQ_SNDBUF));
|
1350
|
+
rb_define_const (zmq_module, "RCVBUF", INT2NUM (ZMQ_RCVBUF));
|
1351
|
+
rb_define_const (zmq_module, "SNDMORE", INT2NUM (ZMQ_SNDMORE));
|
1352
|
+
rb_define_const (zmq_module, "RCVMORE", INT2NUM (ZMQ_RCVMORE));
|
1353
|
+
|
1354
|
+
rb_define_const (zmq_module, "NOBLOCK", INT2NUM (ZMQ_NOBLOCK));
|
1355
|
+
|
1356
|
+
rb_define_const (zmq_module, "PAIR", INT2NUM (ZMQ_PAIR));
|
1357
|
+
rb_define_const (zmq_module, "SUB", INT2NUM (ZMQ_SUB));
|
1358
|
+
rb_define_const (zmq_module, "PUB", INT2NUM (ZMQ_PUB));
|
1359
|
+
rb_define_const (zmq_module, "REQ", INT2NUM (ZMQ_REQ));
|
1360
|
+
rb_define_const (zmq_module, "REP", INT2NUM (ZMQ_REP));
|
1361
|
+
rb_define_const (zmq_module, "XREQ", INT2NUM (ZMQ_XREQ));
|
1362
|
+
rb_define_const (zmq_module, "XREP", INT2NUM (ZMQ_XREP));
|
1363
|
+
rb_define_const (zmq_module, "UPSTREAM", INT2NUM (ZMQ_UPSTREAM));
|
1364
|
+
rb_define_const (zmq_module, "DOWNSTREAM", INT2NUM (ZMQ_DOWNSTREAM));
|
1365
|
+
}
|