stomp 1.2.4 → 1.2.5

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.
Files changed (56) hide show
  1. data/CHANGELOG.rdoc +11 -0
  2. data/README.rdoc +38 -26
  3. data/Rakefile +3 -0
  4. data/bin/catstomp +34 -34
  5. data/bin/stompcat +36 -36
  6. data/examples/client11_ex1.rb +64 -55
  7. data/examples/client11_putget1.rb +47 -35
  8. data/examples/conn11_ex1.rb +59 -51
  9. data/examples/conn11_ex2.rb +59 -50
  10. data/examples/conn11_hb1.rb +35 -26
  11. data/examples/consumer.rb +25 -12
  12. data/examples/get11conn_ex1.rb +97 -89
  13. data/examples/get11conn_ex2.rb +55 -47
  14. data/examples/logexamp.rb +66 -52
  15. data/examples/logexamp_ssl.rb +66 -52
  16. data/examples/publisher.rb +21 -10
  17. data/examples/put11conn_ex1.rb +35 -24
  18. data/examples/putget11_rh1.rb +66 -56
  19. data/examples/slogger.rb +65 -52
  20. data/examples/ssl_uc1.rb +24 -13
  21. data/examples/ssl_uc1_ciphers.rb +28 -15
  22. data/examples/ssl_uc2.rb +26 -16
  23. data/examples/ssl_uc2_ciphers.rb +31 -18
  24. data/examples/ssl_uc3.rb +25 -14
  25. data/examples/ssl_uc3_ciphers.rb +31 -18
  26. data/examples/ssl_uc4.rb +26 -15
  27. data/examples/ssl_uc4_ciphers.rb +32 -19
  28. data/examples/ssl_ucx_default_ciphers.rb +25 -12
  29. data/examples/stomp11_common.rb +16 -15
  30. data/examples/topic_consumer.rb +23 -10
  31. data/examples/topic_publisher.rb +22 -8
  32. data/lib/client/utils.rb +116 -0
  33. data/lib/connection/heartbeats.rb +173 -0
  34. data/lib/connection/netio.rb +322 -0
  35. data/lib/connection/utf8.rb +294 -0
  36. data/lib/connection/utils.rb +104 -0
  37. data/lib/stomp/client.rb +127 -179
  38. data/lib/stomp/codec.rb +5 -2
  39. data/lib/stomp/connection.rb +109 -865
  40. data/lib/stomp/constants.rb +52 -33
  41. data/lib/stomp/errors.rb +56 -5
  42. data/lib/stomp/ext/hash.rb +4 -0
  43. data/lib/stomp/message.rb +49 -29
  44. data/lib/stomp/sslparams.rb +83 -71
  45. data/lib/stomp/version.rb +3 -1
  46. data/lib/stomp.rb +18 -9
  47. data/stomp.gemspec +58 -3
  48. data/test/test_client.rb +28 -1
  49. data/test/test_codec.rb +8 -2
  50. data/test/test_connection.rb +29 -0
  51. data/test/test_connection1p.rb +31 -16
  52. data/test/test_helper.rb +20 -3
  53. data/test/test_message.rb +8 -3
  54. data/test/test_ssl.rb +10 -4
  55. data/test/tlogger.rb +16 -15
  56. metadata +59 -4
@@ -0,0 +1,104 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'socket'
4
+ require 'timeout'
5
+ require 'io/wait'
6
+ require 'digest/sha1'
7
+
8
+ module Stomp
9
+
10
+ class Connection
11
+
12
+ private
13
+
14
+ # Support multi-homed servers.
15
+ def _expand_hosts(hash)
16
+ new_hash = hash.clone
17
+ new_hash[:hosts_cloned] = hash[:hosts].clone
18
+ new_hash[:hosts] = []
19
+ #
20
+ hash[:hosts].each do |host_parms|
21
+ ai = Socket.getaddrinfo(host_parms[:host], nil, nil, Socket::SOCK_STREAM)
22
+ next if ai.nil? || ai.size == 0
23
+ info6 = ai.detect {|info| info[4] == Socket::AF_INET6}
24
+ info4 = ai.detect {|info| info[4] == Socket::AF_INET}
25
+ if info6
26
+ new_hostp = host_parms.clone
27
+ new_hostp[:host] = info6[3]
28
+ new_hash[:hosts] << new_hostp
29
+ end
30
+ if info4
31
+ new_hostp = host_parms.clone
32
+ new_hostp[:host] = info4[3]
33
+ new_hash[:hosts] << new_hostp
34
+ end
35
+ end
36
+ return new_hash
37
+ end
38
+
39
+ # Handle 1.9+ character representation.
40
+ def parse_char(char)
41
+ RUBY_VERSION > '1.9' ? char : char.chr
42
+ end
43
+
44
+ # Create parameters for any callback logger.
45
+ def log_params()
46
+ lparms = @parameters.clone if @parameters
47
+ lparms = {} unless lparms
48
+ lparms[:cur_host] = @host
49
+ lparms[:cur_port] = @port
50
+ lparms[:cur_login] = @login
51
+ lparms[:cur_passcode] = @passcode
52
+ lparms[:cur_ssl] = @ssl
53
+ lparms[:cur_recondelay] = @reconnect_delay
54
+ lparms[:cur_parseto] = @parse_timeout
55
+ lparms[:cur_conattempts] = @connection_attempts
56
+ lparms[:openstat] = open?
57
+ #
58
+ lparms
59
+ end
60
+
61
+ # _pre_connect handles low level logic just prior to a physical connect.
62
+ def _pre_connect()
63
+ @connect_headers = @connect_headers.symbolize_keys
64
+ raise Stomp::Error::ProtocolErrorConnect if (@connect_headers[:"accept-version"] && !@connect_headers[:host])
65
+ raise Stomp::Error::ProtocolErrorConnect if (!@connect_headers[:"accept-version"] && @connect_headers[:host])
66
+ return unless (@connect_headers[:"accept-version"] && @connect_headers[:host]) # 1.0
67
+ # Try 1.1 or greater
68
+ okvers = []
69
+ avers = @connect_headers[:"accept-version"].split(",")
70
+ avers.each do |nver|
71
+ if Stomp::SUPPORTED.index(nver)
72
+ okvers << nver
73
+ end
74
+ end
75
+ raise Stomp::Error::UnsupportedProtocolError if okvers == []
76
+ @connect_headers[:"accept-version"] = okvers.join(",") # This goes to server
77
+ # Heartbeats - pre connect
78
+ return unless @connect_headers[:"heart-beat"]
79
+ _validate_hbheader()
80
+ end
81
+
82
+ # _post_connect handles low level logic just post a physical connect.
83
+ def _post_connect()
84
+ return unless (@connect_headers[:"accept-version"] && @connect_headers[:host])
85
+ return if @connection_frame.command == Stomp::CMD_ERROR
86
+ # We are CONNECTed
87
+ cfh = @connection_frame.headers.symbolize_keys
88
+ @protocol = cfh[:version]
89
+ if @protocol
90
+ # Should not happen, but check anyway
91
+ raise Stomp::Error::UnsupportedProtocolError unless Stomp::SUPPORTED.index(@protocol)
92
+ else # CONNECTed to a 1.0 server that does not return *any* 1.1 type headers
93
+ @protocol = Stomp::SPL_10 # reset
94
+ return
95
+ end
96
+ # Heartbeats
97
+ return unless @connect_headers[:"heart-beat"]
98
+ _init_heartbeats()
99
+ end
100
+
101
+ end # class
102
+
103
+ end # module
104
+
data/lib/stomp/client.rb CHANGED
@@ -12,20 +12,59 @@ module Stomp
12
12
  # in that thread if you have much message volume.
13
13
  class Client
14
14
 
15
- attr_reader :login, :passcode, :host, :port, :reliable, :parameters
16
-
17
- #alias :obj_send :send
15
+ public
18
16
 
19
- # A new Client object can be initialized using two forms:
17
+ # The login ID used by the client.
18
+ attr_reader :login
19
+
20
+ # The login credentials used by the client.
21
+ attr_reader :passcode
22
+
23
+ # The Stomp host specified by the client.
24
+ attr_reader :host
25
+
26
+ # The Stomp host's listening port.
27
+ attr_reader :port
28
+
29
+ # Is this connection reliable?
30
+ attr_reader :reliable
31
+
32
+ # Parameters Hash, possibly nil for a non-hashed connect.
33
+ attr_reader :parameters
34
+
35
+ # A new Client object can be initialized using three forms:
20
36
  #
21
- # Standard positional parameters:
37
+ # Hash (this is the recommended Client initialization method):
38
+ #
39
+ # hash = {
40
+ # :hosts => [
41
+ # {:login => "login1", :passcode => "passcode1", :host => "localhost", :port => 61616, :ssl => false},
42
+ # {:login => "login2", :passcode => "passcode2", :host => "remotehost", :port => 61617, :ssl => false}
43
+ # ],
44
+ # :reliable => true,
45
+ # :initial_reconnect_delay => 0.01,
46
+ # :max_reconnect_delay => 30.0,
47
+ # :use_exponential_back_off => true,
48
+ # :back_off_multiplier => 2,
49
+ # :max_reconnect_attempts => 0,
50
+ # :randomize => false,
51
+ # :backup => false,
52
+ # :connect_timeout => 0,
53
+ # :connect_headers => {},
54
+ # :parse_timeout => 5,
55
+ # :logger => nil,
56
+ # }
57
+ #
58
+ # e.g. c = Stomp::Client.new(hash)
59
+ #
60
+ # Positional parameters:
22
61
  # login (String, default : '')
23
62
  # passcode (String, default : '')
24
63
  # host (String, default : 'localhost')
25
64
  # port (Integer, default : 61613)
26
65
  # reliable (Boolean, default : false)
27
66
  #
28
- # e.g. c = Client.new('login', 'passcode', 'localhost', 61613, true)
67
+ # e.g. c = Stomp::Client.new('login', 'passcode', 'localhost', 61613, true)
29
68
  #
30
69
  # Stomp URL :
31
70
  # A Stomp URL must begin with 'stomp://' and can be in one of the following forms:
@@ -35,19 +74,21 @@ module Stomp
35
74
  # stomp://login:passcode@host:port
36
75
  # stomp://login:passcode@host.domain.tld:port
37
76
  #
77
+ # e.g. c = Stomp::Client.new(urlstring)
78
+ #
38
79
  def initialize(login = '', passcode = '', host = 'localhost', port = 61613, reliable = false, autoflush = false)
39
80
 
40
81
  # Parse stomp:// URL's or set params
41
82
  if login.is_a?(Hash)
42
83
  @parameters = login
43
-
84
+
44
85
  first_host = @parameters[:hosts][0]
45
-
86
+
46
87
  @login = first_host[:login]
47
88
  @passcode = first_host[:passcode]
48
89
  @host = first_host[:host]
49
90
  @port = first_host[:port] || Connection::default_port(first_host[:ssl])
50
-
91
+
51
92
  @reliable = true
52
93
  elsif login =~ /^stomp:\/\/#{url_regex}/ # e.g. stomp://login:passcode@host:port or stomp://host:port
53
94
  @login = $2 || ""
@@ -55,26 +96,26 @@ module Stomp
55
96
  @host = $4
56
97
  @port = $5.to_i
57
98
  @reliable = false
58
- elsif login =~ /^failover:(\/\/)?\(stomp(\+ssl)?:\/\/#{url_regex}(,stomp(\+ssl)?:\/\/#{url_regex}\))+(\?(.*))?$/ # e.g. failover://(stomp://login1:passcode1@localhost:61616,stomp://login2:passcode2@remotehost:61617)?option1=param
59
-
99
+ elsif login =~ /^failover:(\/\/)?\(stomp(\+ssl)?:\/\/#{url_regex}(,stomp(\+ssl)?:\/\/#{url_regex}\))+(\?(.*))?$/
100
+ # e.g. failover://(stomp://login1:passcode1@localhost:61616,stomp://login2:passcode2@remotehost:61617)?option1=param
60
101
  first_host = {}
61
102
  first_host[:ssl] = !$2.nil?
62
103
  @login = first_host[:login] = $4 || ""
63
104
  @passcode = first_host[:passcode] = $5 || ""
64
105
  @host = first_host[:host] = $6
65
106
  @port = first_host[:port] = $7.to_i || Connection::default_port(first_host[:ssl])
66
-
107
+
67
108
  options = $16 || ""
68
109
  parts = options.split(/&|=/)
69
110
  options = Hash[*parts]
70
-
111
+
71
112
  hosts = [first_host] + parse_hosts(login)
72
-
113
+
73
114
  @parameters = {}
74
115
  @parameters[:hosts] = hosts
75
-
116
+
76
117
  @parameters.merge! filter_options(options)
77
-
118
+
78
119
  @reliable = true
79
120
  else
80
121
  @login = login
@@ -84,9 +125,9 @@ module Stomp
84
125
  @reliable = reliable
85
126
  end
86
127
 
87
- check_arguments!
128
+ check_arguments!()
88
129
 
89
- @id_mutex = Mutex.new
130
+ @id_mutex = Mutex.new()
90
131
  @ids = 1
91
132
 
92
133
  if @parameters
@@ -95,28 +136,28 @@ module Stomp
95
136
  @connection = Connection.new(@login, @passcode, @host, @port, @reliable)
96
137
  @connection.autoflush = autoflush
97
138
  end
98
-
99
- start_listeners
139
+
140
+ start_listeners()
100
141
 
101
142
  end
102
-
103
- # Syntactic sugar for 'Client.new' See 'initialize' for usage.
143
+
144
+ # open is syntactic sugar for 'Client.new' See 'initialize' for usage.
104
145
  def self.open(login = '', passcode = '', host = 'localhost', port = 61613, reliable = false)
105
146
  Client.new(login, passcode, host, port, reliable)
106
147
  end
107
148
 
108
- # Join the listener thread for this client,
109
- # generally used to wait for a quit signal
149
+ # join the listener thread for this client,
150
+ # generally used to wait for a quit signal.
110
151
  def join(limit = nil)
111
152
  @listener_thread.join(limit)
112
153
  end
113
154
 
114
- # Begin a transaction by name
155
+ # Begin starts work in a a transaction by name.
115
156
  def begin(name, headers = {})
116
157
  @connection.begin(name, headers)
117
158
  end
118
159
 
119
- # Abort a transaction by name
160
+ # Abort aborts work in a transaction by name.
120
161
  def abort(name, headers = {})
121
162
  @connection.abort(name, headers)
122
163
 
@@ -131,7 +172,7 @@ module Stomp
131
172
  end
132
173
  end
133
174
 
134
- # Commit a transaction by name
175
+ # Commit commits work in a transaction by name.
135
176
  def commit(name, headers = {})
136
177
  txn_id = headers[:transaction]
137
178
  @replay_messages_by_txn.delete(txn_id)
@@ -139,9 +180,8 @@ module Stomp
139
180
  end
140
181
 
141
182
  # Subscribe to a destination, must be passed a block
142
- # which will be used as a callback listener
143
- #
144
- # Accepts a transaction header ( :transaction => 'some_transaction_id' )
183
+ # which will be used as a callback listener.
184
+ # Accepts a transaction header ( :transaction => 'some_transaction_id' ).
145
185
  def subscribe(destination, headers = {})
146
186
  raise "No listener given" unless block_given?
147
187
  # use subscription id to correlate messages to subscription. As described in
@@ -155,7 +195,7 @@ module Stomp
155
195
  @connection.subscribe(destination, headers)
156
196
  end
157
197
 
158
- # Unsubecribe from a channel
198
+ # Unsubscribe from a subscription by name.
159
199
  def unsubscribe(name, headers = {})
160
200
  set_subscription_id_if_missing(name, headers)
161
201
  @connection.unsubscribe(name, headers)
@@ -163,9 +203,8 @@ module Stomp
163
203
  end
164
204
 
165
205
  # Acknowledge a message, used when a subscription has specified
166
- # client acknowledgement ( connection.subscribe "/queue/a", :ack => 'client'g
167
- #
168
- # Accepts a transaction header ( :transaction => 'some_transaction_id' )
206
+ # client acknowledgement ( connection.subscribe("/queue/a",{:ack => 'client'}).
207
+ # Accepts a transaction header ( :transaction => 'some_transaction_id' ).
169
208
  def acknowledge(message, headers = {})
170
209
  txn_id = headers[:transaction]
171
210
  if txn_id
@@ -180,222 +219,131 @@ module Stomp
180
219
  if block_given?
181
220
  headers['receipt'] = register_receipt_listener lambda {|r| yield r}
182
221
  end
183
- @connection.ack message.headers['message-id'], headers
222
+ @connection.ack(message.headers['message-id'], headers)
184
223
  end
185
224
 
186
- # Stomp 1.1+ NACK
225
+ # Stomp 1.1+ NACK.
187
226
  def nack(message_id, headers = {})
188
- @connection.nack message_id, headers
227
+ @connection.nack(message_id, headers)
189
228
  end
190
229
 
191
- # Unreceive a message, sending it back to its queue or to the DLQ
192
- #
230
+ # Unreceive a message, sending it back to its queue or to the DLQ.
193
231
  def unreceive(message, options = {})
194
232
  @connection.unreceive(message, options)
195
233
  end
196
-
197
- # Publishes message to destination
198
- #
234
+
235
+ # Publishes message to destination.
199
236
  # If a block is given a receipt will be requested and passed to the
200
- # block on receipt
201
- #
202
- # Accepts a transaction header ( :transaction => 'some_transaction_id' )
237
+ # block on receipt.
238
+ # Accepts a transaction header ( :transaction => 'some_transaction_id' ).
203
239
  def publish(destination, message, headers = {})
204
240
  if block_given?
205
241
  headers['receipt'] = register_receipt_listener lambda {|r| yield r}
206
242
  end
207
243
  @connection.publish(destination, message, headers)
208
244
  end
209
-
245
+
246
+ # :TODO: This should not be used. Currently only referenced in the
247
+ # spec tests.
248
+ # *NOTE* This will be removed in the next release.
210
249
  def obj_send(*args)
211
250
  __send__(*args)
212
251
  end
213
-
214
- def connection_frame
252
+
253
+ # Return the broker's CONNECTED frame to the client. Misnamed.
254
+ def connection_frame()
215
255
  @connection.connection_frame
216
256
  end
217
257
 
218
- def disconnect_receipt
258
+ # Return any RECEIPT frame received by DISCONNECT.
259
+ def disconnect_receipt()
219
260
  @connection.disconnect_receipt
220
261
  end
221
262
 
222
- # Is this client open?
263
+ # open? tests if this client connection is open.
223
264
  def open?
224
- @connection.open?
265
+ @connection.open?()
225
266
  end
226
267
 
227
- # Is this client closed?
228
- def closed?
229
- @connection.closed?
268
+ # close? tests if this client connection is closed.
269
+ def closed?()
270
+ @connection.closed?()
230
271
  end
231
272
 
232
- # Close out resources in use by this client
233
- def close headers={}
273
+ # close frees resources in use by this client. The listener thread is
274
+ # terminated, and disconnect on the connection is called.
275
+ def close(headers={})
234
276
  @listener_thread.exit
235
- @connection.disconnect headers
277
+ @connection.disconnect(headers)
236
278
  end
237
279
 
238
- # Check if the thread was created and isn't dead
239
- def running
280
+ # running checks if the thread was created and is not dead.
281
+ def running()
240
282
  @listener_thread && !!@listener_thread.status
241
283
  end
242
284
 
243
- # Convenience method
285
+ # set_logger identifies a new callback logger.
244
286
  def set_logger(logger)
245
287
  @connection.set_logger(logger)
246
288
  end
247
289
 
248
- # Convenience method
290
+ # protocol returns the current client's protocol level.
249
291
  def protocol()
250
- @connection.protocol
292
+ @connection.protocol()
251
293
  end
252
294
 
253
- # Convenience method
295
+ # valid_utf8? validates any given string for UTF8 compliance.
254
296
  def valid_utf8?(s)
255
297
  @connection.valid_utf8?(s)
256
298
  end
257
299
 
258
- # Convenience method for clients
300
+ # sha1 returns a SHA1 sum of a given string.
259
301
  def sha1(data)
260
302
  @connection.sha1(data)
261
303
  end
262
304
 
263
- # Convenience method for clients
305
+ # uuid returns a type 4 UUID.
264
306
  def uuid()
265
307
  @connection.uuid()
266
308
  end
267
309
 
268
- # Retrieve heartbeat send interval
269
- def hbsend_interval
270
- @connection.hbsend_interval
310
+ # hbsend_interval returns the connection's heartbeat send interval.
311
+ def hbsend_interval()
312
+ @connection.hbsend_interval()
271
313
  end
272
314
 
273
- # Retrieve heartbeat receive interval
274
- def hbrecv_interval
275
- @connection.hbrecv_interval
315
+ # hbrecv_interval returns the connection's heartbeat receive interval.
316
+ def hbrecv_interval()
317
+ @connection.hbrecv_interval()
276
318
  end
277
319
 
278
- # Retrieve heartbeat send count
279
- def hbsend_count
280
- @connection.hbsend_count
320
+ # hbsend_count returns the current connection's heartbeat send count.
321
+ def hbsend_count()
322
+ @connection.hbsend_count()
281
323
  end
282
324
 
283
- # Retrieve heartbeat receive count
284
- def hbrecv_count
285
- @connection.hbrecv_count
325
+ # hbrecv_count returns the current connection's heartbeat receive count.
326
+ def hbrecv_count()
327
+ @connection.hbrecv_count()
286
328
  end
287
329
 
288
330
  # Poll for asynchronous messages issued by broker.
289
331
  # Return nil of no message available, else the message
290
- def poll
291
- @connection.poll
332
+ def poll()
333
+ @connection.poll()
292
334
  end
293
335
 
336
+ # autoflush= sets the current connection's autoflush setting.
294
337
  def autoflush=(af)
295
338
  @connection.autoflush = af
296
339
  end
297
340
 
298
- def autoflush
299
- @connection.autoflush
341
+ # autoflush returns the current connection's autoflush setting.
342
+ def autoflush()
343
+ @connection.autoflush()
300
344
  end
301
345
 
302
- private
303
- # Set a subscription id in the headers hash if one does not already exist.
304
- # For simplicities sake, all subscriptions have a subscription ID.
305
- # setting an id in the SUBSCRIPTION header is described in the stomp protocol docs:
306
- # http://stomp.github.com/
307
- def set_subscription_id_if_missing(destination, headers)
308
- headers[:id] = headers[:id] ? headers[:id] : headers['id']
309
- if headers[:id] == nil
310
- headers[:id] = Digest::SHA1.hexdigest(destination)
311
- end
312
- end
313
-
314
- def register_receipt_listener(listener)
315
- id = -1
316
- @id_mutex.synchronize do
317
- id = @ids.to_s
318
- @ids = @ids.succ
319
- end
320
- @receipt_listeners[id] = listener
321
- id
322
- end
323
-
324
- # e.g. login:passcode@host:port or host:port
325
- def url_regex
326
- '(([\w\.\-]*):(\w*)@)?([\w\.\-]+):(\d+)'
327
- end
328
-
329
- def parse_hosts(url)
330
- hosts = []
331
-
332
- host_match = /stomp(\+ssl)?:\/\/(([\w\.]*):(\w*)@)?([\w\.]+):(\d+)\)/
333
- url.scan(host_match).each do |match|
334
- host = {}
335
- host[:ssl] = !match[0].nil?
336
- host[:login] = match[2] || ""
337
- host[:passcode] = match[3] || ""
338
- host[:host] = match[4]
339
- host[:port] = match[5].to_i
340
-
341
- hosts << host
342
- end
343
-
344
- hosts
345
- end
346
-
347
- def check_arguments!
348
- raise ArgumentError if @host.nil? || @host.empty?
349
- raise ArgumentError if @port.nil? || @port == '' || @port < 1 || @port > 65535
350
- raise ArgumentError unless @reliable.is_a?(TrueClass) || @reliable.is_a?(FalseClass)
351
- end
352
-
353
- def filter_options(options)
354
- new_options = {}
355
- new_options[:initial_reconnect_delay] = (options["initialReconnectDelay"] || 10).to_f / 1000 # In ms
356
- new_options[:max_reconnect_delay] = (options["maxReconnectDelay"] || 30000 ).to_f / 1000 # In ms
357
- new_options[:use_exponential_back_off] = !(options["useExponentialBackOff"] == "false") # Default: true
358
- new_options[:back_off_multiplier] = (options["backOffMultiplier"] || 2 ).to_i
359
- new_options[:max_reconnect_attempts] = (options["maxReconnectAttempts"] || 0 ).to_i
360
- new_options[:randomize] = options["randomize"] == "true" # Default: false
361
- new_options[:backup] = false # Not implemented yet: I'm using a master X slave solution
362
- new_options[:timeout] = -1 # Not implemented yet: a "timeout(5) do ... end" would do the trick, feel free
363
-
364
- new_options
365
- end
366
-
367
- def find_listener(message)
368
- subscription_id = message.headers['subscription']
369
- if subscription_id == nil
370
- # For backward compatibility, some messages may already exist with no
371
- # subscription id, in which case we can attempt to synthesize one.
372
- set_subscription_id_if_missing(message.headers['destination'], message.headers)
373
- subscription_id = message.headers[:id]
374
- end
375
- @listeners[subscription_id]
376
- end
346
+ end # Class
377
347
 
378
- def start_listeners
379
- @listeners = {}
380
- @receipt_listeners = {}
381
- @replay_messages_by_txn = {}
382
-
383
- @listener_thread = Thread.start do
384
- while true
385
- message = @connection.receive
386
- if message.command == Stomp::CMD_MESSAGE
387
- if listener = find_listener(message)
388
- listener.call(message)
389
- end
390
- elsif message.command == Stomp::CMD_RECEIPT
391
- if listener = @receipt_listeners[message.headers['receipt-id']]
392
- listener.call(message)
393
- end
394
- end
395
- end
396
- end
397
-
398
- end
399
- end
400
- end
348
+ end # Module
401
349
 
data/lib/stomp/codec.rb CHANGED
@@ -14,7 +14,9 @@ module Stomp
14
14
  #
15
15
  class HeaderCodec
16
16
 
17
- # Encode header data per STOMP 1.1 specification
17
+ public
18
+
19
+ # encode encodes header data per the STOMP 1.1 specification.
18
20
  def self.encode(in_string = nil)
19
21
  return in_string unless in_string
20
22
  ev = Stomp::ENCODE_VALUES # avoid typing below
@@ -25,7 +27,7 @@ module Stomp
25
27
  os
26
28
  end
27
29
 
28
- # Decode header data per STOMP 1.1 specification
30
+ # decode decodes header data per the STOMP 1.1 specification.
29
31
  def self.decode(in_string = nil)
30
32
  return in_string unless in_string
31
33
  ev = Stomp::DECODE_VALUES # avoid typing below
@@ -37,5 +39,6 @@ module Stomp
37
39
  end
38
40
 
39
41
  end # of class HeaderCodec
42
+
40
43
  end # of module Stomp
41
44