mqtt 0.4.0 → 0.6.0
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.
- 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:
|