mqtt 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/NEWS.md +15 -0
- data/lib/mqtt/client.rb +21 -10
- data/lib/mqtt/packet.rb +1 -1
- data/lib/mqtt/proxy.rb +4 -4
- data/lib/mqtt/version.rb +1 -1
- data/spec/mqtt_client_spec.rb +70 -9
- data/spec/zz_client_integration_spec.rb +13 -2
- metadata +21 -22
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
OWI1ZGM5Yzk4OWZiZDBkMDY5ZDM5NTllMWQ3YzRhYTk3NThmNDY3Ng==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b740779b0a3780a38d3c673f47e512201329ccf7
|
4
|
+
data.tar.gz: 514676334d05c2affb8371b24d25c635efd829fb
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NmRiYzQ0NmE3NDlhNDQ1MDExNmY2OGM2NzNjYWNlMTAwODc0NDRiNzM3MDU1
|
11
|
-
YWYxYTYyNDdmZTUxNjI2YjM2ODU2ZTgxMGVhNjM1NjAwOWViY2I=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YzkwNjYyYzYxODgyYzZjZWU2MGZhMzQ0YWZhNWM3MTVhNzdjNTFjMjEzYWFj
|
14
|
-
OGMzN2NlYjNmYTdjYzVmODNhZDZmZGIzMDg4ZjBjYmY5MzljNzRlODljMjI0
|
15
|
-
NTI3OGRmZDhhODA0NDA2NDI5ZTBlYzhjZWE3MWJhNGQwYzE4OWQ=
|
6
|
+
metadata.gz: 162771d3087a48968de71863b569ed455bbc6a7f92a1370175db4237bec9b5625ce6b3b7d0997e98eb625bdd900e14cf564152bf35f48f04ea76f857dd3066e3
|
7
|
+
data.tar.gz: 2fa7f6b485082a7f830a063e5a829147ad419566b3ffe0d90a82e8024906b9d37861e97fe779f59fb3230d8309312f0fd17a4e3dd817dd4593dfdab697c03a67
|
data/NEWS.md
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
Ruby MQTT NEWS
|
2
2
|
==============
|
3
3
|
|
4
|
+
Ruby MQTT Version 0.5.0 (2016-04-16)
|
5
|
+
------------------------------------
|
6
|
+
|
7
|
+
* Switched default protocol version to 3.1.1
|
8
|
+
* Added support for Server Name Identification (SNI)
|
9
|
+
* Fix for unescaping user/password in URI
|
10
|
+
* Fix for bug in MQTT::Proxy class
|
11
|
+
* Add the ability to ignore retained packets when subscribed.
|
12
|
+
* Fix problem of wrong Puback packet ID
|
13
|
+
* Don't keepalive ping if disconnected
|
14
|
+
* Immediately close socket after failed Connack
|
15
|
+
* FakeServer improvements
|
16
|
+
* Fix for working with mathn library.
|
17
|
+
|
18
|
+
|
4
19
|
Ruby MQTT Version 0.4.0 (2016-06-27)
|
5
20
|
------------------------------------
|
6
21
|
|
data/lib/mqtt/client.rb
CHANGED
@@ -10,7 +10,7 @@ class MQTT::Client
|
|
10
10
|
# Port number of the remote server
|
11
11
|
attr_accessor :port
|
12
12
|
|
13
|
-
# The version number of the MQTT protocol to use (default 3.1.
|
13
|
+
# The version number of the MQTT protocol to use (default 3.1.1)
|
14
14
|
attr_accessor :version
|
15
15
|
|
16
16
|
# Set to true to enable SSL/TLS encrypted communication
|
@@ -64,7 +64,7 @@ class MQTT::Client
|
|
64
64
|
ATTR_DEFAULTS = {
|
65
65
|
:host => nil,
|
66
66
|
:port => nil,
|
67
|
-
:version => '3.1.
|
67
|
+
:version => '3.1.1',
|
68
68
|
:keep_alive => 15,
|
69
69
|
:clean_session => true,
|
70
70
|
:client_id => nil,
|
@@ -264,6 +264,12 @@ class MQTT::Client
|
|
264
264
|
|
265
265
|
@socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ssl_context)
|
266
266
|
@socket.sync_close = true
|
267
|
+
|
268
|
+
# Set hostname on secure socket for Server Name Indication (SNI)
|
269
|
+
if @socket.respond_to?(:hostname=)
|
270
|
+
@socket.hostname = @host
|
271
|
+
end
|
272
|
+
|
267
273
|
@socket.connect
|
268
274
|
else
|
269
275
|
@socket = tcp_socket
|
@@ -393,15 +399,17 @@ class MQTT::Client
|
|
393
399
|
# # Do stuff here
|
394
400
|
# end
|
395
401
|
#
|
396
|
-
def get(topic=nil)
|
402
|
+
def get(topic=nil, options={})
|
397
403
|
if block_given?
|
398
404
|
get_packet(topic) do |packet|
|
399
|
-
yield(packet.topic, packet.payload)
|
405
|
+
yield(packet.topic, packet.payload) unless packet.retain && options[:omit_retained]
|
400
406
|
end
|
401
407
|
else
|
402
|
-
|
403
|
-
|
404
|
-
|
408
|
+
loop do
|
409
|
+
# Wait for one packet to be available
|
410
|
+
packet = get_packet(topic)
|
411
|
+
return packet.topic, packet.payload unless packet.retain && options[:omit_retained]
|
412
|
+
end
|
405
413
|
end
|
406
414
|
end
|
407
415
|
|
@@ -500,7 +508,7 @@ private
|
|
500
508
|
end
|
501
509
|
|
502
510
|
def keep_alive!
|
503
|
-
if @keep_alive > 0
|
511
|
+
if @keep_alive > 0 && connected?
|
504
512
|
response_timeout = (@keep_alive * 1.5).ceil
|
505
513
|
if Time.now >= @last_ping_request + @keep_alive
|
506
514
|
packet = MQTT::Packet::Pingreq.new
|
@@ -530,6 +538,9 @@ private
|
|
530
538
|
|
531
539
|
# Check the return code
|
532
540
|
if packet.return_code != 0x00
|
541
|
+
# 3.2.2.3 If a server sends a CONNACK packet containing a non-zero
|
542
|
+
# return code it MUST then close the Network Connection
|
543
|
+
@socket.close
|
533
544
|
raise MQTT::ProtocolException.new(packet.return_msg)
|
534
545
|
end
|
535
546
|
end
|
@@ -560,8 +571,8 @@ private
|
|
560
571
|
{
|
561
572
|
:host => uri.host,
|
562
573
|
:port => uri.port || nil,
|
563
|
-
:username => uri.user,
|
564
|
-
:password => uri.password,
|
574
|
+
:username => uri.user ? URI.unescape(uri.user) : nil,
|
575
|
+
:password => uri.password ? URI.unescape(uri.password) : nil,
|
565
576
|
:ssl => ssl
|
566
577
|
}
|
567
578
|
end
|
data/lib/mqtt/packet.rb
CHANGED
@@ -194,7 +194,7 @@ module MQTT
|
|
194
194
|
# Build up the body length field bytes
|
195
195
|
begin
|
196
196
|
digit = (body_length % 128)
|
197
|
-
body_length = (
|
197
|
+
body_length = body_length.div(128)
|
198
198
|
# if there are more digits to encode, set the top bit of this digit
|
199
199
|
digit |= 0x80 if (body_length > 0)
|
200
200
|
header.push(digit)
|
data/lib/mqtt/proxy.rb
CHANGED
@@ -95,19 +95,19 @@ class MQTT::Proxy
|
|
95
95
|
# Iterate through each of the sockets with data to read
|
96
96
|
if selected[0].include?(client_socket)
|
97
97
|
packet = MQTT::Packet.read(client_socket)
|
98
|
-
logger.debug "client -> <#{packet.
|
98
|
+
logger.debug "client -> <#{packet.type_name}>"
|
99
99
|
packet = @client_filter.call(packet) unless @client_filter.nil?
|
100
100
|
unless packet.nil?
|
101
101
|
server_socket.write(packet)
|
102
|
-
logger.debug "<#{packet.
|
102
|
+
logger.debug "<#{packet.type_name}> -> server"
|
103
103
|
end
|
104
104
|
elsif selected[0].include?(server_socket)
|
105
105
|
packet = MQTT::Packet.read(server_socket)
|
106
|
-
logger.debug "server -> <#{packet.
|
106
|
+
logger.debug "server -> <#{packet.type_name}>"
|
107
107
|
packet = @server_filter.call(packet) unless @server_filter.nil?
|
108
108
|
unless packet.nil?
|
109
109
|
client_socket.write(packet)
|
110
|
-
logger.debug "<#{packet.
|
110
|
+
logger.debug "<#{packet.type_name}> -> client"
|
111
111
|
end
|
112
112
|
else
|
113
113
|
logger.error "Problem with select: socket is neither server or client"
|
data/lib/mqtt/version.rb
CHANGED
data/spec/mqtt_client_spec.rb
CHANGED
@@ -28,7 +28,7 @@ describe MQTT::Client do
|
|
28
28
|
client = MQTT::Client.new
|
29
29
|
expect(client.host).to eq(nil)
|
30
30
|
expect(client.port).to eq(1883)
|
31
|
-
expect(client.version).to eq('3.1.
|
31
|
+
expect(client.version).to eq('3.1.1')
|
32
32
|
expect(client.keep_alive).to eq(15)
|
33
33
|
end
|
34
34
|
|
@@ -117,6 +117,22 @@ describe MQTT::Client do
|
|
117
117
|
expect(client.password).to eq('bpass')
|
118
118
|
end
|
119
119
|
|
120
|
+
it "with a URI containing an escaped username and password" do
|
121
|
+
client = MQTT::Client.new(URI.parse('mqtt://foo%20bar:%40123%2B%25@mqtt.example.com'))
|
122
|
+
expect(client.host).to eq('mqtt.example.com')
|
123
|
+
expect(client.port).to eq(1883)
|
124
|
+
expect(client.username).to eq('foo bar')
|
125
|
+
expect(client.password).to eq('@123+%')
|
126
|
+
end
|
127
|
+
|
128
|
+
it "with a URI containing a double escaped username and password" do
|
129
|
+
client = MQTT::Client.new(URI.parse('mqtt://foo%2520bar:123%2525@mqtt.example.com'))
|
130
|
+
expect(client.host).to eq('mqtt.example.com')
|
131
|
+
expect(client.port).to eq(1883)
|
132
|
+
expect(client.username).to eq('foo%20bar')
|
133
|
+
expect(client.password).to eq('123%25')
|
134
|
+
end
|
135
|
+
|
120
136
|
it "with a URI as a string" do
|
121
137
|
client = MQTT::Client.new('mqtt://mqtt.example.com')
|
122
138
|
expect(client.host).to eq('mqtt.example.com')
|
@@ -175,7 +191,7 @@ describe MQTT::Client do
|
|
175
191
|
expect(client.ssl_context.cert).to be_a(OpenSSL::X509::Certificate)
|
176
192
|
end
|
177
193
|
end
|
178
|
-
|
194
|
+
|
179
195
|
describe "setting a client private key file path" do
|
180
196
|
it "should add a certificate to the SSL context" do
|
181
197
|
expect(client.ssl_context.key).to be_nil
|
@@ -323,9 +339,9 @@ describe MQTT::Client do
|
|
323
339
|
client.password = 'password'
|
324
340
|
client.connect('myclient')
|
325
341
|
expect(socket.string).to eq(
|
326
|
-
"\x10\
|
327
|
-
"\x00\
|
328
|
-
"\
|
342
|
+
"\x10\x28"+
|
343
|
+
"\x00\x04MQTT"+
|
344
|
+
"\x04\xC2\x00\x0f"+
|
329
345
|
"\x00\x08myclient"+
|
330
346
|
"\x00\x08username"+
|
331
347
|
"\x00\x08password"
|
@@ -403,6 +419,15 @@ describe MQTT::Client do
|
|
403
419
|
allow(client).to receive(:receive_connack)
|
404
420
|
client.connect
|
405
421
|
end
|
422
|
+
|
423
|
+
it "should use set hostname on the SSL socket for SNI" do
|
424
|
+
expect(OpenSSL::SSL::SSLSocket).to receive(:new).and_return(ssl_socket)
|
425
|
+
expect(ssl_socket).to receive(:hostname=).with('mqtt.example.com')
|
426
|
+
|
427
|
+
client = MQTT::Client.new('mqtts://mqtt.example.com')
|
428
|
+
allow(client).to receive(:receive_connack)
|
429
|
+
client.connect
|
430
|
+
end
|
406
431
|
end
|
407
432
|
|
408
433
|
context "with a last will and testament set" do
|
@@ -429,9 +454,9 @@ describe MQTT::Client do
|
|
429
454
|
it "should include the will in the CONNECT message" do
|
430
455
|
client.connect('myclient')
|
431
456
|
expect(socket.string).to eq(
|
432
|
-
"\x10\
|
433
|
-
"\x00\
|
434
|
-
"\
|
457
|
+
"\x10\x22"+
|
458
|
+
"\x00\x04MQTT"+
|
459
|
+
"\x04\x0e\x00\x0f"+
|
435
460
|
"\x00\x08myclient"+
|
436
461
|
"\x00\x05topic\x00\x05hello"
|
437
462
|
)
|
@@ -473,6 +498,7 @@ describe MQTT::Client do
|
|
473
498
|
socket.write("\x20\x02\x00\x00")
|
474
499
|
socket.rewind
|
475
500
|
expect { client.send(:receive_connack) }.not_to raise_error
|
501
|
+
expect(socket).not_to be_closed
|
476
502
|
end
|
477
503
|
|
478
504
|
it "should raise an exception if the packet type isn't CONNACK" do
|
@@ -504,6 +530,13 @@ describe MQTT::Client do
|
|
504
530
|
socket.rewind
|
505
531
|
expect { client.send(:receive_connack) }.to raise_error(MQTT::ProtocolException, /connection refused/i)
|
506
532
|
end
|
533
|
+
|
534
|
+
it "should close the socket for an unsuccessful CONNACK packet" do
|
535
|
+
socket.write("\x20\x02\x00\x05")
|
536
|
+
socket.rewind
|
537
|
+
expect { client.send(:receive_connack) }.to raise_error(MQTT::ProtocolException, /not authorised/i)
|
538
|
+
expect(socket).to be_closed
|
539
|
+
end
|
507
540
|
end
|
508
541
|
|
509
542
|
describe "when calling the 'disconnect' method" do
|
@@ -595,7 +628,7 @@ describe MQTT::Client do
|
|
595
628
|
it "correctly assigns consecutive ids to packets with QoS 1" do
|
596
629
|
inject_puback(1)
|
597
630
|
inject_puback(2)
|
598
|
-
|
631
|
+
|
599
632
|
expect(client).to receive(:send_packet) { |packet| expect(packet.id).to eq(1) }
|
600
633
|
client.publish "topic", "message", false, 1
|
601
634
|
expect(client).to receive(:send_packet) { |packet| expect(packet.id).to eq(2) }
|
@@ -677,6 +710,15 @@ describe MQTT::Client do
|
|
677
710
|
expect(client.queue_empty?).to be_truthy
|
678
711
|
end
|
679
712
|
|
713
|
+
it "should successfully receive a valid PUBLISH packet, but not return it, if omit_retained is set" do
|
714
|
+
inject_packet(:topic => 'topic1', :payload => 'payload1', :qos => 1, :retain => 1)
|
715
|
+
inject_packet(:topic => 'topic1', :payload => 'payload2', :qos => 1)
|
716
|
+
topic,payload = client.get(nil, :omit_retained => true)
|
717
|
+
expect(topic).to eq('topic1')
|
718
|
+
expect(payload).to eq('payload2')
|
719
|
+
expect(client.queue_empty?).to be_truthy
|
720
|
+
end
|
721
|
+
|
680
722
|
it "acks calling #get_packet and qos=1" do
|
681
723
|
inject_packet(:topic => 'topic1', :payload => 'payload1', :qos => 1)
|
682
724
|
expect(client).to receive(:send_packet).with(an_instance_of(MQTT::Packet::Puback))
|
@@ -712,6 +754,18 @@ describe MQTT::Client do
|
|
712
754
|
break if payloads.size > 1
|
713
755
|
end
|
714
756
|
end
|
757
|
+
|
758
|
+
it "should ignore a PUBLISH message when it is marked as retained and omit_retained is set" do
|
759
|
+
inject_packet(:topic => 'topic0', :payload => 'payload0', :retain => 1)
|
760
|
+
inject_packet(:topic => 'topic1', :payload => 'payload1')
|
761
|
+
payloads = []
|
762
|
+
client.get(nil, :omit_retained => true) do |topic,payload|
|
763
|
+
payloads << payload
|
764
|
+
break if payloads.size > 0
|
765
|
+
end
|
766
|
+
expect(payloads.size).to eq(1)
|
767
|
+
expect(payloads).to eq(['payload1'])
|
768
|
+
end
|
715
769
|
end
|
716
770
|
end
|
717
771
|
|
@@ -845,6 +899,13 @@ describe MQTT::Client do
|
|
845
899
|
/No Ping Response received for \d+ seconds/
|
846
900
|
)
|
847
901
|
end
|
902
|
+
|
903
|
+
it "should not raise an exception if no ping response received and client is disconnected" do
|
904
|
+
client.instance_variable_set('@last_ping_request', Time.now)
|
905
|
+
client.instance_variable_set('@last_ping_response', Time.at(0))
|
906
|
+
client.disconnect(false)
|
907
|
+
client.send('keep_alive!')
|
908
|
+
end
|
848
909
|
end
|
849
910
|
|
850
911
|
describe "generating a client identifier" do
|
@@ -24,9 +24,13 @@ describe "a client talking to a server" do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
context "connecting and publishing a packet" do
|
27
|
-
def connect_and_publish
|
27
|
+
def connect_and_publish(options = {})
|
28
28
|
@client.connect
|
29
|
-
|
29
|
+
|
30
|
+
retain = options.fetch(:retain) { false }
|
31
|
+
qos = options.fetch(:qos) { 0 }
|
32
|
+
|
33
|
+
@client.publish('test', 'foobar', retain, qos)
|
30
34
|
@client.disconnect
|
31
35
|
@server.thread.join(1)
|
32
36
|
end
|
@@ -50,6 +54,13 @@ describe "a client talking to a server" do
|
|
50
54
|
connect_and_publish
|
51
55
|
expect(@error_log.string).to be_empty
|
52
56
|
end
|
57
|
+
|
58
|
+
context "with qos > 0" do
|
59
|
+
it "the server should have received a packet without timeout" do
|
60
|
+
connect_and_publish(:qos => 1)
|
61
|
+
expect(@server.last_publish).not_to be_nil
|
62
|
+
end
|
63
|
+
end
|
53
64
|
end
|
54
65
|
|
55
66
|
context "connecting, subscribing to a topic and getting a message" do
|
metadata
CHANGED
@@ -1,83 +1,83 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mqtt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas J Humfrey
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 1.11.2
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.11.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 10.2.2
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 10.2.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: yard
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.8.
|
47
|
+
version: 0.8.7
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.8.
|
54
|
+
version: 0.8.7
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 3.
|
61
|
+
version: 3.5.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 3.
|
68
|
+
version: 3.5.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: simplecov
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: 0.9.2
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 0.9.2
|
83
83
|
description: Pure Ruby gem that implements the MQTT protocol, a lightweight protocol
|
@@ -113,17 +113,17 @@ require_paths:
|
|
113
113
|
- lib
|
114
114
|
required_ruby_version: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
|
-
- -
|
116
|
+
- - ">="
|
117
117
|
- !ruby/object:Gem::Version
|
118
118
|
version: '0'
|
119
119
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
120
|
requirements:
|
121
|
-
- -
|
121
|
+
- - ">="
|
122
122
|
- !ruby/object:Gem::Version
|
123
123
|
version: '0'
|
124
124
|
requirements: []
|
125
125
|
rubyforge_project: mqtt
|
126
|
-
rubygems_version: 2.5
|
126
|
+
rubygems_version: 2.4.5
|
127
127
|
signing_key:
|
128
128
|
specification_version: 4
|
129
129
|
summary: Implementation of the MQTT protocol
|
@@ -134,4 +134,3 @@ test_files:
|
|
134
134
|
- spec/mqtt_sn_packet_spec.rb
|
135
135
|
- spec/mqtt_version_spec.rb
|
136
136
|
- spec/zz_client_integration_spec.rb
|
137
|
-
has_rdoc:
|