stomp 1.1 → 1.1.3
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.
- data/CHANGELOG +6 -0
- data/README.rdoc +39 -0
- data/lib/stomp/client.rb +119 -42
- data/lib/stomp/connection.rb +187 -19
- metadata +6 -4
data/CHANGELOG
CHANGED
data/README.rdoc
CHANGED
@@ -15,6 +15,45 @@ An implementation of the Stomp protocol (http://stomp.codehaus.org/Protocol) for
|
|
15
15
|
p msg
|
16
16
|
end
|
17
17
|
|
18
|
+
===Failover + SSL Example URL Usage
|
19
|
+
|
20
|
+
options = "initialReconnectDelay=5000&randomize=false&useExponentialBackOff=false"
|
21
|
+
|
22
|
+
#remotehost1 uses SSL, remotehost2 doesn't
|
23
|
+
client = Stomp::Client.new("failover:(stomp+ssl://login1:passcode1@remotehost1:61612,stomp://login2:passcode2@remotehost2:61613)?#{options}")
|
24
|
+
|
25
|
+
client.send("/my/queue", "hello world!")
|
26
|
+
client.subscribe("/my/queue") do |msg|
|
27
|
+
p msg
|
28
|
+
end
|
29
|
+
|
30
|
+
===Hash Example Usage
|
31
|
+
|
32
|
+
hash = {
|
33
|
+
:hosts => [
|
34
|
+
{:login => "login1", :passcode => "passcode1", :host => "remotehost1", :port => 61612, :ssl => true},
|
35
|
+
{:login => "login2", :passcode => "passcode2", :host => "remotehost2", :port => 61613, :ssl => false},
|
36
|
+
|
37
|
+
],
|
38
|
+
# These are the default parameters, don't need to be set
|
39
|
+
:initial_reconnect_delay => 0.01,
|
40
|
+
:max_reconnect_delay => 30.0,
|
41
|
+
:use_exponential_back_off => true,
|
42
|
+
:back_off_multiplier => 2,
|
43
|
+
:max_reconnect_attempts => 0,
|
44
|
+
:randomize => false,
|
45
|
+
:backup => false,
|
46
|
+
:timeout => -1,
|
47
|
+
:connect_headers => {}
|
48
|
+
}
|
49
|
+
|
50
|
+
# for client
|
51
|
+
client = Stomp::Client.new(hash)
|
52
|
+
|
53
|
+
# for connection
|
54
|
+
connection = Stomp::Connection.new(hash)
|
55
|
+
|
56
|
+
|
18
57
|
===Contact info
|
19
58
|
|
20
59
|
Up until March 2009 the project was maintained and primarily developed by Brian McCallister.
|
data/lib/stomp/client.rb
CHANGED
@@ -7,7 +7,8 @@ module Stomp
|
|
7
7
|
# in that thread if you have much message volume.
|
8
8
|
class Client
|
9
9
|
|
10
|
-
attr_reader :login, :passcode, :host, :port, :reliable, :running
|
10
|
+
attr_reader :login, :passcode, :host, :port, :reliable, :running, :parameters
|
11
|
+
alias :obj_send :send
|
11
12
|
|
12
13
|
# A new Client object can be initialized using two forms:
|
13
14
|
#
|
@@ -30,22 +31,46 @@ module Stomp
|
|
30
31
|
#
|
31
32
|
def initialize(login = '', passcode = '', host = 'localhost', port = 61613, reliable = false)
|
32
33
|
|
33
|
-
# Parse stomp:// URL's or set
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
@
|
40
|
-
@
|
41
|
-
@
|
42
|
-
@
|
43
|
-
|
44
|
-
@
|
45
|
-
|
46
|
-
|
47
|
-
@
|
34
|
+
# Parse stomp:// URL's or set params
|
35
|
+
if login.is_a?(Hash)
|
36
|
+
@parameters = login
|
37
|
+
|
38
|
+
first_host = @parameters[:hosts][0]
|
39
|
+
|
40
|
+
@login = first_host[:login]
|
41
|
+
@passcode = first_host[:passcode]
|
42
|
+
@host = first_host[:host]
|
43
|
+
@port = first_host[:port] || default_port(first_host[:ssl])
|
44
|
+
|
45
|
+
@reliable = true
|
46
|
+
|
47
|
+
elsif login =~ /^stomp:\/\/(([\w\.]+):(\w+)@)?([\w\.]+):(\d+)/ # e.g. stomp://login:passcode@host:port or stomp://host:port
|
48
|
+
@login = $2 || ""
|
49
|
+
@passcode = $3 || ""
|
50
|
+
@host = $4
|
51
|
+
@port = $5.to_i
|
48
52
|
@reliable = false
|
53
|
+
elsif login =~ /^failover:(\/\/)?\(stomp(\+ssl)?:\/\/(([\w\.]*):(\w*)@)?([\w\.]+):(\d+)(,stomp(\+ssl)?:\/\/(([\w\.]*):(\w*)@)?([\w\.]+):(\d+)\))+(\?(.*))?$/ # e.g. failover://(stomp://login1:passcode1@localhost:61616,stomp://login2:passcode2@remotehost:61617)?option1=param
|
54
|
+
|
55
|
+
first_host = {}
|
56
|
+
first_host[:ssl] = !$2.nil?
|
57
|
+
@login = first_host[:login] = $4 || ""
|
58
|
+
@passcode = first_host[:passcode] = $5 || ""
|
59
|
+
@host = first_host[:host] = $6
|
60
|
+
@port = first_host[:port] = $7.to_i || default_port(first_host[:ssl])
|
61
|
+
|
62
|
+
options = $16 || ""
|
63
|
+
parts = options.split(/&|=/)
|
64
|
+
options = Hash[*parts]
|
65
|
+
|
66
|
+
hosts = [first_host] + parse_hosts(login)
|
67
|
+
|
68
|
+
@parameters = {}
|
69
|
+
@parameters[:hosts] = hosts
|
70
|
+
|
71
|
+
@parameters.merge! filter_options(options)
|
72
|
+
|
73
|
+
@reliable = true
|
49
74
|
else
|
50
75
|
@login = login
|
51
76
|
@passcode = passcode
|
@@ -54,38 +79,21 @@ module Stomp
|
|
54
79
|
@reliable = reliable
|
55
80
|
end
|
56
81
|
|
57
|
-
|
58
|
-
raise ArgumentError if @port.nil? || @port == '' || @port < 1 || @port > 65535
|
59
|
-
raise ArgumentError unless @reliable.is_a?(TrueClass) || @reliable.is_a?(FalseClass)
|
82
|
+
check_arguments!
|
60
83
|
|
61
84
|
@id_mutex = Mutex.new
|
62
85
|
@ids = 1
|
63
|
-
|
64
|
-
@
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
@listener_thread = Thread.start do
|
70
|
-
while @running
|
71
|
-
message = @connection.receive
|
72
|
-
case
|
73
|
-
when message.nil?
|
74
|
-
break
|
75
|
-
when message.command == 'MESSAGE'
|
76
|
-
if listener = @listeners[message.headers['destination']]
|
77
|
-
listener.call(message)
|
78
|
-
end
|
79
|
-
when message.command == 'RECEIPT'
|
80
|
-
if listener = @receipt_listeners[message.headers['receipt-id']]
|
81
|
-
listener.call(message)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
86
|
+
|
87
|
+
if @parameters
|
88
|
+
@connection = Connection.new(@parameters)
|
89
|
+
else
|
90
|
+
@connection = Connection.new(@login, @passcode, @host, @port, @reliable)
|
85
91
|
end
|
92
|
+
|
93
|
+
start_listeners
|
86
94
|
|
87
95
|
end
|
88
|
-
|
96
|
+
|
89
97
|
# Syntactic sugar for 'Client.new' See 'initialize' for usage.
|
90
98
|
def self.open(login = '', passcode = '', host = 'localhost', port = 61613, reliable = false)
|
91
99
|
Client.new(login, passcode, host, port, reliable)
|
@@ -201,7 +209,76 @@ module Stomp
|
|
201
209
|
@receipt_listeners[id] = listener
|
202
210
|
id
|
203
211
|
end
|
212
|
+
|
213
|
+
def default_port(ssl)
|
214
|
+
return 61612 if ssl
|
215
|
+
|
216
|
+
61613
|
217
|
+
end
|
218
|
+
|
219
|
+
def parse_hosts(url)
|
220
|
+
hosts = []
|
221
|
+
|
222
|
+
host_match = /stomp(\+ssl)?:\/\/(([\w\.]*):(\w*)@)?([\w\.]+):(\d+)\)/
|
223
|
+
url.scan(host_match).each do |match|
|
224
|
+
host = {}
|
225
|
+
host[:ssl] = !match[0].nil?
|
226
|
+
host[:login] = match[2] || ""
|
227
|
+
host[:passcode] = match[3] || ""
|
228
|
+
host[:host] = match[4]
|
229
|
+
host[:port] = match[5].to_i
|
230
|
+
|
231
|
+
hosts << host
|
232
|
+
end
|
233
|
+
|
234
|
+
hosts
|
235
|
+
end
|
236
|
+
|
237
|
+
def check_arguments!
|
238
|
+
raise ArgumentError if @host.nil? || @host.empty?
|
239
|
+
raise ArgumentError if @port.nil? || @port == '' || @port < 1 || @port > 65535
|
240
|
+
raise ArgumentError unless @reliable.is_a?(TrueClass) || @reliable.is_a?(FalseClass)
|
241
|
+
end
|
242
|
+
|
243
|
+
def filter_options(options)
|
244
|
+
new_options = {}
|
245
|
+
new_options[:initial_reconnect_delay] = (options["initialReconnectDelay"] || 10).to_f / 1000 # In ms
|
246
|
+
new_options[:max_reconnect_delay] = (options["maxReconnectDelay"] || 30000 ).to_f / 1000 # In ms
|
247
|
+
new_options[:use_exponential_back_off] = !(options["useExponentialBackOff"] == "false") # Default: true
|
248
|
+
new_options[:back_off_multiplier] = (options["backOffMultiplier"] || 2 ).to_i
|
249
|
+
new_options[:max_reconnect_attempts] = (options["maxReconnectAttempts"] || 0 ).to_i
|
250
|
+
new_options[:randomize] = options["randomize"] == "true" # Default: false
|
251
|
+
new_options[:backup] = false # Not implemented yet: I'm using a master X slave solution
|
252
|
+
new_options[:timeout] = -1 # Not implemented yet: a "timeout(5) do ... end" would do the trick, feel free
|
253
|
+
|
254
|
+
new_options
|
255
|
+
end
|
256
|
+
|
257
|
+
def start_listeners
|
258
|
+
@listeners = {}
|
259
|
+
@receipt_listeners = {}
|
260
|
+
@running = true
|
261
|
+
@replay_messages_by_txn = {}
|
204
262
|
|
263
|
+
@listener_thread = Thread.start do
|
264
|
+
while @running
|
265
|
+
message = @connection.receive
|
266
|
+
case
|
267
|
+
when message.nil?
|
268
|
+
break
|
269
|
+
when message.command == 'MESSAGE'
|
270
|
+
if listener = @listeners[message.headers['destination']]
|
271
|
+
listener.call(message)
|
272
|
+
end
|
273
|
+
when message.command == 'RECEIPT'
|
274
|
+
if listener = @receipt_listeners[message.headers['receipt-id']]
|
275
|
+
listener.call(message)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
205
282
|
end
|
206
283
|
end
|
207
284
|
|
data/lib/stomp/connection.rb
CHANGED
@@ -4,7 +4,7 @@ module Stomp
|
|
4
4
|
# synchronous receives
|
5
5
|
class Connection
|
6
6
|
|
7
|
-
|
7
|
+
alias :obj_send :send
|
8
8
|
# A new Connection object accepts the following parameters:
|
9
9
|
#
|
10
10
|
# login (String, default : '')
|
@@ -14,9 +14,28 @@ module Stomp
|
|
14
14
|
# reliable (Boolean, default : false)
|
15
15
|
# reconnect_delay (Integer, default : 5)
|
16
16
|
#
|
17
|
-
# e.g. c =
|
17
|
+
# e.g. c = Connection.new("username", "password", "localhost", 61613, true)
|
18
|
+
#
|
19
|
+
# Hash:
|
20
|
+
#
|
21
|
+
# hash = {
|
22
|
+
# :hosts => [
|
23
|
+
# {:login => "login1", :passcode => "passcode1", :host => "localhost", :port => 61616, :ssl => false},
|
24
|
+
# {:login => "login2", :passcode => "passcode2", :host => "remotehost", :port => 61617, :ssl => false}
|
25
|
+
# ],
|
26
|
+
# :initial_reconnect_delay => 0.01,
|
27
|
+
# :max_reconnect_delay => 30.0,
|
28
|
+
# :use_exponential_back_off => true,
|
29
|
+
# :back_off_multiplier => 2,
|
30
|
+
# :max_reconnect_attempts => 0,
|
31
|
+
# :randomize => false,
|
32
|
+
# :backup => false,
|
33
|
+
# :timeout => -1
|
34
|
+
# }
|
35
|
+
#
|
36
|
+
# e.g. c = Connection.new(hash)
|
18
37
|
#
|
19
|
-
# TODO
|
38
|
+
# TODO
|
20
39
|
# Stomp URL :
|
21
40
|
# A Stomp URL must begin with 'stomp://' and can be in one of the following forms:
|
22
41
|
#
|
@@ -26,22 +45,42 @@ module Stomp
|
|
26
45
|
# stomp://user:pass@host.domain.tld:port
|
27
46
|
#
|
28
47
|
def initialize(login = '', passcode = '', host = 'localhost', port = 61613, reliable = false, reconnect_delay = 5, connect_headers = {})
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
48
|
+
if login.is_a?(Hash)
|
49
|
+
hashed_initialize(login)
|
50
|
+
else
|
51
|
+
@host = host
|
52
|
+
@port = port
|
53
|
+
@login = login
|
54
|
+
@passcode = passcode
|
55
|
+
@reliable = reliable
|
56
|
+
@reconnect_delay = reconnect_delay
|
57
|
+
@connect_headers = connect_headers
|
58
|
+
@ssl = false
|
59
|
+
@parameters = nil
|
60
|
+
end
|
61
|
+
|
33
62
|
@transmit_semaphore = Mutex.new
|
34
63
|
@read_semaphore = Mutex.new
|
35
64
|
@socket_semaphore = Mutex.new
|
36
|
-
|
37
|
-
@reconnect_delay = reconnect_delay
|
38
|
-
@connect_headers = connect_headers
|
39
|
-
@closed = false
|
65
|
+
|
40
66
|
@subscriptions = {}
|
41
67
|
@failure = nil
|
68
|
+
@connection_attempts = 0
|
69
|
+
|
42
70
|
socket
|
43
71
|
end
|
44
|
-
|
72
|
+
|
73
|
+
def hashed_initialize(params)
|
74
|
+
|
75
|
+
@parameters = refine_params(params)
|
76
|
+
@reliable = true
|
77
|
+
@reconnect_delay = @parameters[:initial_reconnect_delay]
|
78
|
+
@connect_headers = @parameters[:connect_headers]
|
79
|
+
|
80
|
+
#sets the first host to connect
|
81
|
+
change_host
|
82
|
+
end
|
83
|
+
|
45
84
|
# Syntactic sugar for 'Connection.new' See 'initialize' for usage.
|
46
85
|
def Connection.open(login = '', passcode = '', host = 'localhost', port = 61613, reliable = false, reconnect_delay = 5, connect_headers = {})
|
47
86
|
Connection.new(login, passcode, host, port, reliable, reconnect_delay, connect_headers)
|
@@ -50,30 +89,158 @@ module Stomp
|
|
50
89
|
def socket
|
51
90
|
# Need to look into why the following synchronize does not work.
|
52
91
|
#@read_semaphore.synchronize do
|
92
|
+
|
53
93
|
s = @socket;
|
94
|
+
|
95
|
+
s = nil unless connected?
|
96
|
+
|
54
97
|
while s.nil? || !@failure.nil?
|
55
98
|
@failure = nil
|
56
99
|
begin
|
57
|
-
s =
|
58
|
-
|
59
|
-
|
60
|
-
|
100
|
+
s = open_socket
|
101
|
+
@closed = false
|
102
|
+
|
103
|
+
headers = @connect_headers.clone
|
104
|
+
headers[:login] = @login
|
105
|
+
headers[:passcode] = @passcode
|
61
106
|
_transmit(s, "CONNECT", headers)
|
62
107
|
@connect = _receive(s)
|
63
108
|
# replay any subscriptions.
|
64
109
|
@subscriptions.each { |k,v| _transmit(s, "SUBSCRIBE", v) }
|
110
|
+
|
111
|
+
@connection_attempts = 0
|
65
112
|
rescue
|
66
113
|
@failure = $!;
|
67
114
|
s=nil;
|
68
115
|
raise unless @reliable
|
69
|
-
$stderr.print "connect failed: " + $! +" will retry in #{@reconnect_delay}\n";
|
116
|
+
$stderr.print "connect to #{@host} failed: " + $! +" will retry(##{@connection_attempts}) in #{@reconnect_delay}\n";
|
117
|
+
|
118
|
+
raise "Max number of reconnection attempts reached" if max_reconnect_attempts?
|
119
|
+
|
70
120
|
sleep(@reconnect_delay);
|
121
|
+
|
122
|
+
@connection_attempts += 1
|
123
|
+
|
124
|
+
if @parameters
|
125
|
+
change_host
|
126
|
+
increase_reconnect_delay
|
127
|
+
end
|
71
128
|
end
|
72
129
|
end
|
73
130
|
@socket = s
|
74
131
|
return s;
|
75
132
|
#end
|
76
133
|
end
|
134
|
+
|
135
|
+
def connected?
|
136
|
+
begin
|
137
|
+
test_socket = TCPSocket.open @host, @port
|
138
|
+
test_socket.close
|
139
|
+
open?
|
140
|
+
rescue
|
141
|
+
false
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def close_socket
|
146
|
+
begin
|
147
|
+
@socket.close
|
148
|
+
rescue
|
149
|
+
#Ignoring if already closed
|
150
|
+
end
|
151
|
+
|
152
|
+
@closed = true
|
153
|
+
end
|
154
|
+
|
155
|
+
def open_socket
|
156
|
+
return TCPSocket.open @host, @port unless @ssl
|
157
|
+
|
158
|
+
ssl_socket
|
159
|
+
end
|
160
|
+
|
161
|
+
def ssl_socket
|
162
|
+
require 'openssl' unless defined?(OpenSSL)
|
163
|
+
|
164
|
+
ctx = OpenSSL::SSL::SSLContext.new
|
165
|
+
|
166
|
+
# For client certificate authentication:
|
167
|
+
# key_path = ENV["STOMP_KEY_PATH"] || "~/stomp_keys"
|
168
|
+
# ctx.cert = OpenSSL::X509::Certificate.new("#{key_path}/client.cer")
|
169
|
+
# ctx.key = OpenSSL::PKey::RSA.new("#{key_path}/client.keystore")
|
170
|
+
|
171
|
+
# For server certificate authentication:
|
172
|
+
# truststores = OpenSSL::X509::Store.new
|
173
|
+
# truststores.add_file("#{key_path}/client.ts")
|
174
|
+
# ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
175
|
+
# ctx.cert_store = truststores
|
176
|
+
|
177
|
+
ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
178
|
+
|
179
|
+
tcp_socket = TCPSocket.new @host, @port
|
180
|
+
ssl = OpenSSL::SSL::SSLSocket.new(tcp_socket, ctx)
|
181
|
+
ssl.connect
|
182
|
+
ssl
|
183
|
+
end
|
184
|
+
|
185
|
+
def refine_params(params)
|
186
|
+
params = uncamelized_sym_keys(params)
|
187
|
+
|
188
|
+
{
|
189
|
+
:initial_reconnect_delay => 0.01,
|
190
|
+
:max_reconnect_delay => 30.0,
|
191
|
+
:use_exponential_back_off => true,
|
192
|
+
:back_off_multiplier => 2,
|
193
|
+
:max_reconnect_attempts => 0,
|
194
|
+
:randomize => false,
|
195
|
+
:connect_headers => {},
|
196
|
+
:backup => false,
|
197
|
+
:timeout => -1
|
198
|
+
}.merge(params)
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
def uncamelized_sym_keys(params)
|
203
|
+
uncamelized = {}
|
204
|
+
params.each_pair do |key, value|
|
205
|
+
key = key.to_s.split(/(?=[A-Z])/).join('_').downcase.to_sym
|
206
|
+
uncamelized[key] = value
|
207
|
+
end
|
208
|
+
|
209
|
+
uncamelized
|
210
|
+
end
|
211
|
+
|
212
|
+
def change_host
|
213
|
+
@parameters[:hosts].shuffle! if @parameters[:randomize]
|
214
|
+
|
215
|
+
# Set first as master and send it to the end of array
|
216
|
+
current_host = @parameters[:hosts].shift
|
217
|
+
@parameters[:hosts] << current_host
|
218
|
+
|
219
|
+
@ssl = current_host[:ssl]
|
220
|
+
@host = current_host[:host]
|
221
|
+
@port = current_host[:port] || default_port(@ssl)
|
222
|
+
@login = current_host[:login] || ""
|
223
|
+
@passcode = current_host[:passcode] || ""
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
def default_port(ssl)
|
228
|
+
return 61612 if ssl
|
229
|
+
|
230
|
+
61613
|
231
|
+
end
|
232
|
+
|
233
|
+
def max_reconnect_attempts?
|
234
|
+
!(@parameters.nil? || @parameters[:max_reconnect_attempts].nil?) && @parameters[:max_reconnect_attempts] != 0 && @connection_attempts > @parameters[:max_reconnect_attempts]
|
235
|
+
end
|
236
|
+
|
237
|
+
def increase_reconnect_delay
|
238
|
+
|
239
|
+
@reconnect_delay *= @parameters[:back_off_multiplier] if @parameters[:use_exponential_back_off]
|
240
|
+
@reconnect_delay = @parameters[:max_reconnect_delay] if @reconnect_delay > @parameters[:max_reconnect_delay]
|
241
|
+
|
242
|
+
@reconnect_delay
|
243
|
+
end
|
77
244
|
|
78
245
|
# Is this connection open?
|
79
246
|
def open?
|
@@ -145,7 +312,8 @@ module Stomp
|
|
145
312
|
# Close this connection
|
146
313
|
def disconnect(headers = {})
|
147
314
|
transmit("DISCONNECT", headers)
|
148
|
-
|
315
|
+
|
316
|
+
close_socket
|
149
317
|
end
|
150
318
|
|
151
319
|
# Return a pending message if one is available, otherwise
|
@@ -233,7 +401,7 @@ module Stomp
|
|
233
401
|
rescue
|
234
402
|
@failure = $!;
|
235
403
|
raise unless @reliable
|
236
|
-
$stderr.print "transmit failed: " + $!+"\n";
|
404
|
+
$stderr.print "transmit to #{@host} failed: " + $!+"\n";
|
237
405
|
end
|
238
406
|
end
|
239
407
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stomp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian McCallister
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-
|
13
|
+
date: 2009-12-03 00:00:00 -02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -41,6 +41,8 @@ files:
|
|
41
41
|
- test/test_helper.rb
|
42
42
|
has_rdoc: true
|
43
43
|
homepage: http://stomp.codehaus.org/
|
44
|
+
licenses: []
|
45
|
+
|
44
46
|
post_install_message:
|
45
47
|
rdoc_options:
|
46
48
|
- --quiet
|
@@ -69,9 +71,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
71
|
requirements: []
|
70
72
|
|
71
73
|
rubyforge_project:
|
72
|
-
rubygems_version: 1.3.
|
74
|
+
rubygems_version: 1.3.5
|
73
75
|
signing_key:
|
74
|
-
specification_version:
|
76
|
+
specification_version: 3
|
75
77
|
summary: Ruby client for the Stomp messaging protocol
|
76
78
|
test_files:
|
77
79
|
- test/test_client.rb
|