paho-mqtt 0.0.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|