ezmq 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/ezmq.gemspec +1 -1
- data/lib/ezmq.rb +7 -292
- data/lib/ezmq/publish.rb +31 -0
- data/lib/ezmq/pull.rb +19 -0
- data/lib/ezmq/push.rb +19 -0
- data/lib/ezmq/reply.rb +39 -0
- data/lib/ezmq/request.rb +36 -0
- data/lib/ezmq/socket.rb +121 -0
- data/lib/ezmq/subscribe.rb +96 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e62170a8e52ab7093f6d608ec8181d94d5370723
|
4
|
+
data.tar.gz: acf0e8b894d6b6b5781be637f7c50c04223c567a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8d4e7d8f6792d97b5243ec2ae688d90cef0d5a4fca49026eced158882ec72ebd0284db90896fda8a0d542e9bdc71a9d03b7d67ef837065d6471907c63e86795
|
7
|
+
data.tar.gz: 2a54c39341debddb86cffb3a4d238fc996fd40e2e5895afdfe28b5b5faef819771d70f999a07eb6feb755000e54fe0afac32a44cd0616c3bbce78566dba16255
|
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
[EZMQ (Effortless ZeroMQ)](https://colstrom.github.io/ezmq/)
|
2
2
|
========================
|
3
3
|
|
4
|
+
[](http://badge.fury.io/rb/ezmq)
|
5
|
+
[](https://gemnasium.com/colstrom/ezmq)
|
6
|
+
[](https://codeclimate.com/github/colstrom/ezmq)
|
7
|
+
|
4
8
|
Overview
|
5
9
|
--------
|
6
10
|
|
@@ -82,10 +86,10 @@ Publishes an endless stream of 'foo's with a topic of 'foorever'.
|
|
82
86
|
```
|
83
87
|
require 'ezmq'
|
84
88
|
|
85
|
-
publisher = EZMQ.Publisher.new
|
89
|
+
publisher = EZMQ.Publisher.new
|
86
90
|
|
87
91
|
loop do
|
88
|
-
publisher.send 'foo'
|
92
|
+
publisher.send 'foo', topic: 'foorever'
|
89
93
|
end
|
90
94
|
```
|
91
95
|
|
data/ezmq.gemspec
CHANGED
data/lib/ezmq.rb
CHANGED
@@ -1,293 +1,8 @@
|
|
1
1
|
require 'ffi-rzmq'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# Creates a 0MQ socket.
|
10
|
-
#
|
11
|
-
# @param [:bind, :connect] mode the mode of the socket.
|
12
|
-
# @param [Object] type the type of socket to use.
|
13
|
-
# @param [Hash] options optional parameters.
|
14
|
-
#
|
15
|
-
# @option options [ZMQ::Context] context a context to use for this socket
|
16
|
-
# (one will be created if not provided).
|
17
|
-
# @option options [lambda] encode how to encode messages.
|
18
|
-
# @option options [lambda] decode how to decode messages.
|
19
|
-
# @option options [String] protocol ('tcp') protocol for transport.
|
20
|
-
# @option options [String] address ('127.0.0.1') address for endpoint.
|
21
|
-
# @option options [Fixnum] port (5555) port for endpoint.
|
22
|
-
# @note port is ignored unless protocol is either 'tcp' or 'udp'.
|
23
|
-
#
|
24
|
-
# @return [Socket] a new instance of Socket.
|
25
|
-
#
|
26
|
-
def initialize(mode, type, **options)
|
27
|
-
fail ArgumentError unless [:bind, :connect].include? mode
|
28
|
-
@context = options[:context] || ZMQ::Context.new
|
29
|
-
@socket = @context.socket type
|
30
|
-
@encode = options[:encode] || -> m { m }
|
31
|
-
@decode = options[:decode] || -> m { m }
|
32
|
-
endpoint = options.select { |k, _| [:protocol, :address, :port].include? k }
|
33
|
-
method(mode).call endpoint
|
34
|
-
end
|
35
|
-
|
36
|
-
# Sends a message to the socket.
|
37
|
-
#
|
38
|
-
# @note If message is not a String, #encode must convert it to one.
|
39
|
-
#
|
40
|
-
# @param [String] message the message to send.
|
41
|
-
# @param [Hash] options optional parameters.
|
42
|
-
# @option options [lambda] encode how to encode the message.
|
43
|
-
#
|
44
|
-
# @return [Fixnum] the size of the message.
|
45
|
-
#
|
46
|
-
def send(message = '', **options)
|
47
|
-
encoded = (options[:encode] || @encode).call message
|
48
|
-
@socket.send_string encoded
|
49
|
-
end
|
50
|
-
|
51
|
-
# Receive a message from the socket.
|
52
|
-
#
|
53
|
-
# @note This method blocks until a message arrives.
|
54
|
-
#
|
55
|
-
# @param [Hash] options optional parameters.
|
56
|
-
# @option options [lambda] decode how to decode the message.
|
57
|
-
#
|
58
|
-
# @yield message passes the message received to the block.
|
59
|
-
# @yieldparam [Object] message the message received (decoded).
|
60
|
-
#
|
61
|
-
# @return [Object] the message received (decoded).
|
62
|
-
#
|
63
|
-
def receive(**options)
|
64
|
-
message = ''
|
65
|
-
@socket.recv_string message
|
66
|
-
decoded = (options[:decode] || @decode).call message
|
67
|
-
if block_given?
|
68
|
-
yield decoded
|
69
|
-
else
|
70
|
-
decoded
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# Binds the socket to the given address.
|
75
|
-
#
|
76
|
-
# @param [String] protocol ('tcp') protocol for transport.
|
77
|
-
# @param [String] address ('127.0.0.1') address for endpoint.
|
78
|
-
# @note An address of 'localhost' is not reliable on all platforms.
|
79
|
-
# Prefer '127.0.0.1' instead.
|
80
|
-
# @param [Fixnum] port (5555) port for endpoint.
|
81
|
-
# @note port is ignored unless protocol is either 'tcp' or 'udp'.
|
82
|
-
#
|
83
|
-
# @return [Boolean] was binding successful?
|
84
|
-
#
|
85
|
-
def bind(protocol: 'tcp', address: '127.0.0.1', port: 5555)
|
86
|
-
endpoint = "#{ protocol }://#{ address }"
|
87
|
-
endpoint = "#{ endpoint }:#{ port }" if %w(tcp udp).include? protocol
|
88
|
-
@socket.bind(endpoint) == 0
|
89
|
-
end
|
90
|
-
|
91
|
-
# Connects the socket to the given address.
|
92
|
-
#
|
93
|
-
# @param [String] protocol ('tcp') protocol for transport.
|
94
|
-
# @param [String] address ('127.0.0.1') address for endpoint.
|
95
|
-
# @param [Fixnum] port (5555) port for endpoint.
|
96
|
-
# @note port is ignored unless protocol is either 'tcp' or 'udp'.
|
97
|
-
#
|
98
|
-
# @return [Boolean] was connection successful?
|
99
|
-
#
|
100
|
-
def connect(protocol: 'tcp', address: '127.0.0.1', port: 5555)
|
101
|
-
endpoint = "#{ protocol }://#{ address }"
|
102
|
-
endpoint = "#{ endpoint }:#{ port }" if %w(tcp udp).include? protocol
|
103
|
-
@socket.connect(endpoint) == 0
|
104
|
-
end
|
105
|
-
|
106
|
-
# By default, waits for a message and prints it to STDOUT.
|
107
|
-
#
|
108
|
-
# @yield message passes the message received to the block.
|
109
|
-
# @yieldparam [String] message the message received.
|
110
|
-
#
|
111
|
-
# @return [void]
|
112
|
-
#
|
113
|
-
def listen
|
114
|
-
loop do
|
115
|
-
if block_given?
|
116
|
-
yield receive
|
117
|
-
else
|
118
|
-
puts receive
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# Request socket that sends messages and receives replies.
|
125
|
-
class Client < EZMQ::Socket
|
126
|
-
# Creates a new Client socket.
|
127
|
-
#
|
128
|
-
# @param [Hash] options optional parameters.
|
129
|
-
# @see EZMQ::Socket EZMQ::Socket for optional parameters.
|
130
|
-
#
|
131
|
-
# @return [Client] a new instance of Client.
|
132
|
-
#
|
133
|
-
def initialize(**options)
|
134
|
-
super :connect, ZMQ::REQ, options
|
135
|
-
end
|
136
|
-
|
137
|
-
# Sends a message and waits to receive a response.
|
138
|
-
#
|
139
|
-
# @param [String] message the message to send.
|
140
|
-
# @param [Hash] options optional parameters.
|
141
|
-
# @option options [lambda] encode how to encode the message.
|
142
|
-
# @option options [lambda] decode how to decode the message.
|
143
|
-
#
|
144
|
-
# @return [void] the decoded response message.
|
145
|
-
#
|
146
|
-
def request(message = '', **options)
|
147
|
-
send message, options
|
148
|
-
if block_given?
|
149
|
-
yield receive options
|
150
|
-
else
|
151
|
-
receive options
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
# Reply socket that listens for and replies to requests.
|
157
|
-
class Server < EZMQ::Socket
|
158
|
-
# Creates a new Server socket.
|
159
|
-
#
|
160
|
-
# @param [Hash] options optional parameters
|
161
|
-
#
|
162
|
-
# @see EZMQ::Socket EZMQ::Socket for optional parameters.
|
163
|
-
#
|
164
|
-
# @return [Server] a new instance of Server
|
165
|
-
#
|
166
|
-
def initialize(**options)
|
167
|
-
super :bind, ZMQ::REP, options
|
168
|
-
end
|
169
|
-
|
170
|
-
# Listens for a request, and responds to it.
|
171
|
-
#
|
172
|
-
# If no block is given, responds with the request message.
|
173
|
-
#
|
174
|
-
# @yield message passes the message received to the block.
|
175
|
-
# @yieldparam [String] message the message received.
|
176
|
-
# @yieldreturn [void] the message to reply with.
|
177
|
-
#
|
178
|
-
# @return [void] the return from handler.
|
179
|
-
#
|
180
|
-
def listen
|
181
|
-
loop do
|
182
|
-
if block_given?
|
183
|
-
send yield receive
|
184
|
-
else
|
185
|
-
send receive
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
# Publish socket that broadcasts messages with an optional topic.
|
192
|
-
class Publisher < EZMQ::Socket
|
193
|
-
# Creates a new Publisher socket.
|
194
|
-
#
|
195
|
-
# @param [Hash] options optional parameters.
|
196
|
-
# @see EZMQ::Socket EZMQ::Socket for optional parameters.
|
197
|
-
#
|
198
|
-
# @return [Publisher] a new instance of Publisher.
|
199
|
-
#
|
200
|
-
def initialize(**options)
|
201
|
-
super :bind, ZMQ::PUB, options
|
202
|
-
end
|
203
|
-
|
204
|
-
# Sends a message on the socket, with an optional topic.
|
205
|
-
#
|
206
|
-
# @param [String] message the message to send.
|
207
|
-
# @param [String] topic an optional topic for the message.
|
208
|
-
# @param [Hash] options optional parameters.
|
209
|
-
# @option options [lambda] encode how to encode the message.
|
210
|
-
#
|
211
|
-
# @return [Fixnum] the size of the message.
|
212
|
-
#
|
213
|
-
def send(message = '', topic: '', **options)
|
214
|
-
@socket.send_string "#{ topic } #{ (options[:encode] || @encode).call message }"
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
# Subscribe socket that listens for messages with an optional topic.
|
219
|
-
class Subscriber < EZMQ::Socket
|
220
|
-
attr_accessor :action
|
221
|
-
|
222
|
-
# Creates a new Subscriber socket.
|
223
|
-
#
|
224
|
-
# @note The default behaviour is to output and messages received to STDOUT.
|
225
|
-
#
|
226
|
-
# @param [Hash] options optional parameters.
|
227
|
-
# @option options [String] topic a topic to subscribe to.
|
228
|
-
# @see EZMQ::Socket EZMQ::Socket for optional parameters.
|
229
|
-
#
|
230
|
-
# @return [Publisher] a new instance of Publisher.
|
231
|
-
#
|
232
|
-
def initialize(**options)
|
233
|
-
super :connect, ZMQ::SUB, options
|
234
|
-
subscribe options[:topic] if options[:topic]
|
235
|
-
end
|
236
|
-
|
237
|
-
# Establishes a new message filter on the socket.
|
238
|
-
#
|
239
|
-
# @note By default, a Subscriber filters all incoming messages. Without
|
240
|
-
# calling subscribe at least once, no messages will be accepted. If topic
|
241
|
-
# was provided, #initialize calls #subscribe automatically.
|
242
|
-
#
|
243
|
-
# @param [String] topic a topic to subscribe to. Messages matching this
|
244
|
-
# prefix will be accepted.
|
245
|
-
#
|
246
|
-
# @return [Boolean] was subscription successful?
|
247
|
-
#
|
248
|
-
def subscribe(topic)
|
249
|
-
@socket.setsockopt(ZMQ::SUBSCRIBE, topic) == 0
|
250
|
-
end
|
251
|
-
|
252
|
-
# Removes a message filter (as set with subscribe) from the socket.
|
253
|
-
#
|
254
|
-
# @param [String] topic the topic to unsubscribe from. If multiple filters
|
255
|
-
# with the same topic are set, this will only remove one.
|
256
|
-
#
|
257
|
-
# @return [Boolean] was unsubscription successful?
|
258
|
-
#
|
259
|
-
def unsubscribe(topic)
|
260
|
-
@socket.setsockopt(ZMQ::UNSUBSCRIBE, topic) == 0
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
# Push socket that sends messages but does not receive them.
|
265
|
-
class Pusher < EZMQ::Socket
|
266
|
-
# Creates a new Pusher socket.
|
267
|
-
#
|
268
|
-
# @param [:bind, :connect] mode a mode for the socket.
|
269
|
-
# @param [Hash] options optional parameters.
|
270
|
-
# @see EZMQ::Socket EZMQ::Socket for optional parameters.
|
271
|
-
#
|
272
|
-
# @return [Pusher] a new instance of Pusher.
|
273
|
-
#
|
274
|
-
def initialize(mode = :connect, **options)
|
275
|
-
super mode, ZMQ::PUSH, options
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
# Pull socket that receives messages but does not send them.
|
280
|
-
class Puller < EZMQ::Socket
|
281
|
-
# Creates a new Puller socket.
|
282
|
-
#
|
283
|
-
# @param [:bind, :connect] mode a mode for the socket.
|
284
|
-
# @param [Hash] options optional parameters.
|
285
|
-
# @see EZMQ::Socket EZMQ::Socket for optional parameters.
|
286
|
-
#
|
287
|
-
# @return [Puller] a new instance of Puller.
|
288
|
-
#
|
289
|
-
def initialize(mode = :bind, **options)
|
290
|
-
super mode, ZMQ::PULL, options
|
291
|
-
end
|
292
|
-
end
|
293
|
-
end
|
2
|
+
require_relative 'ezmq/socket'
|
3
|
+
require_relative 'ezmq/request'
|
4
|
+
require_relative 'ezmq/reply'
|
5
|
+
require_relative 'ezmq/publish'
|
6
|
+
require_relative 'ezmq/subscribe'
|
7
|
+
require_relative 'ezmq/push'
|
8
|
+
require_relative 'ezmq/pull'
|
data/lib/ezmq/publish.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative 'socket'
|
2
|
+
|
3
|
+
# Syntactic sugar for 0MQ, because Ruby shouldn't feel like C.
|
4
|
+
module EZMQ
|
5
|
+
# Publish socket that broadcasts messages with an optional topic.
|
6
|
+
class Publisher < EZMQ::Socket
|
7
|
+
# Creates a new Publisher socket.
|
8
|
+
#
|
9
|
+
# @param [Hash] options optional parameters.
|
10
|
+
# @see EZMQ::Socket EZMQ::Socket for optional parameters.
|
11
|
+
#
|
12
|
+
# @return [Publisher] a new instance of Publisher.
|
13
|
+
#
|
14
|
+
def initialize(**options)
|
15
|
+
super :bind, ZMQ::PUB, options
|
16
|
+
end
|
17
|
+
|
18
|
+
# Sends a message on the socket, with an optional topic.
|
19
|
+
#
|
20
|
+
# @param [String] message the message to send.
|
21
|
+
# @param [String] topic an optional topic for the message.
|
22
|
+
# @param [Hash] options optional parameters.
|
23
|
+
# @option options [lambda] encode how to encode the message.
|
24
|
+
#
|
25
|
+
# @return [Fixnum] the size of the message.
|
26
|
+
#
|
27
|
+
def send(message = '', topic: '', **options)
|
28
|
+
@socket.send_string "#{ topic } #{ (options[:encode] || @encode).call message }"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/ezmq/pull.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'socket'
|
2
|
+
|
3
|
+
# Syntactic sugar for 0MQ, because Ruby shouldn't feel like C.
|
4
|
+
module EZMQ
|
5
|
+
# Pull socket that receives messages but does not send them.
|
6
|
+
class Puller < EZMQ::Socket
|
7
|
+
# Creates a new Puller socket.
|
8
|
+
#
|
9
|
+
# @param [:bind, :connect] mode a mode for the socket.
|
10
|
+
# @param [Hash] options optional parameters.
|
11
|
+
# @see EZMQ::Socket EZMQ::Socket for optional parameters.
|
12
|
+
#
|
13
|
+
# @return [Puller] a new instance of Puller.
|
14
|
+
#
|
15
|
+
def initialize(mode = :bind, **options)
|
16
|
+
super mode, ZMQ::PULL, options
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/ezmq/push.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'socket'
|
2
|
+
|
3
|
+
# Syntactic sugar for 0MQ, because Ruby shouldn't feel like C.
|
4
|
+
module EZMQ
|
5
|
+
# Push socket that sends messages but does not receive them.
|
6
|
+
class Pusher < EZMQ::Socket
|
7
|
+
# Creates a new Pusher socket.
|
8
|
+
#
|
9
|
+
# @param [:bind, :connect] mode a mode for the socket.
|
10
|
+
# @param [Hash] options optional parameters.
|
11
|
+
# @see EZMQ::Socket EZMQ::Socket for optional parameters.
|
12
|
+
#
|
13
|
+
# @return [Pusher] a new instance of Pusher.
|
14
|
+
#
|
15
|
+
def initialize(mode = :connect, **options)
|
16
|
+
super mode, ZMQ::PUSH, options
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/ezmq/reply.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative 'socket'
|
2
|
+
|
3
|
+
# Syntactic sugar for 0MQ, because Ruby shouldn't feel like C.
|
4
|
+
module EZMQ
|
5
|
+
# Reply socket that listens for and replies to requests.
|
6
|
+
class Server < EZMQ::Socket
|
7
|
+
# Creates a new Server socket.
|
8
|
+
#
|
9
|
+
# @param [Hash] options optional parameters
|
10
|
+
#
|
11
|
+
# @see EZMQ::Socket EZMQ::Socket for optional parameters.
|
12
|
+
#
|
13
|
+
# @return [Server] a new instance of Server
|
14
|
+
#
|
15
|
+
def initialize(**options)
|
16
|
+
super :bind, ZMQ::REP, options
|
17
|
+
end
|
18
|
+
|
19
|
+
# Listens for a request, and responds to it.
|
20
|
+
#
|
21
|
+
# If no block is given, responds with the request message.
|
22
|
+
#
|
23
|
+
# @yield message passes the message received to the block.
|
24
|
+
# @yieldparam [String] message the message received.
|
25
|
+
# @yieldreturn [void] the message to reply with.
|
26
|
+
#
|
27
|
+
# @return [void] the return from handler.
|
28
|
+
#
|
29
|
+
def listen
|
30
|
+
loop do
|
31
|
+
if block_given?
|
32
|
+
send yield receive
|
33
|
+
else
|
34
|
+
send receive
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/ezmq/request.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative 'socket'
|
2
|
+
|
3
|
+
# Syntactic sugar for 0MQ, because Ruby shouldn't feel like C.
|
4
|
+
module EZMQ
|
5
|
+
# Request socket that sends messages and receives replies.
|
6
|
+
class Client < EZMQ::Socket
|
7
|
+
# Creates a new Client socket.
|
8
|
+
#
|
9
|
+
# @param [Hash] options optional parameters.
|
10
|
+
# @see EZMQ::Socket EZMQ::Socket for optional parameters.
|
11
|
+
#
|
12
|
+
# @return [Client] a new instance of Client.
|
13
|
+
#
|
14
|
+
def initialize(**options)
|
15
|
+
super :connect, ZMQ::REQ, options
|
16
|
+
end
|
17
|
+
|
18
|
+
# Sends a message and waits to receive a response.
|
19
|
+
#
|
20
|
+
# @param [String] message the message to send.
|
21
|
+
# @param [Hash] options optional parameters.
|
22
|
+
# @option options [lambda] encode how to encode the message.
|
23
|
+
# @option options [lambda] decode how to decode the message.
|
24
|
+
#
|
25
|
+
# @return [void] the decoded response message.
|
26
|
+
#
|
27
|
+
def request(message = '', **options)
|
28
|
+
send message, options
|
29
|
+
if block_given?
|
30
|
+
yield receive options
|
31
|
+
else
|
32
|
+
receive options
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/ezmq/socket.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# Syntactic sugar for 0MQ, because Ruby shouldn't feel like C.
|
2
|
+
module EZMQ
|
3
|
+
# Wrapper class to simplify 0MQ sockets.
|
4
|
+
class Socket
|
5
|
+
attr_accessor :context, :socket, :encode, :decode
|
6
|
+
|
7
|
+
# Creates a 0MQ socket.
|
8
|
+
#
|
9
|
+
# @param [:bind, :connect] mode the mode of the socket.
|
10
|
+
# @param [Object] type the type of socket to use.
|
11
|
+
# @param [Hash] options optional parameters.
|
12
|
+
#
|
13
|
+
# @option options [ZMQ::Context] context a context to use for this socket
|
14
|
+
# (one will be created if not provided).
|
15
|
+
# @option options [lambda] encode how to encode messages.
|
16
|
+
# @option options [lambda] decode how to decode messages.
|
17
|
+
# @option options [String] protocol ('tcp') protocol for transport.
|
18
|
+
# @option options [String] address ('127.0.0.1') address for endpoint.
|
19
|
+
# @option options [Fixnum] port (5555) port for endpoint.
|
20
|
+
# @note port is ignored unless protocol is either 'tcp' or 'udp'.
|
21
|
+
#
|
22
|
+
# @return [Socket] a new instance of Socket.
|
23
|
+
#
|
24
|
+
def initialize(mode, type, **options)
|
25
|
+
fail ArgumentError unless [:bind, :connect].include? mode
|
26
|
+
@context = options[:context] || ZMQ::Context.new
|
27
|
+
@socket = @context.socket type
|
28
|
+
@encode = options[:encode] || -> m { m }
|
29
|
+
@decode = options[:decode] || -> m { m }
|
30
|
+
endpoint = options.select { |k, _| [:protocol, :address, :port].include? k }
|
31
|
+
method(mode).call endpoint
|
32
|
+
end
|
33
|
+
|
34
|
+
# Sends a message to the socket.
|
35
|
+
#
|
36
|
+
# @note If message is not a String, #encode must convert it to one.
|
37
|
+
#
|
38
|
+
# @param [String] message the message to send.
|
39
|
+
# @param [Hash] options optional parameters.
|
40
|
+
# @option options [lambda] encode how to encode the message.
|
41
|
+
#
|
42
|
+
# @return [Fixnum] the size of the message.
|
43
|
+
#
|
44
|
+
def send(message = '', **options)
|
45
|
+
encoded = (options[:encode] || @encode).call message
|
46
|
+
@socket.send_string encoded
|
47
|
+
end
|
48
|
+
|
49
|
+
# Receive a message from the socket.
|
50
|
+
#
|
51
|
+
# @note This method blocks until a message arrives.
|
52
|
+
#
|
53
|
+
# @param [Hash] options optional parameters.
|
54
|
+
# @option options [lambda] decode how to decode the message.
|
55
|
+
#
|
56
|
+
# @yield message passes the message received to the block.
|
57
|
+
# @yieldparam [Object] message the message received (decoded).
|
58
|
+
#
|
59
|
+
# @return [Object] the message received (decoded).
|
60
|
+
#
|
61
|
+
def receive(**options)
|
62
|
+
message = ''
|
63
|
+
@socket.recv_string message
|
64
|
+
decoded = (options[:decode] || @decode).call message
|
65
|
+
if block_given?
|
66
|
+
yield decoded
|
67
|
+
else
|
68
|
+
decoded
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Binds the socket to the given address.
|
73
|
+
#
|
74
|
+
# @param [String] protocol ('tcp') protocol for transport.
|
75
|
+
# @param [String] address ('127.0.0.1') address for endpoint.
|
76
|
+
# @note An address of 'localhost' is not reliable on all platforms.
|
77
|
+
# Prefer '127.0.0.1' instead.
|
78
|
+
# @param [Fixnum] port (5555) port for endpoint.
|
79
|
+
# @note port is ignored unless protocol is either 'tcp' or 'udp'.
|
80
|
+
#
|
81
|
+
# @return [Boolean] was binding successful?
|
82
|
+
#
|
83
|
+
def bind(protocol: 'tcp', address: '127.0.0.1', port: 5555)
|
84
|
+
endpoint = "#{ protocol }://#{ address }"
|
85
|
+
endpoint = "#{ endpoint }:#{ port }" if %w(tcp udp).include? protocol
|
86
|
+
@socket.bind(endpoint) == 0
|
87
|
+
end
|
88
|
+
|
89
|
+
# Connects the socket to the given address.
|
90
|
+
#
|
91
|
+
# @param [String] protocol ('tcp') protocol for transport.
|
92
|
+
# @param [String] address ('127.0.0.1') address for endpoint.
|
93
|
+
# @param [Fixnum] port (5555) port for endpoint.
|
94
|
+
# @note port is ignored unless protocol is either 'tcp' or 'udp'.
|
95
|
+
#
|
96
|
+
# @return [Boolean] was connection successful?
|
97
|
+
#
|
98
|
+
def connect(protocol: 'tcp', address: '127.0.0.1', port: 5555)
|
99
|
+
endpoint = "#{ protocol }://#{ address }"
|
100
|
+
endpoint = "#{ endpoint }:#{ port }" if %w(tcp udp).include? protocol
|
101
|
+
@socket.connect(endpoint) == 0
|
102
|
+
end
|
103
|
+
|
104
|
+
# By default, waits for a message and prints it to STDOUT.
|
105
|
+
#
|
106
|
+
# @yield message passes the message received to the block.
|
107
|
+
# @yieldparam [String] message the message received.
|
108
|
+
#
|
109
|
+
# @return [void]
|
110
|
+
#
|
111
|
+
def listen
|
112
|
+
loop do
|
113
|
+
if block_given?
|
114
|
+
yield receive
|
115
|
+
else
|
116
|
+
puts receive
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require_relative 'socket'
|
2
|
+
|
3
|
+
# Syntactic sugar for 0MQ, because Ruby shouldn't feel like C.
|
4
|
+
module EZMQ
|
5
|
+
# Subscribe socket that listens for messages with an optional topic.
|
6
|
+
class Subscriber < EZMQ::Socket
|
7
|
+
attr_accessor :action
|
8
|
+
|
9
|
+
# Creates a new Subscriber socket.
|
10
|
+
#
|
11
|
+
# @note The default behaviour is to output and messages received to STDOUT.
|
12
|
+
#
|
13
|
+
# @param [Hash] options optional parameters.
|
14
|
+
# @option options [String] topic a topic to subscribe to.
|
15
|
+
# @see EZMQ::Socket EZMQ::Socket for optional parameters.
|
16
|
+
#
|
17
|
+
# @return [Publisher] a new instance of Publisher.
|
18
|
+
#
|
19
|
+
def initialize(**options)
|
20
|
+
super :connect, ZMQ::SUB, options
|
21
|
+
subscribe options[:topic] if options[:topic]
|
22
|
+
end
|
23
|
+
|
24
|
+
# Receive a message from the socket.
|
25
|
+
#
|
26
|
+
# @note This method blocks until a message arrives.
|
27
|
+
#
|
28
|
+
# @param [Hash] options optional parameters.
|
29
|
+
# @option options [lambda] decode how to decode the message.
|
30
|
+
#
|
31
|
+
# @yield [message, topic] passes the message body and topic to the block.
|
32
|
+
# @yieldparam [Object] message the message received (decoded).
|
33
|
+
# @yieldparam [String] topic the topic of the message.
|
34
|
+
#
|
35
|
+
# @return [Object] the message received (decoded).
|
36
|
+
#
|
37
|
+
def receive(**options)
|
38
|
+
message = ''
|
39
|
+
@socket.recv_string message
|
40
|
+
|
41
|
+
message = message.match(/^(?<topic>[^\ ]*)\s(?<body>.*)/)
|
42
|
+
|
43
|
+
decoded = (options[:decode] || @decode).call message['body']
|
44
|
+
if block_given?
|
45
|
+
yield decoded, message['topic']
|
46
|
+
else
|
47
|
+
[decoded, message['topic']]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# By default, waits for a message and prints it to STDOUT.
|
52
|
+
#
|
53
|
+
# @yield [message, topic] passes the message body and topic to the block.
|
54
|
+
# @yieldparam [String] message the message received.
|
55
|
+
# @yieldparam [String] topic the topic of the message.
|
56
|
+
#
|
57
|
+
# @return [void]
|
58
|
+
#
|
59
|
+
def listen
|
60
|
+
loop do
|
61
|
+
if block_given?
|
62
|
+
yield(*receive)
|
63
|
+
else
|
64
|
+
message, topic = receive
|
65
|
+
puts "#{ topic } #{ message }"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Establishes a new message filter on the socket.
|
71
|
+
#
|
72
|
+
# @note By default, a Subscriber filters all incoming messages. Without
|
73
|
+
# calling subscribe at least once, no messages will be accepted. If topic
|
74
|
+
# was provided, #initialize calls #subscribe automatically.
|
75
|
+
#
|
76
|
+
# @param [String] topic a topic to subscribe to. Messages matching this
|
77
|
+
# prefix will be accepted.
|
78
|
+
#
|
79
|
+
# @return [Boolean] was subscription successful?
|
80
|
+
#
|
81
|
+
def subscribe(topic)
|
82
|
+
@socket.setsockopt(ZMQ::SUBSCRIBE, topic) == 0
|
83
|
+
end
|
84
|
+
|
85
|
+
# Removes a message filter (as set with subscribe) from the socket.
|
86
|
+
#
|
87
|
+
# @param [String] topic the topic to unsubscribe from. If multiple filters
|
88
|
+
# with the same topic are set, this will only remove one.
|
89
|
+
#
|
90
|
+
# @return [Boolean] was unsubscription successful?
|
91
|
+
#
|
92
|
+
def unsubscribe(topic)
|
93
|
+
@socket.setsockopt(ZMQ::UNSUBSCRIBE, topic) == 0
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ezmq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Olstrom
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi-rzmq
|
@@ -187,6 +187,13 @@ files:
|
|
187
187
|
- doc/top-level-namespace.html
|
188
188
|
- ezmq.gemspec
|
189
189
|
- lib/ezmq.rb
|
190
|
+
- lib/ezmq/publish.rb
|
191
|
+
- lib/ezmq/pull.rb
|
192
|
+
- lib/ezmq/push.rb
|
193
|
+
- lib/ezmq/reply.rb
|
194
|
+
- lib/ezmq/request.rb
|
195
|
+
- lib/ezmq/socket.rb
|
196
|
+
- lib/ezmq/subscribe.rb
|
190
197
|
homepage: http://colstrom.github.io/ezmq/
|
191
198
|
licenses:
|
192
199
|
- MIT
|