paho-mqtt 0.0.2 → 1.0.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 +4 -4
- data/README.md +289 -10
- data/lib/paho-mqtt.rb +26 -8
- data/lib/{paho.mqtt/paho_client.rb → paho_mqtt/client.rb} +130 -99
- data/lib/paho_mqtt/packet.rb +19 -0
- data/lib/paho_mqtt/packet/base.rb +290 -0
- data/lib/paho_mqtt/packet/connack.rb +84 -0
- data/lib/paho_mqtt/packet/connect.rb +149 -0
- data/lib/paho_mqtt/packet/disconnect.rb +20 -0
- data/lib/paho_mqtt/packet/pingreq.rb +12 -0
- data/lib/paho_mqtt/packet/pingresp.rb +20 -0
- data/lib/paho_mqtt/packet/puback.rb +27 -0
- data/lib/paho_mqtt/packet/pubcomp.rb +26 -0
- data/lib/paho_mqtt/packet/publish.rb +127 -0
- data/lib/paho_mqtt/packet/pubrec.rb +26 -0
- data/lib/paho_mqtt/packet/pubrel.rb +44 -0
- data/lib/paho_mqtt/packet/suback.rb +56 -0
- data/lib/paho_mqtt/packet/subscribe.rb +104 -0
- data/lib/paho_mqtt/packet/unsuback.rb +31 -0
- data/lib/paho_mqtt/packet/unsubscribe.rb +65 -0
- data/lib/{paho.mqtt → paho_mqtt}/version.rb +1 -1
- data/paho-mqtt.gemspec +2 -2
- data/samples/client_blocking(writing).rb +16 -0
- data/samples/client_blocking.rb +34 -0
- data/samples/getting_started.rb +49 -0
- metadata +24 -8
- data/lib/paho.mqtt/packet_manager.rb +0 -1056
- data/paho-mqtt-0.0.1.gem +0 -0
- data/samples/test_aws.rb +0 -31
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
|
3
|
+
module PahoMqtt
|
4
|
+
module Packet
|
5
|
+
class Disconnect < PahoMqtt::Packet::Base
|
6
|
+
# Create a new Client Disconnect packet
|
7
|
+
def initialize(args={})
|
8
|
+
super(args)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Check the body
|
12
|
+
def parse_body(buffer)
|
13
|
+
super(buffer)
|
14
|
+
unless buffer.empty?
|
15
|
+
raise "Extra bytes at end of Disconnect packet"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
|
3
|
+
module PahoMqtt
|
4
|
+
module Packet
|
5
|
+
class Pingresp < PahoMqtt::Packet::Base
|
6
|
+
# Create a new Ping Response packet
|
7
|
+
def initialize(args={})
|
8
|
+
super(args)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Check the body
|
12
|
+
def parse_body(buffer)
|
13
|
+
super(buffer)
|
14
|
+
unless buffer.empty?
|
15
|
+
raise "Extra bytes at end of Ping Response packet"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
|
3
|
+
module PahoMqtt
|
4
|
+
module Packet
|
5
|
+
class Puback < PahoMqtt::Packet::Base
|
6
|
+
# Get serialisation of packet's body
|
7
|
+
def encode_body
|
8
|
+
encode_short(@id)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Parse the body (variable header and payload) of a packet
|
12
|
+
def parse_body(buffer)
|
13
|
+
super(buffer)
|
14
|
+
@id = shift_short(buffer)
|
15
|
+
unless buffer.empty?
|
16
|
+
raise "Extra bytes at end of Publish Acknowledgment packet"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns a human readable string, summarising the properties of the packet
|
21
|
+
def inspect
|
22
|
+
"\#<#{self.class}: 0x%2.2X>" % id
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
|
3
|
+
module PahoMqtt
|
4
|
+
module Packet
|
5
|
+
class Pubcomp < PahoMqtt::Packet::Base
|
6
|
+
# Get serialisation of packet's body
|
7
|
+
def encode_body
|
8
|
+
encode_short(@id)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Parse the body (variable header and payload) of a packet
|
12
|
+
def parse_body(buffer)
|
13
|
+
super(buffer)
|
14
|
+
@id = shift_short(buffer)
|
15
|
+
unless buffer.empty?
|
16
|
+
raise "Extra bytes at end of Publish Complete packet"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns a human readable string, summarising the properties of the packet
|
21
|
+
def inspect
|
22
|
+
"\#<#{self.class}: 0x%2.2X>" % id
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
|
3
|
+
module PahoMqtt
|
4
|
+
module Packet
|
5
|
+
class Publish < PahoMqtt::Packet::Base
|
6
|
+
# Duplicate delivery flag
|
7
|
+
attr_accessor :duplicate
|
8
|
+
|
9
|
+
# Retain flag
|
10
|
+
attr_accessor :retain
|
11
|
+
|
12
|
+
# Quality of Service level (0, 1, 2)
|
13
|
+
attr_accessor :qos
|
14
|
+
|
15
|
+
# The topic name to publish to
|
16
|
+
attr_accessor :topic
|
17
|
+
|
18
|
+
# The data to be published
|
19
|
+
attr_accessor :payload
|
20
|
+
|
21
|
+
# Default attribute values
|
22
|
+
ATTR_DEFAULTS = {
|
23
|
+
:topic => nil,
|
24
|
+
:payload => ''
|
25
|
+
}
|
26
|
+
|
27
|
+
# Create a new Publish packet
|
28
|
+
def initialize(args={})
|
29
|
+
super(ATTR_DEFAULTS.merge(args))
|
30
|
+
end
|
31
|
+
|
32
|
+
def duplicate
|
33
|
+
@flags[3]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Set the DUP flag (true/false)
|
37
|
+
def duplicate=(arg)
|
38
|
+
if arg.kind_of?(Integer)
|
39
|
+
@flags[3] = (arg == 0x1)
|
40
|
+
else
|
41
|
+
@flags[3] = arg
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def retain
|
46
|
+
@flags[0]
|
47
|
+
end
|
48
|
+
|
49
|
+
# Set the retain flag (true/false)
|
50
|
+
def retain=(arg)
|
51
|
+
if arg.kind_of?(Integer)
|
52
|
+
@flags[0] = (arg == 0x1)
|
53
|
+
else
|
54
|
+
@flags[0] = arg
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def qos
|
59
|
+
(@flags[1] ? 0x01 : 0x00) | (@flags[2] ? 0x02 : 0x00)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Set the Quality of Service level (0/1/2)
|
63
|
+
def qos=(arg)
|
64
|
+
@qos = arg.to_i
|
65
|
+
if @qos < 0 or @qos > 2
|
66
|
+
raise "Invalid QoS value: #{@qos}"
|
67
|
+
else
|
68
|
+
@flags[1] = (arg & 0x01 == 0x01)
|
69
|
+
@flags[2] = (arg & 0x02 == 0x02)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Get serialisation of packet's body
|
74
|
+
def encode_body
|
75
|
+
body = ''
|
76
|
+
if @topic.nil? or @topic.to_s.empty?
|
77
|
+
raise "Invalid topic name when serialising packet"
|
78
|
+
end
|
79
|
+
body += encode_string(@topic)
|
80
|
+
body += encode_short(@id) unless qos == 0
|
81
|
+
body += payload.to_s.dup.force_encoding('ASCII-8BIT')
|
82
|
+
return body
|
83
|
+
end
|
84
|
+
|
85
|
+
# Parse the body (variable header and payload) of a Publish packet
|
86
|
+
def parse_body(buffer)
|
87
|
+
super(buffer)
|
88
|
+
@topic = shift_string(buffer)
|
89
|
+
@id = shift_short(buffer) unless qos == 0
|
90
|
+
@payload = buffer
|
91
|
+
end
|
92
|
+
|
93
|
+
# Check that fixed header flags are valid for this packet type
|
94
|
+
# @private
|
95
|
+
def validate_flags
|
96
|
+
if qos == 3
|
97
|
+
raise "Invalid packet: QoS value of 3 is not allowed"
|
98
|
+
end
|
99
|
+
if qos == 0 and duplicate
|
100
|
+
raise "Invalid packet: DUP cannot be set for QoS 0"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns a human readable string, summarising the properties of the packet
|
105
|
+
def inspect
|
106
|
+
"\#<#{self.class}: " +
|
107
|
+
"d#{duplicate ? '1' : '0'}, " +
|
108
|
+
"q#{qos}, " +
|
109
|
+
"r#{retain ? '1' : '0'}, " +
|
110
|
+
"m#{id}, " +
|
111
|
+
"'#{topic}', " +
|
112
|
+
"#{inspect_payload}>"
|
113
|
+
end
|
114
|
+
|
115
|
+
protected
|
116
|
+
|
117
|
+
def inspect_payload
|
118
|
+
str = payload.to_s
|
119
|
+
if str.bytesize < 16 and str =~ /^[ -~]*$/
|
120
|
+
"'#{str}'"
|
121
|
+
else
|
122
|
+
"... (#{str.bytesize} bytes)"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
|
3
|
+
module PahoMqtt
|
4
|
+
module Packet
|
5
|
+
class Pubrec < PahoMqtt::Packet::Base
|
6
|
+
# Get serialisation of packet's body
|
7
|
+
def encode_body
|
8
|
+
encode_short(@id)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Parse the body (variable header and payload) of a packet
|
12
|
+
def parse_body(buffer)
|
13
|
+
super(buffer)
|
14
|
+
@id = shift_short(buffer)
|
15
|
+
unless buffer.empty?
|
16
|
+
raise "Extra bytes at end of Publish Received packet"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns a human readable string, summarising the properties of the packet
|
21
|
+
def inspect
|
22
|
+
"\#<#{self.class}: 0x%2.2X>" % id
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
|
3
|
+
module PahoMqtt
|
4
|
+
module Packet
|
5
|
+
class Pubrel < PahoMqtt::Packet::Base
|
6
|
+
# Default attribute values
|
7
|
+
ATTR_DEFAULTS = {
|
8
|
+
:flags => [false, true, false, false],
|
9
|
+
}
|
10
|
+
|
11
|
+
# Create a new Pubrel packet
|
12
|
+
def initialize(args={})
|
13
|
+
super(ATTR_DEFAULTS.merge(args))
|
14
|
+
end
|
15
|
+
|
16
|
+
# Get serialisation of packet's body
|
17
|
+
def encode_body
|
18
|
+
encode_short(@id)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Parse the body (variable header and payload) of a packet
|
22
|
+
def parse_body(buffer)
|
23
|
+
super(buffer)
|
24
|
+
@id = shift_short(buffer)
|
25
|
+
unless buffer.empty?
|
26
|
+
raise "Extra bytes at end of Publish Release packet"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Check that fixed header flags are valid for this packet type
|
31
|
+
# @private
|
32
|
+
def validate_flags
|
33
|
+
if @flags != [false, true, false, false]
|
34
|
+
raise "Invalid flags in PUBREL packet header"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns a human readable string, summarising the properties of the packet
|
39
|
+
def inspect
|
40
|
+
"\#<#{self.class}: 0x%2.2X>" % id
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
|
3
|
+
module PahoMqtt
|
4
|
+
module Packet
|
5
|
+
class Suback < PahoMqtt::Packet::Base
|
6
|
+
# An array of return codes, ordered by the topics that were subscribed to
|
7
|
+
attr_accessor :return_codes
|
8
|
+
|
9
|
+
# Default attribute values
|
10
|
+
ATTR_DEFAULTS = {
|
11
|
+
:return_codes => [],
|
12
|
+
}
|
13
|
+
|
14
|
+
# Create a new Subscribe Acknowledgment packet
|
15
|
+
def initialize(args={})
|
16
|
+
super(ATTR_DEFAULTS.merge(args))
|
17
|
+
end
|
18
|
+
|
19
|
+
# Set the granted QoS value for each of the topics that were subscribed to
|
20
|
+
# Can either be an integer or an array or integers.
|
21
|
+
def return_codes=(value)
|
22
|
+
if value.is_a?(Array)
|
23
|
+
@return_codes = value
|
24
|
+
elsif value.is_a?(Integer)
|
25
|
+
@return_codes = [value]
|
26
|
+
else
|
27
|
+
raise "return_codes should be an integer or an array of return codes"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Get serialisation of packet's body
|
32
|
+
def encode_body
|
33
|
+
if @return_codes.empty?
|
34
|
+
raise "no granted QoS given when serialising packet"
|
35
|
+
end
|
36
|
+
body = encode_short(@id)
|
37
|
+
return_codes.each { |qos| body += encode_bytes(qos) }
|
38
|
+
return body
|
39
|
+
end
|
40
|
+
|
41
|
+
# Parse the body (variable header and payload) of a packet
|
42
|
+
def parse_body(buffer)
|
43
|
+
super(buffer)
|
44
|
+
@id = shift_short(buffer)
|
45
|
+
while(buffer.bytesize>0)
|
46
|
+
@return_codes << shift_byte(buffer)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns a human readable string, summarising the properties of the packet
|
51
|
+
def inspect
|
52
|
+
"\#<#{self.class}: 0x%2.2X, rc=%s>" % [id, return_codes.map{|rc| "0x%2.2X" % rc}.join(',')]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
|
3
|
+
module PahoMqtt
|
4
|
+
module Packet
|
5
|
+
class Subscribe < PahoMqtt::Packet::Base
|
6
|
+
# One or more topic filters to subscribe to
|
7
|
+
attr_accessor :topics
|
8
|
+
|
9
|
+
# Default attribute values
|
10
|
+
ATTR_DEFAULTS = {
|
11
|
+
:topics => [],
|
12
|
+
:flags => [false, true, false, false],
|
13
|
+
}
|
14
|
+
|
15
|
+
# Create a new Subscribe packet
|
16
|
+
def initialize(args={})
|
17
|
+
super(ATTR_DEFAULTS.merge(args))
|
18
|
+
end
|
19
|
+
|
20
|
+
# Set one or more topic filters for the Subscribe packet
|
21
|
+
# The topics parameter should be one of the following:
|
22
|
+
# * String: subscribe to one topic with QoS 0
|
23
|
+
# * Array: subscribe to multiple topics with QoS 0
|
24
|
+
# * Hash: subscribe to multiple topics where the key is the topic and the value is the QoS level
|
25
|
+
#
|
26
|
+
# For example:
|
27
|
+
# packet.topics = 'a/b'
|
28
|
+
# packet.topics = ['a/b', 'c/d']
|
29
|
+
# packet.topics = [['a/b',0], ['c/d',1]]
|
30
|
+
# packet.topics = {'a/b' => 0, 'c/d' => 1}
|
31
|
+
#
|
32
|
+
def topics=(value)
|
33
|
+
# Get input into a consistent state
|
34
|
+
if value.is_a?(Array)
|
35
|
+
input = value.flatten
|
36
|
+
else
|
37
|
+
input = [value]
|
38
|
+
end
|
39
|
+
|
40
|
+
@topics = []
|
41
|
+
while(input.length>0)
|
42
|
+
item = input.shift
|
43
|
+
if item.is_a?(Hash)
|
44
|
+
# Convert hash into an ordered array of arrays
|
45
|
+
@topics += item.sort
|
46
|
+
elsif item.is_a?(String)
|
47
|
+
# Peek at the next item in the array, and remove it if it is an integer
|
48
|
+
if input.first.is_a?(Integer)
|
49
|
+
qos = input.shift
|
50
|
+
@topics << [item,qos]
|
51
|
+
else
|
52
|
+
@topics << [item,0]
|
53
|
+
end
|
54
|
+
else
|
55
|
+
# Meh?
|
56
|
+
raise "Invalid topics input: #{value.inspect}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
@topics
|
60
|
+
end
|
61
|
+
|
62
|
+
# Get serialisation of packet's body
|
63
|
+
def encode_body
|
64
|
+
if @topics.empty?
|
65
|
+
raise "no topics given when serialising packet"
|
66
|
+
end
|
67
|
+
body = encode_short(@id)
|
68
|
+
topics.each do |item|
|
69
|
+
body += encode_string(item[0])
|
70
|
+
body += encode_bytes(item[1])
|
71
|
+
end
|
72
|
+
return body
|
73
|
+
end
|
74
|
+
|
75
|
+
# Parse the body (variable header and payload) of a packet
|
76
|
+
def parse_body(buffer)
|
77
|
+
super(buffer)
|
78
|
+
@id = shift_short(buffer)
|
79
|
+
@topics = []
|
80
|
+
while(buffer.bytesize>0)
|
81
|
+
topic_name = shift_string(buffer)
|
82
|
+
topic_qos = shift_byte(buffer)
|
83
|
+
@topics << [topic_name,topic_qos]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Check that fixed header flags are valid for this packet type
|
88
|
+
# @private
|
89
|
+
def validate_flags
|
90
|
+
if @flags != [false, true, false, false]
|
91
|
+
raise "Invalid flags in SUBSCRIBE packet header"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Returns a human readable string, summarising the properties of the packet
|
96
|
+
def inspect
|
97
|
+
_str = "\#<#{self.class}: 0x%2.2X, %s>" % [
|
98
|
+
id,
|
99
|
+
topics.map {|t| "'#{t[0]}':#{t[1]}"}.join(', ')
|
100
|
+
]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|