mqtt 0.4.0 → 0.6.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/README.md +1 -1
- data/lib/mqtt/client.rb +496 -469
- data/lib/mqtt/openssl_fix.rb +29 -0
- data/lib/mqtt/packet.rb +182 -235
- data/lib/mqtt/patches/string_encoding.rb +5 -7
- data/lib/mqtt/proxy.rb +85 -89
- data/lib/mqtt/sn/packet.rb +469 -512
- data/lib/mqtt/version.rb +1 -1
- data/lib/mqtt.rb +1 -3
- data/spec/mqtt_client_spec.rb +148 -16
- data/spec/mqtt_packet_spec.rb +8 -0
- data/spec/zz_client_integration_spec.rb +13 -2
- metadata +40 -27
data/lib/mqtt/version.rb
CHANGED
data/lib/mqtt.rb
CHANGED
@@ -13,7 +13,6 @@ unless String.method_defined?(:force_encoding)
|
|
13
13
|
end
|
14
14
|
|
15
15
|
module MQTT
|
16
|
-
|
17
16
|
# Default port number for unencrypted connections
|
18
17
|
DEFAULT_PORT = 1883
|
19
18
|
|
@@ -41,7 +40,6 @@ module MQTT
|
|
41
40
|
|
42
41
|
# MQTT-SN
|
43
42
|
module SN
|
44
|
-
|
45
43
|
# Default port number for unencrypted connections
|
46
44
|
DEFAULT_PORT = 1883
|
47
45
|
|
@@ -50,6 +48,6 @@ module MQTT
|
|
50
48
|
class ProtocolException < MQTT::Exception
|
51
49
|
end
|
52
50
|
|
53
|
-
autoload :Packet,
|
51
|
+
autoload :Packet, 'mqtt/sn/packet'
|
54
52
|
end
|
55
53
|
end
|
data/spec/mqtt_client_spec.rb
CHANGED
@@ -23,12 +23,23 @@ describe MQTT::Client do
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
if Process.const_defined? :CLOCK_MONOTONIC
|
27
|
+
def now
|
28
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
29
|
+
end
|
30
|
+
else
|
31
|
+
# Support older Ruby
|
32
|
+
def now
|
33
|
+
Time.now.to_f
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
26
37
|
describe "initializing a client" do
|
27
38
|
it "with no arguments, it should use the defaults" do
|
28
39
|
client = MQTT::Client.new
|
29
40
|
expect(client.host).to eq(nil)
|
30
41
|
expect(client.port).to eq(1883)
|
31
|
-
expect(client.version).to eq('3.1.
|
42
|
+
expect(client.version).to eq('3.1.1')
|
32
43
|
expect(client.keep_alive).to eq(15)
|
33
44
|
end
|
34
45
|
|
@@ -117,6 +128,22 @@ describe MQTT::Client do
|
|
117
128
|
expect(client.password).to eq('bpass')
|
118
129
|
end
|
119
130
|
|
131
|
+
it "with a URI containing an escaped username and password" do
|
132
|
+
client = MQTT::Client.new(URI.parse('mqtt://foo%20bar:%40123%2B%25@mqtt.example.com'))
|
133
|
+
expect(client.host).to eq('mqtt.example.com')
|
134
|
+
expect(client.port).to eq(1883)
|
135
|
+
expect(client.username).to eq('foo bar')
|
136
|
+
expect(client.password).to eq('@123+%')
|
137
|
+
end
|
138
|
+
|
139
|
+
it "with a URI containing a double escaped username and password" do
|
140
|
+
client = MQTT::Client.new(URI.parse('mqtt://foo%2520bar:123%2525@mqtt.example.com'))
|
141
|
+
expect(client.host).to eq('mqtt.example.com')
|
142
|
+
expect(client.port).to eq(1883)
|
143
|
+
expect(client.username).to eq('foo%20bar')
|
144
|
+
expect(client.password).to eq('123%25')
|
145
|
+
end
|
146
|
+
|
120
147
|
it "with a URI as a string" do
|
121
148
|
client = MQTT::Client.new('mqtt://mqtt.example.com')
|
122
149
|
expect(client.host).to eq('mqtt.example.com')
|
@@ -175,7 +202,7 @@ describe MQTT::Client do
|
|
175
202
|
expect(client.ssl_context.cert).to be_a(OpenSSL::X509::Certificate)
|
176
203
|
end
|
177
204
|
end
|
178
|
-
|
205
|
+
|
179
206
|
describe "setting a client private key file path" do
|
180
207
|
it "should add a certificate to the SSL context" do
|
181
208
|
expect(client.ssl_context.key).to be_nil
|
@@ -323,9 +350,9 @@ describe MQTT::Client do
|
|
323
350
|
client.password = 'password'
|
324
351
|
client.connect('myclient')
|
325
352
|
expect(socket.string).to eq(
|
326
|
-
"\x10\
|
327
|
-
"\x00\
|
328
|
-
"\
|
353
|
+
"\x10\x28"+
|
354
|
+
"\x00\x04MQTT"+
|
355
|
+
"\x04\xC2\x00\x0f"+
|
329
356
|
"\x00\x08myclient"+
|
330
357
|
"\x00\x08username"+
|
331
358
|
"\x00\x08password"
|
@@ -403,6 +430,15 @@ describe MQTT::Client do
|
|
403
430
|
allow(client).to receive(:receive_connack)
|
404
431
|
client.connect
|
405
432
|
end
|
433
|
+
|
434
|
+
it "should use set hostname on the SSL socket for SNI" do
|
435
|
+
expect(OpenSSL::SSL::SSLSocket).to receive(:new).and_return(ssl_socket)
|
436
|
+
expect(ssl_socket).to receive(:hostname=).with('mqtt.example.com')
|
437
|
+
|
438
|
+
client = MQTT::Client.new('mqtts://mqtt.example.com')
|
439
|
+
allow(client).to receive(:receive_connack)
|
440
|
+
client.connect
|
441
|
+
end
|
406
442
|
end
|
407
443
|
|
408
444
|
context "with a last will and testament set" do
|
@@ -429,9 +465,9 @@ describe MQTT::Client do
|
|
429
465
|
it "should include the will in the CONNECT message" do
|
430
466
|
client.connect('myclient')
|
431
467
|
expect(socket.string).to eq(
|
432
|
-
"\x10\
|
433
|
-
"\x00\
|
434
|
-
"\
|
468
|
+
"\x10\x22"+
|
469
|
+
"\x00\x04MQTT"+
|
470
|
+
"\x04\x0e\x00\x0f"+
|
435
471
|
"\x00\x08myclient"+
|
436
472
|
"\x00\x05topic\x00\x05hello"
|
437
473
|
)
|
@@ -473,6 +509,7 @@ describe MQTT::Client do
|
|
473
509
|
socket.write("\x20\x02\x00\x00")
|
474
510
|
socket.rewind
|
475
511
|
expect { client.send(:receive_connack) }.not_to raise_error
|
512
|
+
expect(socket).not_to be_closed
|
476
513
|
end
|
477
514
|
|
478
515
|
it "should raise an exception if the packet type isn't CONNACK" do
|
@@ -504,6 +541,13 @@ describe MQTT::Client do
|
|
504
541
|
socket.rewind
|
505
542
|
expect { client.send(:receive_connack) }.to raise_error(MQTT::ProtocolException, /connection refused/i)
|
506
543
|
end
|
544
|
+
|
545
|
+
it "should close the socket for an unsuccessful CONNACK packet" do
|
546
|
+
socket.write("\x20\x02\x00\x05")
|
547
|
+
socket.rewind
|
548
|
+
expect { client.send(:receive_connack) }.to raise_error(MQTT::ProtocolException, /not authorised/i)
|
549
|
+
expect(socket).to be_closed
|
550
|
+
end
|
507
551
|
end
|
508
552
|
|
509
553
|
describe "when calling the 'disconnect' method" do
|
@@ -538,10 +582,48 @@ describe MQTT::Client do
|
|
538
582
|
end
|
539
583
|
|
540
584
|
describe "when calling the 'publish' method" do
|
585
|
+
class ClientWithPubackInjection < MQTT::Client
|
586
|
+
def initialize
|
587
|
+
super(:host => 'localhost')
|
588
|
+
@injected_pubacks = {}
|
589
|
+
end
|
590
|
+
|
591
|
+
def inject_puback(packet)
|
592
|
+
@injected_pubacks[packet.id] = packet
|
593
|
+
end
|
594
|
+
|
595
|
+
def wait_for_puback(id, queue)
|
596
|
+
packet = @injected_pubacks.fetch(id) {
|
597
|
+
return super
|
598
|
+
}
|
599
|
+
queue << packet
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
let(:client) { ClientWithPubackInjection.new }
|
604
|
+
|
541
605
|
before(:each) do
|
542
606
|
client.instance_variable_set('@socket', socket)
|
543
607
|
end
|
544
608
|
|
609
|
+
it "should respect timeouts" do
|
610
|
+
require "socket"
|
611
|
+
rd, wr = UNIXSocket.pair
|
612
|
+
client = MQTT::Client.new(:host => 'localhost', :ack_timeout => 1.0)
|
613
|
+
client.instance_variable_set('@socket', rd)
|
614
|
+
t = Thread.new {
|
615
|
+
Thread.current[:parent] = Thread.main
|
616
|
+
loop do
|
617
|
+
client.send :receive_packet
|
618
|
+
end
|
619
|
+
}
|
620
|
+
start = now
|
621
|
+
expect(client.publish('topic','payload', false, 1)).to eq(-1)
|
622
|
+
elapsed = now - start
|
623
|
+
t.kill
|
624
|
+
expect(elapsed).to be_within(0.1).of(1.0)
|
625
|
+
end
|
626
|
+
|
545
627
|
it "should write a valid PUBLISH packet to the socket without the retain flag" do
|
546
628
|
client.publish('topic','payload', false, 0)
|
547
629
|
expect(socket.string).to eq("\x30\x0e\x00\x05topicpayload")
|
@@ -558,6 +640,19 @@ describe MQTT::Client do
|
|
558
640
|
expect(socket.string).to eq("\x32\x10\x00\x05topic\x00\x01payload")
|
559
641
|
end
|
560
642
|
|
643
|
+
it "should wrap the packet id after 65535" do
|
644
|
+
0xffff.times do |n|
|
645
|
+
inject_puback(n + 1)
|
646
|
+
client.publish('topic','payload', false, 1)
|
647
|
+
end
|
648
|
+
expect(client.instance_variable_get(:@last_packet_id)).to eq(0xffff)
|
649
|
+
|
650
|
+
socket.string = ""
|
651
|
+
inject_puback(1)
|
652
|
+
client.publish('topic','payload', false, 1)
|
653
|
+
expect(socket.string).to eq("\x32\x10\x00\x05topic\x00\x01payload")
|
654
|
+
end
|
655
|
+
|
561
656
|
it "should write a valid PUBLISH packet to the socket with the QoS set to 2" do
|
562
657
|
inject_puback(1)
|
563
658
|
client.publish('topic','payload', false, 2)
|
@@ -595,7 +690,7 @@ describe MQTT::Client do
|
|
595
690
|
it "correctly assigns consecutive ids to packets with QoS 1" do
|
596
691
|
inject_puback(1)
|
597
692
|
inject_puback(2)
|
598
|
-
|
693
|
+
|
599
694
|
expect(client).to receive(:send_packet) { |packet| expect(packet.id).to eq(1) }
|
600
695
|
client.publish "topic", "message", false, 1
|
601
696
|
expect(client).to receive(:send_packet) { |packet| expect(packet.id).to eq(2) }
|
@@ -657,6 +752,15 @@ describe MQTT::Client do
|
|
657
752
|
end
|
658
753
|
end
|
659
754
|
|
755
|
+
describe "when calling the 'clear_queue' method" do
|
756
|
+
it "should clear the waiting incoming messages" do
|
757
|
+
inject_packet(:topic => 'topic0', :payload => 'payload0', :qos => 0)
|
758
|
+
expect(client.queue_length).to eq(1)
|
759
|
+
client.clear_queue
|
760
|
+
expect(client.queue_length).to eq(0)
|
761
|
+
end
|
762
|
+
end
|
763
|
+
|
660
764
|
describe "when calling the 'get' method" do
|
661
765
|
before(:each) do
|
662
766
|
client.instance_variable_set('@socket', socket)
|
@@ -677,6 +781,15 @@ describe MQTT::Client do
|
|
677
781
|
expect(client.queue_empty?).to be_truthy
|
678
782
|
end
|
679
783
|
|
784
|
+
it "should successfully receive a valid PUBLISH packet, but not return it, if omit_retained is set" do
|
785
|
+
inject_packet(:topic => 'topic1', :payload => 'payload1', :qos => 1, :retain => 1)
|
786
|
+
inject_packet(:topic => 'topic1', :payload => 'payload2', :qos => 1)
|
787
|
+
topic,payload = client.get(nil, :omit_retained => true)
|
788
|
+
expect(topic).to eq('topic1')
|
789
|
+
expect(payload).to eq('payload2')
|
790
|
+
expect(client.queue_empty?).to be_truthy
|
791
|
+
end
|
792
|
+
|
680
793
|
it "acks calling #get_packet and qos=1" do
|
681
794
|
inject_packet(:topic => 'topic1', :payload => 'payload1', :qos => 1)
|
682
795
|
expect(client).to receive(:send_packet).with(an_instance_of(MQTT::Packet::Puback))
|
@@ -712,6 +825,18 @@ describe MQTT::Client do
|
|
712
825
|
break if payloads.size > 1
|
713
826
|
end
|
714
827
|
end
|
828
|
+
|
829
|
+
it "should ignore a PUBLISH message when it is marked as retained and omit_retained is set" do
|
830
|
+
inject_packet(:topic => 'topic0', :payload => 'payload0', :retain => 1)
|
831
|
+
inject_packet(:topic => 'topic1', :payload => 'payload1')
|
832
|
+
payloads = []
|
833
|
+
client.get(nil, :omit_retained => true) do |topic,payload|
|
834
|
+
payloads << payload
|
835
|
+
break if payloads.size > 0
|
836
|
+
end
|
837
|
+
expect(payloads.size).to eq(1)
|
838
|
+
expect(payloads).to eq(['payload1'])
|
839
|
+
end
|
715
840
|
end
|
716
841
|
end
|
717
842
|
|
@@ -814,7 +939,7 @@ describe MQTT::Client do
|
|
814
939
|
allow(MQTT::Packet).to receive(:read).and_return MQTT::Packet::Pingresp.new
|
815
940
|
client.instance_variable_set '@last_ping_response', Time.at(0)
|
816
941
|
client.send :receive_packet
|
817
|
-
expect(client.last_ping_response).to be_within(1).of
|
942
|
+
expect(client.last_ping_response).to be_within(1).of now
|
818
943
|
end
|
819
944
|
end
|
820
945
|
|
@@ -824,20 +949,20 @@ describe MQTT::Client do
|
|
824
949
|
end
|
825
950
|
|
826
951
|
it "should send a ping packet if one is due" do
|
827
|
-
client.instance_variable_set('@last_ping_request',
|
952
|
+
client.instance_variable_set('@last_ping_request', 0.0)
|
828
953
|
client.send('keep_alive!')
|
829
954
|
expect(socket.string).to eq("\xC0\x00")
|
830
955
|
end
|
831
956
|
|
832
957
|
it "should update the time a ping was last sent" do
|
833
|
-
client.instance_variable_set('@last_ping_request',
|
958
|
+
client.instance_variable_set('@last_ping_request', 0.0)
|
834
959
|
client.send('keep_alive!')
|
835
|
-
expect(client.instance_variable_get('@last_ping_request')).
|
960
|
+
expect(client.instance_variable_get('@last_ping_request')).to be_within(0.01).of(now)
|
836
961
|
end
|
837
962
|
|
838
963
|
it "should raise an exception if no ping response has been received" do
|
839
|
-
client.instance_variable_set('@last_ping_request',
|
840
|
-
client.instance_variable_set('@last_ping_response',
|
964
|
+
client.instance_variable_set('@last_ping_request', now)
|
965
|
+
client.instance_variable_set('@last_ping_response', 0.0)
|
841
966
|
expect {
|
842
967
|
client.send('keep_alive!')
|
843
968
|
}.to raise_error(
|
@@ -845,6 +970,13 @@ describe MQTT::Client do
|
|
845
970
|
/No Ping Response received for \d+ seconds/
|
846
971
|
)
|
847
972
|
end
|
973
|
+
|
974
|
+
it "should not raise an exception if no ping response received and client is disconnected" do
|
975
|
+
client.instance_variable_set('@last_ping_request', Time.now)
|
976
|
+
client.instance_variable_set('@last_ping_response', Time.at(0))
|
977
|
+
client.disconnect(false)
|
978
|
+
client.send('keep_alive!')
|
979
|
+
end
|
848
980
|
end
|
849
981
|
|
850
982
|
describe "generating a client identifier" do
|
@@ -890,7 +1022,7 @@ describe MQTT::Client do
|
|
890
1022
|
|
891
1023
|
def inject_puback(packet_id)
|
892
1024
|
packet = MQTT::Packet::Puback.new(:id => packet_id)
|
893
|
-
client.
|
1025
|
+
client.inject_puback packet
|
894
1026
|
end
|
895
1027
|
|
896
1028
|
end
|
data/spec/mqtt_packet_spec.rb
CHANGED
@@ -49,6 +49,14 @@ describe MQTT::Packet do
|
|
49
49
|
expect(data.encoding.to_s).to eq("ASCII-8BIT")
|
50
50
|
end
|
51
51
|
|
52
|
+
it "should raise an error if too big argument for encode_short" do
|
53
|
+
expect {
|
54
|
+
data = packet.send(:encode_short, 0x10000)
|
55
|
+
}.to raise_error(
|
56
|
+
'Value too big for short'
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
52
60
|
it "should provide a add_string method to get a string preceeded by its length" do
|
53
61
|
data = packet.send(:encode_string, 'quack')
|
54
62
|
expect(data).to eq("\x00\x05quack")
|
@@ -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,85 +1,99 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mqtt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas J Humfrey
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-17 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.
|
47
|
+
version: 0.9.11
|
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.
|
54
|
+
version: 0.9.11
|
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
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.45'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.45'
|
83
97
|
description: Pure Ruby gem that implements the MQTT protocol, a lightweight protocol
|
84
98
|
for publish/subscribe messaging.
|
85
99
|
email: njh@aelius.com
|
@@ -92,6 +106,7 @@ files:
|
|
92
106
|
- README.md
|
93
107
|
- lib/mqtt.rb
|
94
108
|
- lib/mqtt/client.rb
|
109
|
+
- lib/mqtt/openssl_fix.rb
|
95
110
|
- lib/mqtt/packet.rb
|
96
111
|
- lib/mqtt/patches/string_encoding.rb
|
97
112
|
- lib/mqtt/proxy.rb
|
@@ -103,28 +118,27 @@ files:
|
|
103
118
|
- spec/mqtt_sn_packet_spec.rb
|
104
119
|
- spec/mqtt_version_spec.rb
|
105
120
|
- spec/zz_client_integration_spec.rb
|
106
|
-
homepage:
|
121
|
+
homepage: https://github.com/njh/ruby-mqtt
|
107
122
|
licenses:
|
108
123
|
- MIT
|
109
124
|
metadata: {}
|
110
|
-
post_install_message:
|
125
|
+
post_install_message:
|
111
126
|
rdoc_options: []
|
112
127
|
require_paths:
|
113
128
|
- lib
|
114
129
|
required_ruby_version: !ruby/object:Gem::Requirement
|
115
130
|
requirements:
|
116
|
-
- -
|
131
|
+
- - ">="
|
117
132
|
- !ruby/object:Gem::Version
|
118
133
|
version: '0'
|
119
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
135
|
requirements:
|
121
|
-
- -
|
136
|
+
- - ">="
|
122
137
|
- !ruby/object:Gem::Version
|
123
138
|
version: '0'
|
124
139
|
requirements: []
|
125
|
-
|
126
|
-
|
127
|
-
signing_key:
|
140
|
+
rubygems_version: 3.3.7
|
141
|
+
signing_key:
|
128
142
|
specification_version: 4
|
129
143
|
summary: Implementation of the MQTT protocol
|
130
144
|
test_files:
|
@@ -134,4 +148,3 @@ test_files:
|
|
134
148
|
- spec/mqtt_sn_packet_spec.rb
|
135
149
|
- spec/mqtt_version_spec.rb
|
136
150
|
- spec/zz_client_integration_spec.rb
|
137
|
-
has_rdoc:
|