em-zeromq 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -53,50 +53,25 @@ flag api changes but be aware that small changes can still occur between release
53
53
 
54
54
  ## Example ##
55
55
  ```ruby
56
- require 'rubygems'
57
56
  require 'em-zeromq'
58
57
 
59
- class EMTestPullHandler
60
- attr_reader :received
61
- def on_readable(socket, parts)
62
- parts.each do |m|
63
- puts m.copy_out_string
64
- end
65
- end
66
- end
58
+ zmq = EM::ZeroMQ::Context.new(1)
67
59
 
68
- trap('INT') do
69
- EM::stop()
70
- end
60
+ EM.run {
61
+ push = zmq.socket(ZMQ::PUSH)
62
+ push.connect("tcp://127.0.0.1:2091")
71
63
 
72
- ctx = EM::ZeroMQ::Context.new(1)
73
- EM.run do
74
- # setup push sockets
75
- push_socket1 = ctx.socket(ZMQ::PUSH)
76
- push_socket1.bind('tcp://127.0.0.1:2091')
77
-
78
- push_socket2 = ctx.socket(ZMQ::PUSH) do |s|
79
- s.bind('ipc:///tmp/a')
80
- end
81
-
82
- push_socket3 = ctx.socket(ZMQ::PUSH)
83
- push_socket3.bind('inproc://simple_test')
84
-
85
- # setup one pull sockets listening to all push sockets
86
- pull_socket = ctx.socket(ZMQ::PULL, EMTestPullHandler.new)
87
- pull_socket.connect('tcp://127.0.0.1:2091')
88
- pull_socket.connect('ipc:///tmp/a')
89
- pull_socket.connect('inproc://simple_test')
90
-
91
- n = 0
92
-
93
- EM::PeriodicTimer.new(0.1) do
94
- puts '.'
95
- push_socket1.send_msg("t#{n += 1}_")
96
- push_socket2.send_msg("i#{n += 1}_")
97
- push_socket3.send_msg("p#{n += 1}_")
98
- end
99
- end
64
+ pull = zmq.socket(ZMQ::PULL)
65
+ pull.bind("tcp://127.0.0.1:2091")
66
+
67
+ pull.on(:message) { |part|
68
+ puts part.copy_out_string
69
+ }
70
+
71
+ EM.add_periodic_timer(1) {
72
+ push.send_msg("Hello")
73
+ }
74
+ }
100
75
  ```
101
76
 
102
77
  ## License: ##
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
 
16
16
  s.rubyforge_project = "em-zeromq"
17
17
 
18
- s.add_dependency 'eventmachine', '1.0.0.beta.4'
18
+ s.add_dependency 'eventmachine', '>= 1.0.0'
19
19
  s.add_dependency 'ffi', '>= 1.0.0'
20
20
  s.add_dependency 'ffi-rzmq', '0.9.3'
21
21
 
@@ -0,0 +1,31 @@
1
+ # This example shows how one might deal with sending and recieving multi-part
2
+ # messages
3
+
4
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
5
+
6
+ require 'em-zeromq'
7
+
8
+ zmq = EM::ZeroMQ::Context.new(1)
9
+
10
+ EM.run {
11
+ pull = zmq.socket(ZMQ::PULL)
12
+ pull.bind("ipc:///tmp/test")
13
+
14
+ pull.on(:message) { |part1, part2|
15
+ p [:part1, part1.copy_out_string, :part2, part2.copy_out_string]
16
+ }
17
+
18
+ pull.on(:message) { |*parts|
19
+ p [:parts, parts.map(&:copy_out_string)]
20
+ }
21
+
22
+ push = zmq.socket(ZMQ::PUSH)
23
+ push.connect("ipc:///tmp/test")
24
+
25
+ i = 0
26
+ EM.add_periodic_timer(1) {
27
+ puts "Sending 2-part message"
28
+ i += 1
29
+ push.send_msg("hello #{i}", "second part")
30
+ }
31
+ }
@@ -4,23 +4,14 @@ require 'em-zeromq'
4
4
 
5
5
  Thread.abort_on_exception = true
6
6
 
7
- class EMTestPullHandler
8
- attr_reader :received
9
- def on_readable(socket, parts)
10
- parts.each do |m|
11
- puts m.copy_out_string
12
- end
13
- end
14
- end
15
-
16
7
  trap('INT') do
17
8
  EM::stop()
18
9
  end
19
10
 
20
11
  puts "Started (with zmq #{ZMQ::Util.version.join('.')})."
21
12
 
22
-
23
13
  ctx = EM::ZeroMQ::Context.new(1)
14
+
24
15
  EM.run do
25
16
  # setup push sockets
26
17
  push_socket1 = ctx.socket(ZMQ::PUSH)
@@ -30,19 +21,24 @@ EM.run do
30
21
 
31
22
  push_socket1.bind('tcp://127.0.0.1:2091')
32
23
 
33
- push_socket2 = ctx.socket(ZMQ::PUSH) do |s|
34
- s.bind('ipc:///tmp/a')
35
- end
24
+ push_socket2 = ctx.socket(ZMQ::PUSH)
25
+ push_socket2.bind('ipc:///tmp/a')
36
26
 
37
27
  push_socket3 = ctx.socket(ZMQ::PUSH)
38
28
  push_socket3.bind('inproc://simple_test')
39
29
 
40
30
  # setup one pull sockets listening to all push sockets
41
- pull_socket = ctx.socket(ZMQ::PULL, EMTestPullHandler.new)
31
+ pull_socket = ctx.socket(ZMQ::PULL)
42
32
  pull_socket.connect('tcp://127.0.0.1:2091')
43
33
  pull_socket.connect('ipc:///tmp/a')
44
34
  pull_socket.connect('inproc://simple_test')
45
35
 
36
+ pull_socket.on(:message) { |*parts|
37
+ parts.each do |m|
38
+ puts m.copy_out_string
39
+ end
40
+ }
41
+
46
42
  n = 0
47
43
 
48
44
  EM::PeriodicTimer.new(0.1) do
@@ -0,0 +1,23 @@
1
+ # Simpler than simple.rb ;)
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
4
+
5
+ require 'em-zeromq'
6
+
7
+ zmq = EM::ZeroMQ::Context.new(1)
8
+
9
+ EM.run {
10
+ push = zmq.socket(ZMQ::PUSH)
11
+ push.connect("tcp://127.0.0.1:2091")
12
+
13
+ pull = zmq.socket(ZMQ::PULL)
14
+ pull.bind("tcp://127.0.0.1:2091")
15
+
16
+ pull.on(:message) { |part|
17
+ puts part.copy_out_string
18
+ }
19
+
20
+ EM.add_periodic_timer(1) {
21
+ push.send_msg("Hello")
22
+ }
23
+ }
@@ -0,0 +1,23 @@
1
+ # This example shows how to use setsockopt to set the linger period for socket
2
+ # shutdown. This is useful since by default pending meesages will block the
3
+ # termination of the ZMQ context.
4
+
5
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
6
+
7
+ require 'em-zeromq'
8
+
9
+ zmq = EM::ZeroMQ::Context.new(1)
10
+
11
+ EM.run {
12
+ push = zmq.socket(ZMQ::PUSH)
13
+ push.setsockopt(ZMQ::LINGER, 0)
14
+
15
+ push.connect("ipc:///tmp/foo")
16
+
17
+ push.send_msg('hello')
18
+
19
+ Signal.trap('INT') {
20
+ puts 'Trapped INT signal. Stopping eventmachine'
21
+ EM.stop
22
+ }
23
+ }
@@ -3,59 +3,8 @@ require 'ffi-rzmq'
3
3
 
4
4
  module EmZeromq
5
5
 
6
- # :stopdoc:
7
- LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
8
- PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
9
- # :startdoc:
10
-
11
- # Returns the library path for the module. If any arguments are given,
12
- # they will be joined to the end of the libray path using
13
- # <tt>File.join</tt>.
14
- #
15
- def self.libpath( *args, &block )
16
- rv = args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
17
- if block
18
- begin
19
- $LOAD_PATH.unshift LIBPATH
20
- rv = block.call
21
- ensure
22
- $LOAD_PATH.shift
23
- end
24
- end
25
- return rv
26
- end
27
-
28
- # Returns the lpath for the module. If any arguments are given,
29
- # they will be joined to the end of the path using
30
- # <tt>File.join</tt>.
31
- #
32
- def self.path( *args, &block )
33
- rv = args.empty? ? PATH : ::File.join(PATH, args.flatten)
34
- if block
35
- begin
36
- $LOAD_PATH.unshift PATH
37
- rv = block.call
38
- ensure
39
- $LOAD_PATH.shift
40
- end
41
- end
42
- return rv
43
- end
44
-
45
- # Utility method used to require all files ending in .rb that lie in the
46
- # directory below this file that has the same name as the filename passed
47
- # in. Optionally, a specific _directory_ name can be passed in such that
48
- # the _filename_ does not have to be equivalent to the directory.
49
- #
50
- def self.require_all_libs_relative_to( fname, dir = nil )
51
- dir ||= ::File.basename(fname, '.*')
52
- search_me = ::File.expand_path(
53
- ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
54
-
55
- Dir.glob(search_me).sort.each {|rb| require rb}
56
- end
57
-
58
- end # module EmZeromq
59
-
60
- EmZeromq.require_all_libs_relative_to(__FILE__)
6
+ end
61
7
 
8
+ require 'em-zeromq/context'
9
+ require 'em-zeromq/event_emitter'
10
+ require 'em-zeromq/socket'
@@ -7,8 +7,7 @@
7
7
  module EventMachine
8
8
  module ZeroMQ
9
9
  class Context
10
- READABLES = [ ZMQ::SUB, ZMQ::PULL, ZMQ::ROUTER, ZMQ::DEALER, ZMQ::REP, ZMQ::REQ ]
11
- WRITABLES = [ ZMQ::PUB, ZMQ::PUSH, ZMQ::ROUTER, ZMQ::DEALER, ZMQ::REP, ZMQ::REQ ]
10
+
12
11
 
13
12
  def initialize(threads_or_context)
14
13
  if threads_or_context.is_a?(ZMQ::Context)
@@ -24,10 +23,8 @@ module EventMachine
24
23
  # @param [Integer] socket_type One of ZMQ::REQ, ZMQ::REP, ZMQ::PULL, ZMQ::PUSH,
25
24
  # ZMQ::ROUTER, ZMQ::DEALER
26
25
  #
27
- # @param [Object] handler an object which respond to on_readable(socket, parts)
28
- # and can respond to on_writeable(socket)
29
26
  #
30
- def socket(socket_type, handler = nil)
27
+ def socket(socket_type)
31
28
  zmq_socket = @context.socket(socket_type)
32
29
 
33
30
  fd = []
@@ -35,13 +32,7 @@ module EventMachine
35
32
  raise "Unable to get socket FD: #{ZMQ::Util.error_string}"
36
33
  end
37
34
 
38
-
39
- EM.watch(fd[0], EventMachine::ZeroMQ::Socket, zmq_socket, socket_type, handler).tap do |s|
40
- s.register_readable if READABLES.include?(socket_type)
41
- s.register_writable if WRITABLES.include?(socket_type)
42
-
43
- yield(s) if block_given?
44
- end
35
+ EM.watch(fd[0], EventMachine::ZeroMQ::Socket, zmq_socket, socket_type)
45
36
  end
46
37
 
47
38
  end
@@ -0,0 +1,31 @@
1
+ module EventMachine
2
+ module ZeroMQ
3
+ module EventEmitter
4
+ def on(event, &listener)
5
+ _listeners[event] << listener
6
+ end
7
+
8
+ def emit(event, *args)
9
+ _listeners[event].each { |l| l.call(*args) }
10
+ end
11
+
12
+ def remove_listener(event, &listener)
13
+ _listeners[event].delete(listener)
14
+ end
15
+
16
+ def remove_all_listeners(event)
17
+ _listeners.delete(event)
18
+ end
19
+
20
+ def listeners(event)
21
+ _listeners[event]
22
+ end
23
+
24
+ private
25
+
26
+ def _listeners
27
+ @_listeners ||= Hash.new { |h,k| h[k] = [] }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,13 +1,19 @@
1
1
  module EventMachine
2
2
  module ZeroMQ
3
3
  class Socket < EventMachine::Connection
4
- attr_accessor :on_readable, :on_writable, :handler
4
+ READABLES = [ ZMQ::SUB, ZMQ::PULL, ZMQ::ROUTER, ZMQ::DEALER, ZMQ::REP, ZMQ::REQ, ZMQ::PAIR ]
5
+ WRITABLES = [ ZMQ::PUB, ZMQ::PUSH, ZMQ::ROUTER, ZMQ::DEALER, ZMQ::REP, ZMQ::REQ, ZMQ::PAIR ]
6
+
7
+ include EventEmitter
8
+
5
9
  attr_reader :socket, :socket_type
6
10
 
7
- def initialize(socket, socket_type, handler)
11
+ def initialize(socket, socket_type)
8
12
  @socket = socket
9
13
  @socket_type = socket_type
10
- @handler = handler
14
+
15
+ self.notify_readable = true if READABLES.include?(socket_type)
16
+ self.notify_writable = true if WRITABLES.include?(socket_type)
11
17
  end
12
18
 
13
19
  def self.map_sockopt(opt, name)
@@ -96,26 +102,10 @@ module EventMachine
96
102
  def setsockopt(opt, value)
97
103
  @socket.setsockopt(opt, value)
98
104
  end
99
-
100
- # cleanup when ending loop
101
- def unbind
102
- detach_and_close
103
- end
104
-
105
- # Make this socket available for reads
106
- def register_readable
107
- # Since ZMQ is event triggered I think this is necessary
108
- if readable?
109
- notify_readable
110
- end
111
- # Subscribe to EM read notifications
112
- self.notify_readable = true
113
- end
114
105
 
115
- # Trigger on_readable when socket is readable
116
- def register_writable
117
- # Subscribe to EM write notifications
118
- self.notify_writable = true
106
+ def unbind
107
+ detach
108
+ @socket.close
119
109
  end
120
110
 
121
111
  def notify_readable
@@ -124,25 +114,9 @@ module EventMachine
124
114
  # I'm leaving this is because its in the docs, but it could probably
125
115
  # be taken out.
126
116
  return unless readable?
127
-
128
- loop do
129
- msg_parts = []
130
- msg = get_message
131
- if msg
132
- msg_parts << msg
133
- while @socket.more_parts?
134
- msg = get_message
135
- if msg
136
- msg_parts << msg
137
- else
138
- raise "Multi-part message missing a message!"
139
- end
140
- end
141
-
142
- @handler.on_readable(self, msg_parts)
143
- else
144
- break
145
- end
117
+
118
+ while (message = get_message)
119
+ emit(:message, *message)
146
120
  end
147
121
  end
148
122
 
@@ -154,9 +128,7 @@ module EventMachine
154
128
  # write events
155
129
  self.notify_writable = false
156
130
 
157
- if @handler.respond_to?(:on_writable)
158
- @handler.on_writable(self)
159
- end
131
+ emit(:writable)
160
132
  end
161
133
  def readable?
162
134
  (getsockopt(ZMQ::EVENTS) & ZMQ::POLLIN) == ZMQ::POLLIN
@@ -169,20 +141,11 @@ module EventMachine
169
141
  end
170
142
 
171
143
  private
172
-
173
- # internal methods
174
144
 
175
145
  def get_message
176
- msg = ZMQ::Message.new
177
- msg_recvd = @socket.recv(msg, ZMQ::NOBLOCK)
178
- msg_recvd != -1 ? msg : nil
179
- end
180
-
181
- # Detaches the socket from the EM loop,
182
- # then closes the socket
183
- def detach_and_close
184
- detach
185
- @socket.close
146
+ parts = []
147
+ rc = @socket.recvmsgs(parts, ZMQ::NOBLOCK)
148
+ rc >= 0 ? parts : nil
186
149
  end
187
150
  end
188
151
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module EmZeromq
3
- VERSION = "0.3.1"
3
+ VERSION = "0.4.0"
4
4
  end
@@ -1,22 +1,12 @@
1
1
  require File.join(File.dirname(__FILE__), %w[spec_helper])
2
2
 
3
3
  describe EventMachine::ZeroMQ do
4
- class EMTestSubHandler
5
- attr_reader :received
6
- def initialize
7
- @received = []
8
- end
9
- def on_readable(socket, messages)
10
- @received += messages
11
- end
12
- end
13
-
14
4
  it "Should instantiate a connection given valid opts" do
15
5
  sub_conn = nil
16
6
  address = rand_addr
17
7
 
18
- run_reactor(1) do
19
- sub_conn = SPEC_CTX.socket(ZMQ::PUB, EMTestSubHandler.new)
8
+ run_reactor do
9
+ sub_conn = SPEC_CTX.socket(ZMQ::PUB)
20
10
  sub_conn.bind(address)
21
11
  end
22
12
  sub_conn.should be_a(EventMachine::ZeroMQ::Socket)
@@ -24,42 +14,43 @@ describe EventMachine::ZeroMQ do
24
14
 
25
15
  describe "sending/receiving a single message via PUB/SUB" do
26
16
  before(:all) do
27
- results = {}
17
+ @results = {}
18
+ @received = []
28
19
  @test_message = test_message = "TMsg#{rand(999)}"
29
20
 
30
- run_reactor(0.5) do
21
+ run_reactor do
31
22
  address = rand_addr
32
23
 
33
- results[:sub_hndlr] = pull_hndlr = EMTestSubHandler.new
34
- sub_conn = SPEC_CTX.socket(ZMQ::SUB, pull_hndlr)
24
+ sub_conn = SPEC_CTX.socket(ZMQ::SUB)
35
25
  sub_conn.bind(address)
36
26
  sub_conn.subscribe('')
27
+ sub_conn.on(:message) { |m|
28
+ @received << m
29
+ }
37
30
 
38
- pub_conn = SPEC_CTX.socket(ZMQ::PUB, EMTestSubHandler.new)
31
+ pub_conn = SPEC_CTX.socket(ZMQ::PUB)
39
32
  pub_conn.connect(address)
40
33
 
41
34
  pub_conn.socket.send_string test_message, ZMQ::NOBLOCK
42
35
 
43
- EM::Timer.new(0.1) { results[:specs_ran] = true }
36
+ EM::Timer.new(0.1) { @results[:specs_ran] = true }
44
37
  end
45
-
46
- @results = results
47
38
  end
48
39
 
49
40
  it "should run completely" do
50
- @results[:specs_ran].should be_true
41
+ @received.should be_true
51
42
  end
52
43
 
53
44
  it "should receive one message" do
54
- @results[:sub_hndlr].received.length.should == 1
45
+ @received.length.should == 1
55
46
  end
56
47
 
57
48
  it "should receive the message as a ZMQ::Message" do
58
- @results[:sub_hndlr].received.first.should be_a(ZMQ::Message)
49
+ @received.first.should be_a(ZMQ::Message)
59
50
  end
60
51
 
61
52
  it "should receive the message intact" do
62
- @results[:sub_hndlr].received.first.copy_out_string.should == @test_message
53
+ @received.first.copy_out_string.should == @test_message
63
54
  end
64
55
  end
65
56
  end
@@ -1,20 +1,10 @@
1
1
  require File.join(File.dirname(__FILE__), %w[spec_helper])
2
2
 
3
3
  describe EventMachine::ZeroMQ do
4
- class EMTestPullHandler
5
- attr_reader :received
6
- def initialize
7
- @received = []
8
- end
9
- def on_readable(socket, messages)
10
- @received += messages
11
- end
12
- end
13
-
14
4
  it "Should instantiate a connection given valid opts" do
15
5
  pull_conn = nil
16
6
  run_reactor do
17
- pull_conn = SPEC_CTX.socket(ZMQ::PULL, EMTestPullHandler.new)
7
+ pull_conn = SPEC_CTX.socket(ZMQ::PULL)
18
8
  pull_conn.bind(rand_addr)
19
9
  end
20
10
  pull_conn.should be_a(EventMachine::ZeroMQ::Socket)
@@ -22,26 +12,26 @@ describe EventMachine::ZeroMQ do
22
12
 
23
13
  describe "sending/receiving a single message via PUB/SUB" do
24
14
  before(:all) do
25
- results = {}
15
+ @results = {}
16
+ @received = []
26
17
  @test_message = test_message = "TMsg#{rand(999)}"
27
18
 
28
- run_reactor(0.5) do
29
-
19
+ run_reactor(0.2) do
30
20
  address = rand_addr
31
21
 
32
- results[:pull_hndlr] = pull_hndlr = EMTestPullHandler.new
33
- pull_conn = SPEC_CTX.socket(ZMQ::PULL, pull_hndlr)
22
+ pull_conn = SPEC_CTX.socket(ZMQ::PULL)
34
23
  pull_conn.bind(address)
24
+ pull_conn.on(:message) { |m|
25
+ @received << m
26
+ }
35
27
 
36
28
  push_conn = SPEC_CTX.socket(ZMQ::PUSH)
37
29
  push_conn.connect(address)
38
30
 
39
31
  push_conn.socket.send_string test_message, ZMQ::NOBLOCK
40
32
 
41
- EM::Timer.new(0.1) { results[:specs_ran] = true }
33
+ EM::Timer.new(0.1) { @results[:specs_ran] = true }
42
34
  end
43
-
44
- @results = results
45
35
  end
46
36
 
47
37
  it "should run completely" do
@@ -49,9 +39,9 @@ describe EventMachine::ZeroMQ do
49
39
  end
50
40
 
51
41
  it "should receive the message intact" do
52
- @results[:pull_hndlr].received.should_not be_empty
53
- @results[:pull_hndlr].received.first.should be_a(ZMQ::Message)
54
- @results[:pull_hndlr].received.first.copy_out_string.should == @test_message
42
+ @received.should_not be_empty
43
+ @received.first.should be_a(ZMQ::Message)
44
+ @received.first.copy_out_string.should == @test_message
55
45
  end
56
46
  end
57
47
  end
@@ -1,39 +1,10 @@
1
1
  require File.join(File.dirname(__FILE__), %w[spec_helper])
2
2
 
3
3
  describe EventMachine::ZeroMQ do
4
- class EMTestRouterHandler
5
- attr_reader :received
6
- def initialize
7
- @received = []
8
- end
9
- def on_writable(socket)
10
- end
11
- def on_readable(socket, messages)
12
- @received += messages
13
- end
14
- end
15
-
16
- class EMTestDealerHandler
17
- attr_reader :received
18
- def initialize(&block)
19
- @received = []
20
- @on_writable_callback = block
21
- end
22
- def on_writable(socket)
23
- @on_writable_callback.call(socket) if @on_writable_callback
24
- end
25
- def on_readable(socket, messages)
26
- _, message = messages.map(&:copy_out_string)
27
- @received += [message].map {|s| ZMQ::Message.new(s)}
28
-
29
- socket.send_msg('', "re:#{message}")
30
- end
31
- end
32
-
33
4
  it "Should instantiate a connection given valid opts for Router/Dealer" do
34
5
  router_conn = nil
35
- run_reactor(1) do
36
- router_conn = SPEC_CTX.socket(ZMQ::ROUTER, EMTestRouterHandler.new)
6
+ run_reactor do
7
+ router_conn = SPEC_CTX.socket(ZMQ::ROUTER)
37
8
  router_conn.bind(rand_addr)
38
9
  end
39
10
  router_conn.should be_a(EventMachine::ZeroMQ::Socket)
@@ -41,32 +12,38 @@ describe EventMachine::ZeroMQ do
41
12
 
42
13
  describe "sending/receiving a single message via Router/Dealer" do
43
14
  before(:all) do
44
- results = {}
15
+ @results = {}
16
+ @dealer_received, @router_received = [], []
45
17
  @test_message = test_message = "M#{rand(999)}"
46
18
 
47
- run_reactor(2) do
48
- results[:dealer_hndlr] = dealer_hndlr = EMTestDealerHandler.new
49
- results[:router_hndlr] = router_hndlr = EMTestRouterHandler.new
50
-
19
+ run_reactor(0.3) do
51
20
  addr = rand_addr
52
- dealer_conn = SPEC_CTX.socket(ZMQ::DEALER, dealer_hndlr)
21
+ dealer_conn = SPEC_CTX.socket(ZMQ::DEALER)
53
22
  dealer_conn.identity = "dealer1"
54
23
  dealer_conn.bind(addr)
24
+ dealer_conn.on(:message) { |message|
25
+ # 2. Dealer receives messages, sends reply back to router
26
+ @dealer_received << message
27
+ dealer_conn.send_msg("re:#{message.copy_out_string}")
28
+ }
55
29
 
56
- router_conn = SPEC_CTX.socket(ZMQ::ROUTER, router_hndlr)
30
+ router_conn = SPEC_CTX.socket(ZMQ::ROUTER)
57
31
  router_conn.identity = "router1"
58
32
  router_conn.connect(addr)
33
+ router_conn.on(:message) { |*parts|
34
+ # 3. Message received in router identifies the sending dealer
35
+ @router_received << parts
36
+ }
59
37
 
60
38
  EM::add_timer(0.1) do
61
- router_conn.send_msg('dealer1','', test_message)
39
+ # 1. Send message to the dealer
40
+ router_conn.send_msg('dealer1', test_message)
62
41
  end
63
42
 
64
43
  EM::Timer.new(0.2) do
65
- results[:specs_ran] = true
44
+ @results[:specs_ran] = true
66
45
  end
67
46
  end
68
-
69
- @results = results
70
47
  end
71
48
 
72
49
  it "should run completely" do
@@ -74,15 +51,16 @@ describe EventMachine::ZeroMQ do
74
51
  end
75
52
 
76
53
  it "should receive the message intact on the dealer" do
77
- @results[:dealer_hndlr].received.should_not be_empty
78
- @results[:dealer_hndlr].received.last.should be_a(ZMQ::Message)
79
- @results[:dealer_hndlr].received.last.copy_out_string.should == @test_message
54
+ @dealer_received.should_not be_empty
55
+ @dealer_received.last.should be_a(ZMQ::Message)
56
+ @dealer_received.last.copy_out_string.should == @test_message
80
57
  end
81
58
 
82
- it "the router should be echoed its original message" do
83
- @results[:router_hndlr].received.should_not be_empty
84
- @results[:router_hndlr].received.last.should be_a(ZMQ::Message)
85
- @results[:router_hndlr].received.last.copy_out_string.should == "re:#{@test_message}"
59
+ it "the router should be echoed its original message with the dealer identity" do
60
+ @router_received.size.should == 1
61
+ parts = @router_received[0]
62
+ parts[0].copy_out_string.should == "dealer1"
63
+ parts[1].copy_out_string.should == "re:#{@test_message}"
86
64
  end
87
65
  end
88
66
  end
@@ -10,7 +10,7 @@ end
10
10
  require File.expand_path(
11
11
  File.join(File.dirname(__FILE__), %w[.. lib em-zeromq]))
12
12
 
13
- def run_reactor(time=0.2,&block)
13
+ def run_reactor(time=0.1,&block)
14
14
  Thread.new do
15
15
  EM.run do
16
16
  yield
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-zeromq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,24 +10,24 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-10-01 00:00:00.000000000 Z
13
+ date: 2012-11-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: eventmachine
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
- - - '='
20
+ - - ! '>='
21
21
  - !ruby/object:Gem::Version
22
- version: 1.0.0.beta.4
22
+ version: 1.0.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  none: false
27
27
  requirements:
28
- - - '='
28
+ - - ! '>='
29
29
  - !ruby/object:Gem::Version
30
- version: 1.0.0.beta.4
30
+ version: 1.0.0
31
31
  - !ruby/object:Gem::Dependency
32
32
  name: ffi
33
33
  requirement: !ruby/object:Gem::Requirement
@@ -122,9 +122,13 @@ files:
122
122
  - README.md
123
123
  - Rakefile
124
124
  - em-zeromq.gemspec
125
+ - example/multi-part.rb
125
126
  - example/simple.rb
127
+ - example/simpler.rb
128
+ - example/terminating.rb
126
129
  - lib/em-zeromq.rb
127
130
  - lib/em-zeromq/context.rb
131
+ - lib/em-zeromq/event_emitter.rb
128
132
  - lib/em-zeromq/socket.rb
129
133
  - lib/em-zeromq/version.rb
130
134
  - spec/context_spec.rb
@@ -148,7 +152,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
148
152
  version: '0'
149
153
  segments:
150
154
  - 0
151
- hash: 3380199177389627233
155
+ hash: 4479496977537005722
152
156
  required_rubygems_version: !ruby/object:Gem::Requirement
153
157
  none: false
154
158
  requirements:
@@ -157,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
161
  version: '0'
158
162
  segments:
159
163
  - 0
160
- hash: 3380199177389627233
164
+ hash: 4479496977537005722
161
165
  requirements: []
162
166
  rubyforge_project: em-zeromq
163
167
  rubygems_version: 1.8.24