mqtt 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/NEWS.md +1 -1
- data/README.md +1 -1
- data/lib/mqtt/client.rb +495 -479
- data/lib/mqtt/openssl_fix.rb +29 -0
- data/lib/mqtt/packet.rb +181 -234
- data/lib/mqtt/patches/string_encoding.rb +5 -7
- data/lib/mqtt/proxy.rb +81 -85
- 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 +78 -7
- data/spec/mqtt_packet_spec.rb +8 -0
- metadata +24 -10
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,6 +23,17 @@ 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
|
@@ -571,10 +582,48 @@ describe MQTT::Client do
|
|
571
582
|
end
|
572
583
|
|
573
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
|
+
|
574
605
|
before(:each) do
|
575
606
|
client.instance_variable_set('@socket', socket)
|
576
607
|
end
|
577
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
|
+
|
578
627
|
it "should write a valid PUBLISH packet to the socket without the retain flag" do
|
579
628
|
client.publish('topic','payload', false, 0)
|
580
629
|
expect(socket.string).to eq("\x30\x0e\x00\x05topicpayload")
|
@@ -591,6 +640,19 @@ describe MQTT::Client do
|
|
591
640
|
expect(socket.string).to eq("\x32\x10\x00\x05topic\x00\x01payload")
|
592
641
|
end
|
593
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
|
+
|
594
656
|
it "should write a valid PUBLISH packet to the socket with the QoS set to 2" do
|
595
657
|
inject_puback(1)
|
596
658
|
client.publish('topic','payload', false, 2)
|
@@ -690,6 +752,15 @@ describe MQTT::Client do
|
|
690
752
|
end
|
691
753
|
end
|
692
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
|
+
|
693
764
|
describe "when calling the 'get' method" do
|
694
765
|
before(:each) do
|
695
766
|
client.instance_variable_set('@socket', socket)
|
@@ -868,7 +939,7 @@ describe MQTT::Client do
|
|
868
939
|
allow(MQTT::Packet).to receive(:read).and_return MQTT::Packet::Pingresp.new
|
869
940
|
client.instance_variable_set '@last_ping_response', Time.at(0)
|
870
941
|
client.send :receive_packet
|
871
|
-
expect(client.last_ping_response).to be_within(1).of
|
942
|
+
expect(client.last_ping_response).to be_within(1).of now
|
872
943
|
end
|
873
944
|
end
|
874
945
|
|
@@ -878,20 +949,20 @@ describe MQTT::Client do
|
|
878
949
|
end
|
879
950
|
|
880
951
|
it "should send a ping packet if one is due" do
|
881
|
-
client.instance_variable_set('@last_ping_request',
|
952
|
+
client.instance_variable_set('@last_ping_request', 0.0)
|
882
953
|
client.send('keep_alive!')
|
883
954
|
expect(socket.string).to eq("\xC0\x00")
|
884
955
|
end
|
885
956
|
|
886
957
|
it "should update the time a ping was last sent" do
|
887
|
-
client.instance_variable_set('@last_ping_request',
|
958
|
+
client.instance_variable_set('@last_ping_request', 0.0)
|
888
959
|
client.send('keep_alive!')
|
889
|
-
expect(client.instance_variable_get('@last_ping_request')).
|
960
|
+
expect(client.instance_variable_get('@last_ping_request')).to be_within(0.01).of(now)
|
890
961
|
end
|
891
962
|
|
892
963
|
it "should raise an exception if no ping response has been received" do
|
893
|
-
client.instance_variable_set('@last_ping_request',
|
894
|
-
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)
|
895
966
|
expect {
|
896
967
|
client.send('keep_alive!')
|
897
968
|
}.to raise_error(
|
@@ -951,7 +1022,7 @@ describe MQTT::Client do
|
|
951
1022
|
|
952
1023
|
def inject_puback(packet_id)
|
953
1024
|
packet = MQTT::Packet::Puback.new(:id => packet_id)
|
954
|
-
client.
|
1025
|
+
client.inject_puback packet
|
955
1026
|
end
|
956
1027
|
|
957
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")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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
|
@@ -44,14 +44,14 @@ dependencies:
|
|
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
|
@@ -80,6 +80,20 @@ dependencies:
|
|
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,11 +118,11 @@ 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
|
@@ -122,9 +137,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
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:
|