mqtt 0.1.0 → 0.2.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.
- data/{LICENSE → LICENSE.md} +0 -0
- data/{NEWS → NEWS.md} +15 -0
- data/{README → README.md} +3 -2
- data/lib/mqtt.rb +10 -1
- data/lib/mqtt/client.rb +192 -40
- data/lib/mqtt/packet.rb +114 -34
- data/lib/mqtt/proxy.rb +12 -2
- data/lib/mqtt/version.rb +1 -1
- data/spec/mqtt_client_spec.rb +355 -175
- data/spec/mqtt_packet_spec.rb +241 -273
- data/spec/{zz_integration_spec.rb → zz_client_integration_spec.rb} +0 -0
- metadata +90 -107
data/{LICENSE → LICENSE.md}
RENAMED
File without changes
|
data/{NEWS → NEWS.md}
RENAMED
@@ -1,6 +1,21 @@
|
|
1
1
|
Ruby MQTT NEWS
|
2
2
|
==============
|
3
3
|
|
4
|
+
Ruby MQTT Version 0.2.0 (2014-04-02)
|
5
|
+
------------------------------------
|
6
|
+
|
7
|
+
* Added SSL/TLS support
|
8
|
+
* Added support for passing connection details using a URI
|
9
|
+
* Added support for using the MQTT_BROKER environment variable
|
10
|
+
* Allow passing array of topics to Client#unsubscribe
|
11
|
+
* Allow more combinations of arguments to be passed to a new Client
|
12
|
+
* No longer defaults to ‘localhost’ if there is no broker configured
|
13
|
+
* Fixed more 'unused variable' warnings
|
14
|
+
* Documentation improvements
|
15
|
+
* Ruby 1.8 fixes
|
16
|
+
* Ruby 2 fixes
|
17
|
+
|
18
|
+
|
4
19
|
Ruby MQTT Version 0.1.0 (2013-09-07)
|
5
20
|
------------------------------------
|
6
21
|
|
data/{README → README.md}
RENAMED
@@ -1,8 +1,7 @@
|
|
1
1
|
ruby-mqtt
|
2
2
|
=========
|
3
3
|
|
4
|
-
Pure Ruby gem that implements the MQTT
|
5
|
-
a lightweight protocol for publish/subscribe messaging.
|
4
|
+
Pure Ruby gem that implements the MQTT protocol, a lightweight protocol for publish/subscribe messaging.
|
6
5
|
|
7
6
|
|
8
7
|
Installing
|
@@ -46,12 +45,14 @@ Resources
|
|
46
45
|
* GitHub Project: http://github.com/njh/ruby-mqtt
|
47
46
|
* API Documentation: http://rubydoc.info/gems/mqtt/frames
|
48
47
|
|
48
|
+
|
49
49
|
License
|
50
50
|
-------
|
51
51
|
|
52
52
|
The ruby-mqtt gem is licensed under the terms of the MIT license.
|
53
53
|
See the file LICENSE for details.
|
54
54
|
|
55
|
+
|
55
56
|
Contact
|
56
57
|
-------
|
57
58
|
|
data/lib/mqtt.rb
CHANGED
@@ -14,15 +14,24 @@ end
|
|
14
14
|
|
15
15
|
module MQTT
|
16
16
|
|
17
|
-
|
17
|
+
# Default port number for unencrypted connections
|
18
18
|
DEFAULT_PORT = 1883
|
19
|
+
|
20
|
+
# Default port number for TLS/SSL encrypted connections
|
21
|
+
DEFAULT_SSL_PORT = 8883
|
19
22
|
|
23
|
+
# Super-class for other MQTT related exceptions
|
20
24
|
class Exception < Exception
|
21
25
|
end
|
22
26
|
|
27
|
+
# A ProtocolException will be raised if there is a
|
28
|
+
# problem with data received from a remote host
|
23
29
|
class ProtocolException < MQTT::Exception
|
24
30
|
end
|
25
31
|
|
32
|
+
# A NotConnectedException will be raised when trying to
|
33
|
+
# perform a function but no connection has been
|
34
|
+
# established
|
26
35
|
class NotConnectedException < MQTT::Exception
|
27
36
|
end
|
28
37
|
|
data/lib/mqtt/client.rb
CHANGED
@@ -1,29 +1,63 @@
|
|
1
|
+
autoload :OpenSSL, 'openssl'
|
2
|
+
autoload :URI, 'uri'
|
3
|
+
|
4
|
+
|
1
5
|
# Client class for talking to an MQTT broker
|
2
6
|
class MQTT::Client
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
attr_accessor :
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
#
|
17
|
-
|
18
|
-
|
7
|
+
# Hostname of the remote broker
|
8
|
+
attr_accessor :remote_host
|
9
|
+
|
10
|
+
# Port number of the remote broker
|
11
|
+
attr_accessor :remote_port
|
12
|
+
|
13
|
+
# Set to true to enable SSL/TLS encrypted communication
|
14
|
+
#
|
15
|
+
# Set to a symbol to use a specific variant of SSL/TLS.
|
16
|
+
# Allowed values include:
|
17
|
+
#
|
18
|
+
# @example Using TLS 1.0
|
19
|
+
# client = Client.new('mqtt.example.com', :ssl => :TLSv1)
|
20
|
+
# @see OpenSSL::SSL::SSLContext::METHODS
|
21
|
+
attr_accessor :ssl
|
22
|
+
|
23
|
+
# Time (in seconds) between pings to remote broker
|
24
|
+
attr_accessor :keep_alive
|
25
|
+
|
26
|
+
# Set the 'Clean Session' flag when connecting?
|
27
|
+
attr_accessor :clean_session
|
28
|
+
|
29
|
+
# Client Identifier
|
30
|
+
attr_accessor :client_id
|
31
|
+
|
32
|
+
# Number of seconds to wait for acknowledgement packets
|
33
|
+
attr_accessor :ack_timeout
|
34
|
+
|
35
|
+
# Username to authenticate to the broker with
|
36
|
+
attr_accessor :username
|
37
|
+
|
38
|
+
# Password to authenticate to the broker with
|
39
|
+
attr_accessor :password
|
40
|
+
|
41
|
+
# The topic that the Will message is published to
|
42
|
+
attr_accessor :will_topic
|
43
|
+
|
44
|
+
# Contents of message that is sent by broker when client disconnect
|
45
|
+
attr_accessor :will_payload
|
46
|
+
|
47
|
+
# The QoS level of the will message sent by the broker
|
48
|
+
attr_accessor :will_qos
|
49
|
+
|
50
|
+
# If the Will message should be retain by the broker after it is sent
|
51
|
+
attr_accessor :will_retain
|
52
|
+
|
19
53
|
|
20
54
|
# Timeout between select polls (in seconds)
|
21
55
|
SELECT_TIMEOUT = 0.5
|
22
56
|
|
23
57
|
# Default attribute values
|
24
58
|
ATTR_DEFAULTS = {
|
25
|
-
:remote_host =>
|
26
|
-
:remote_port =>
|
59
|
+
:remote_host => nil,
|
60
|
+
:remote_port => nil,
|
27
61
|
:keep_alive => 15,
|
28
62
|
:clean_session => true,
|
29
63
|
:client_id => nil,
|
@@ -33,10 +67,12 @@ class MQTT::Client
|
|
33
67
|
:will_topic => nil,
|
34
68
|
:will_payload => nil,
|
35
69
|
:will_qos => 0,
|
36
|
-
:will_retain => false
|
70
|
+
:will_retain => false,
|
71
|
+
:ssl => false
|
37
72
|
}
|
38
73
|
|
39
74
|
# Create and connect a new MQTT Client
|
75
|
+
#
|
40
76
|
# Accepts the same arguments as creating a new client.
|
41
77
|
# If a block is given, then it will be executed before disconnecting again.
|
42
78
|
#
|
@@ -71,28 +107,63 @@ class MQTT::Client
|
|
71
107
|
|
72
108
|
# Create a new MQTT Client instance
|
73
109
|
#
|
110
|
+
# Accepts one of the following:
|
111
|
+
# - a URI that uses the MQTT scheme
|
112
|
+
# - a hostname and port
|
113
|
+
# - a Hash containing attributes to be set on the new instance
|
114
|
+
#
|
115
|
+
# If no arguments are given then the method will look for a URI
|
116
|
+
# in the MQTT_BROKER environment variable.
|
117
|
+
#
|
74
118
|
# Examples:
|
119
|
+
# client = MQTT::Client.new
|
120
|
+
# client = MQTT::Client.new('mqtt://myserver.example.com')
|
121
|
+
# client = MQTT::Client.new('mqtt://user:pass@myserver.example.com')
|
75
122
|
# client = MQTT::Client.new('myserver.example.com')
|
76
123
|
# client = MQTT::Client.new('myserver.example.com', 18830)
|
77
124
|
# client = MQTT::Client.new(:remote_host => 'myserver.example.com')
|
78
125
|
# client = MQTT::Client.new(:remote_host => 'myserver.example.com', :keep_alive => 30)
|
79
126
|
#
|
80
127
|
def initialize(*args)
|
81
|
-
if args.
|
82
|
-
|
83
|
-
elsif args.count == 1 and args[0].is_a?(Hash)
|
84
|
-
args = args[0]
|
85
|
-
elsif args.count == 1
|
86
|
-
args = {:remote_host => args[0]}
|
87
|
-
elsif args.count == 2
|
88
|
-
args = {:remote_host => args[0], :remote_port => args[1]}
|
128
|
+
if args.last.is_a?(Hash)
|
129
|
+
attr = args.pop
|
89
130
|
else
|
131
|
+
attr = {}
|
132
|
+
end
|
133
|
+
|
134
|
+
if args.length == 0
|
135
|
+
if ENV['MQTT_BROKER']
|
136
|
+
attr.merge!(parse_uri(ENV['MQTT_BROKER']))
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
if args.length >= 1
|
141
|
+
case args[0]
|
142
|
+
when URI
|
143
|
+
attr.merge!(parse_uri(args[0]))
|
144
|
+
when %r|^mqtts?://|
|
145
|
+
attr.merge!(parse_uri(args[0]))
|
146
|
+
else
|
147
|
+
attr.merge!(:remote_host => args[0])
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
if args.length >= 2
|
152
|
+
attr.merge!(:remote_port => args[1])
|
153
|
+
end
|
154
|
+
|
155
|
+
if args.length >= 3
|
90
156
|
raise ArgumentError, "Unsupported number of arguments"
|
91
157
|
end
|
92
158
|
|
93
159
|
# Merge arguments with default values for attributes
|
94
|
-
ATTR_DEFAULTS.merge(
|
95
|
-
|
160
|
+
ATTR_DEFAULTS.merge(attr).each_pair do |k,v|
|
161
|
+
self.send("#{k}=", v)
|
162
|
+
end
|
163
|
+
|
164
|
+
# Set a default port number
|
165
|
+
if @remote_port.nil?
|
166
|
+
@remote_port = @ssl ? MQTT::DEFAULT_SSL_PORT : MQTT::DEFAULT_PORT
|
96
167
|
end
|
97
168
|
|
98
169
|
# Initialise private instance variables
|
@@ -105,6 +176,33 @@ class MQTT::Client
|
|
105
176
|
@write_semaphore = Mutex.new
|
106
177
|
end
|
107
178
|
|
179
|
+
# Get the OpenSSL context, that is used if SSL/TLS is enabled
|
180
|
+
def ssl_context
|
181
|
+
@ssl_context ||= OpenSSL::SSL::SSLContext.new
|
182
|
+
end
|
183
|
+
|
184
|
+
# Set a path to a file containing a PEM-format client certificate
|
185
|
+
def cert_file=(path)
|
186
|
+
ssl_context.cert = OpenSSL::X509::Certificate.new(File.open(path))
|
187
|
+
end
|
188
|
+
|
189
|
+
# Set a path to a file containing a PEM-format client private key
|
190
|
+
def key_file=(path)
|
191
|
+
ssl_context.key = OpenSSL::PKey::RSA.new(File.open(path))
|
192
|
+
end
|
193
|
+
|
194
|
+
# Set a path to a file containing a PEM-format CA certificate and enable peer verification
|
195
|
+
def ca_file=(path)
|
196
|
+
ssl_context.ca_file = path
|
197
|
+
unless path.nil?
|
198
|
+
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Set the Will for the client
|
203
|
+
#
|
204
|
+
# The will is a message that will be delivered by the broker when the client dies.
|
205
|
+
# The Will must be set before establishing a connection to the broker
|
108
206
|
def set_will(topic, payload, retain=false, qos=0)
|
109
207
|
self.will_topic = topic
|
110
208
|
self.will_payload = payload
|
@@ -115,16 +213,38 @@ class MQTT::Client
|
|
115
213
|
# Connect to the MQTT broker
|
116
214
|
# If a block is given, then yield to that block and then disconnect again.
|
117
215
|
def connect(clientid=nil)
|
118
|
-
|
216
|
+
unless clientid.nil?
|
119
217
|
@client_id = clientid
|
120
|
-
|
121
|
-
|
122
|
-
|
218
|
+
end
|
219
|
+
|
220
|
+
if @client_id.nil? or @client_id.empty?
|
221
|
+
if @clean_session
|
222
|
+
@client_id = MQTT::Client.generate_client_id
|
223
|
+
else
|
224
|
+
raise 'Must provide a client_id if clean_session is set to false'
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
if @remote_host.nil?
|
229
|
+
raise 'No MQTT broker host set when attempting to connect'
|
123
230
|
end
|
124
231
|
|
125
232
|
if not connected?
|
126
233
|
# Create network socket
|
127
|
-
|
234
|
+
tcp_socket = TCPSocket.new(@remote_host, @remote_port)
|
235
|
+
|
236
|
+
if @ssl
|
237
|
+
# Set the protocol version
|
238
|
+
if @ssl.is_a?(Symbol)
|
239
|
+
ssl_context.ssl_version = @ssl
|
240
|
+
end
|
241
|
+
|
242
|
+
@socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ssl_context)
|
243
|
+
@socket.sync_close = true
|
244
|
+
@socket.connect
|
245
|
+
else
|
246
|
+
@socket = tcp_socket
|
247
|
+
end
|
128
248
|
|
129
249
|
# Protocol name and version
|
130
250
|
packet = MQTT::Packet::Connect.new(
|
@@ -148,7 +268,9 @@ class MQTT::Client
|
|
148
268
|
# Start packet reading thread
|
149
269
|
@read_thread = Thread.new(Thread.current) do |parent|
|
150
270
|
Thread.current[:parent] = parent
|
151
|
-
|
271
|
+
while connected? do
|
272
|
+
receive_packet
|
273
|
+
end
|
152
274
|
end
|
153
275
|
end
|
154
276
|
|
@@ -162,6 +284,11 @@ class MQTT::Client
|
|
162
284
|
# Disconnect from the MQTT broker.
|
163
285
|
# If you don't want to say goodbye to the broker, set send_msg to false.
|
164
286
|
def disconnect(send_msg=true)
|
287
|
+
# Stop reading packets from the socket first
|
288
|
+
@read_thread.kill if @read_thread and @read_thread.alive?
|
289
|
+
@read_thread = nil
|
290
|
+
|
291
|
+
# Close the socket if it is open
|
165
292
|
if connected?
|
166
293
|
if send_msg
|
167
294
|
packet = MQTT::Packet::Disconnect.new
|
@@ -170,16 +297,17 @@ class MQTT::Client
|
|
170
297
|
@socket.close unless @socket.nil?
|
171
298
|
@socket = nil
|
172
299
|
end
|
173
|
-
@read_thread.kill if @read_thread and @read_thread.alive?
|
174
|
-
@read_thread = nil
|
175
300
|
end
|
176
301
|
|
177
302
|
# Checks whether the client is connected to the broker.
|
178
303
|
def connected?
|
179
|
-
not @socket.nil?
|
304
|
+
(not @socket.nil?) and (not @socket.closed?)
|
180
305
|
end
|
181
306
|
|
182
307
|
# Send a MQTT ping message to indicate that the MQTT client is alive.
|
308
|
+
#
|
309
|
+
# Note that you will not normally need to call this method
|
310
|
+
# as it is called automatically
|
183
311
|
def ping
|
184
312
|
packet = MQTT::Packet::Pingreq.new
|
185
313
|
send_packet(packet)
|
@@ -288,6 +416,10 @@ class MQTT::Client
|
|
288
416
|
|
289
417
|
# Send a unsubscribe message for one or more topics on the MQTT broker
|
290
418
|
def unsubscribe(*topics)
|
419
|
+
if topics.is_a?(Enumerable) and topics.count == 1
|
420
|
+
topics = topics.first
|
421
|
+
end
|
422
|
+
|
291
423
|
packet = MQTT::Packet::Unsubscribe.new(
|
292
424
|
:topics => topics,
|
293
425
|
:message_id => @message_id.next
|
@@ -302,7 +434,7 @@ private
|
|
302
434
|
def receive_packet
|
303
435
|
begin
|
304
436
|
# Poll socket - is there data waiting?
|
305
|
-
result = IO.select([@socket],
|
437
|
+
result = IO.select([@socket], [], [], SELECT_TIMEOUT)
|
306
438
|
unless result.nil?
|
307
439
|
# Yes - read in the packet
|
308
440
|
packet = MQTT::Packet.read(@socket)
|
@@ -355,8 +487,28 @@ private
|
|
355
487
|
|
356
488
|
# Only allow one thread to write to socket at a time
|
357
489
|
@write_semaphore.synchronize do
|
358
|
-
@socket.write(data)
|
490
|
+
@socket.write(data.to_s)
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
private
|
495
|
+
def parse_uri(uri)
|
496
|
+
uri = URI.parse(uri) unless uri.is_a?(URI)
|
497
|
+
if uri.scheme == 'mqtt'
|
498
|
+
ssl = false
|
499
|
+
elsif uri.scheme == 'mqtts'
|
500
|
+
ssl = true
|
501
|
+
else
|
502
|
+
raise "Only the mqtt:// and mqtts:// schemes are supported"
|
359
503
|
end
|
504
|
+
|
505
|
+
{
|
506
|
+
:remote_host => uri.host,
|
507
|
+
:remote_port => uri.port || nil,
|
508
|
+
:username => uri.user,
|
509
|
+
:password => uri.password,
|
510
|
+
:ssl => ssl
|
511
|
+
}
|
360
512
|
end
|
361
513
|
|
362
514
|
end
|
data/lib/mqtt/packet.rb
CHANGED
@@ -5,12 +5,20 @@ module MQTT
|
|
5
5
|
# Class representing a MQTT Packet
|
6
6
|
# Performs binary encoding and decoding of headers
|
7
7
|
class MQTT::Packet
|
8
|
-
|
9
|
-
attr_reader :
|
10
|
-
attr_reader :qos # Quality of Service level
|
11
|
-
attr_reader :body_length # The length of the parsed packet body
|
8
|
+
# Duplicate delivery flag
|
9
|
+
attr_reader :duplicate
|
12
10
|
|
13
|
-
|
11
|
+
# Retain flag
|
12
|
+
attr_reader :retain
|
13
|
+
|
14
|
+
# Quality of Service level (0, 1, 2)
|
15
|
+
attr_reader :qos
|
16
|
+
|
17
|
+
# The length of the parsed packet body
|
18
|
+
attr_reader :body_length
|
19
|
+
|
20
|
+
# Default attribute values
|
21
|
+
ATTR_DEFAULTS = {
|
14
22
|
:duplicate => false,
|
15
23
|
:qos => 0,
|
16
24
|
:retain => false,
|
@@ -105,9 +113,10 @@ module MQTT
|
|
105
113
|
|
106
114
|
# Create a new empty packet
|
107
115
|
def initialize(args={})
|
108
|
-
update_attributes(
|
116
|
+
update_attributes(ATTR_DEFAULTS.merge(args))
|
109
117
|
end
|
110
118
|
|
119
|
+
# Set packet attributes from a hash of attribute names and values
|
111
120
|
def update_attributes(attr={})
|
112
121
|
attr.each_pair do |k,v|
|
113
122
|
send("#{k}=", v)
|
@@ -201,6 +210,7 @@ module MQTT
|
|
201
210
|
header.pack('C*') + body
|
202
211
|
end
|
203
212
|
|
213
|
+
# Returns a human readable string
|
204
214
|
def inspect
|
205
215
|
"\#<#{self.class}>"
|
206
216
|
end
|
@@ -270,11 +280,18 @@ module MQTT
|
|
270
280
|
|
271
281
|
# Class representing an MQTT Publish message
|
272
282
|
class Publish < MQTT::Packet
|
283
|
+
# The topic name to publish to
|
273
284
|
attr_accessor :topic
|
285
|
+
|
286
|
+
# Identifier for an individual publishing flow
|
287
|
+
# Only required in PUBLISH Packets where the QoS level is 1 or 2
|
274
288
|
attr_accessor :message_id
|
289
|
+
|
290
|
+
# The data to be published
|
275
291
|
attr_accessor :payload
|
276
292
|
|
277
|
-
|
293
|
+
# Default attribute values
|
294
|
+
ATTR_DEFAULTS = {
|
278
295
|
:topic => nil,
|
279
296
|
:message_id => 0,
|
280
297
|
:payload => ''
|
@@ -282,7 +299,7 @@ module MQTT
|
|
282
299
|
|
283
300
|
# Create a new Publish packet
|
284
301
|
def initialize(args={})
|
285
|
-
super(
|
302
|
+
super(ATTR_DEFAULTS.merge(args))
|
286
303
|
end
|
287
304
|
|
288
305
|
# Get serialisation of packet's body
|
@@ -305,6 +322,7 @@ module MQTT
|
|
305
322
|
@payload = buffer
|
306
323
|
end
|
307
324
|
|
325
|
+
# Returns a human readable string, summarising the properties of the packet
|
308
326
|
def inspect
|
309
327
|
"\#<#{self.class}: " +
|
310
328
|
"d#{duplicate ? '1' : '0'}, " +
|
@@ -328,23 +346,41 @@ module MQTT
|
|
328
346
|
|
329
347
|
# Class representing an MQTT Connect Packet
|
330
348
|
class Connect < MQTT::Packet
|
349
|
+
# The name of the protocol (defaults to MQIsdp)
|
331
350
|
attr_accessor :protocol_name
|
351
|
+
|
352
|
+
# The version number of the protocol (defaults to 3)
|
332
353
|
attr_accessor :protocol_version
|
354
|
+
|
355
|
+
# The client identifier string
|
333
356
|
attr_accessor :client_id
|
357
|
+
|
358
|
+
# Set to false to keep a persistent session with the broker
|
334
359
|
attr_accessor :clean_session
|
360
|
+
|
361
|
+
# Period the broker should keep connection open for between pings
|
335
362
|
attr_accessor :keep_alive
|
363
|
+
|
364
|
+
# The topic name to send the Will message to
|
336
365
|
attr_accessor :will_topic
|
366
|
+
|
367
|
+
# The QoS level to send the Will message as
|
337
368
|
attr_accessor :will_qos
|
369
|
+
|
370
|
+
# Set to true to make the Will message retained
|
338
371
|
attr_accessor :will_retain
|
372
|
+
|
373
|
+
# The payload of the Will message
|
339
374
|
attr_accessor :will_payload
|
375
|
+
|
376
|
+
# The username for authenticating with the broker
|
340
377
|
attr_accessor :username
|
378
|
+
|
379
|
+
# The password for authenticating with the broker
|
341
380
|
attr_accessor :password
|
342
381
|
|
343
|
-
#
|
344
|
-
|
345
|
-
alias :clean_start= :clean_session=
|
346
|
-
|
347
|
-
DEFAULTS = {
|
382
|
+
# Default attribute values
|
383
|
+
ATTR_DEFAULTS = {
|
348
384
|
:protocol_name => 'MQIsdp',
|
349
385
|
:protocol_version => 0x03,
|
350
386
|
:client_id => nil,
|
@@ -360,7 +396,7 @@ module MQTT
|
|
360
396
|
|
361
397
|
# Create a new Client Connect packet
|
362
398
|
def initialize(args={})
|
363
|
-
super(
|
399
|
+
super(ATTR_DEFAULTS.merge(args))
|
364
400
|
end
|
365
401
|
|
366
402
|
# Get serialisation of packet's body
|
@@ -436,6 +472,7 @@ module MQTT
|
|
436
472
|
end
|
437
473
|
end
|
438
474
|
|
475
|
+
# Returns a human readable string, summarising the properties of the packet
|
439
476
|
def inspect
|
440
477
|
str = "\#<#{self.class}: "
|
441
478
|
str += "keep_alive=#{keep_alive}"
|
@@ -449,12 +486,15 @@ module MQTT
|
|
449
486
|
|
450
487
|
# Class representing an MQTT Connect Acknowledgment Packet
|
451
488
|
class Connack < MQTT::Packet
|
489
|
+
# The return code (defaults to 0 for connection accepted)
|
452
490
|
attr_accessor :return_code
|
453
|
-
|
491
|
+
|
492
|
+
# Default attribute values
|
493
|
+
ATTR_DEFAULTS = {:return_code => 0x00}
|
454
494
|
|
455
495
|
# Create a new Client Connect packet
|
456
496
|
def initialize(args={})
|
457
|
-
super(
|
497
|
+
super(ATTR_DEFAULTS.merge(args))
|
458
498
|
end
|
459
499
|
|
460
500
|
# Get a string message corresponding to a return code
|
@@ -495,6 +535,7 @@ module MQTT
|
|
495
535
|
end
|
496
536
|
end
|
497
537
|
|
538
|
+
# Returns a human readable string, summarising the properties of the packet
|
498
539
|
def inspect
|
499
540
|
"\#<#{self.class}: 0x%2.2X>" % return_code
|
500
541
|
end
|
@@ -502,12 +543,15 @@ module MQTT
|
|
502
543
|
|
503
544
|
# Class representing an MQTT Publish Acknowledgment packet
|
504
545
|
class Puback < MQTT::Packet
|
546
|
+
# Identifier for an individual publishing flow
|
505
547
|
attr_accessor :message_id
|
506
|
-
|
548
|
+
|
549
|
+
# Default attribute values
|
550
|
+
ATTR_DEFAULTS = {:message_id => 0}
|
507
551
|
|
508
552
|
# Create a new Publish Acknowledgment packet
|
509
553
|
def initialize(args={})
|
510
|
-
super(
|
554
|
+
super(ATTR_DEFAULTS.merge(args))
|
511
555
|
end
|
512
556
|
|
513
557
|
# Get serialisation of packet's body
|
@@ -524,6 +568,7 @@ module MQTT
|
|
524
568
|
end
|
525
569
|
end
|
526
570
|
|
571
|
+
# Returns a human readable string, summarising the properties of the packet
|
527
572
|
def inspect
|
528
573
|
"\#<#{self.class}: 0x%2.2X>" % message_id
|
529
574
|
end
|
@@ -531,12 +576,15 @@ module MQTT
|
|
531
576
|
|
532
577
|
# Class representing an MQTT Publish Received packet
|
533
578
|
class Pubrec < MQTT::Packet
|
579
|
+
# Identifier for an individual publishing flow
|
534
580
|
attr_accessor :message_id
|
535
|
-
|
581
|
+
|
582
|
+
# Default attribute values
|
583
|
+
ATTR_DEFAULTS = {:message_id => 0}
|
536
584
|
|
537
585
|
# Create a new Publish Recieved packet
|
538
586
|
def initialize(args={})
|
539
|
-
super(
|
587
|
+
super(ATTR_DEFAULTS.merge(args))
|
540
588
|
end
|
541
589
|
|
542
590
|
# Get serialisation of packet's body
|
@@ -553,6 +601,7 @@ module MQTT
|
|
553
601
|
end
|
554
602
|
end
|
555
603
|
|
604
|
+
# Returns a human readable string, summarising the properties of the packet
|
556
605
|
def inspect
|
557
606
|
"\#<#{self.class}: 0x%2.2X>" % message_id
|
558
607
|
end
|
@@ -560,12 +609,15 @@ module MQTT
|
|
560
609
|
|
561
610
|
# Class representing an MQTT Publish Release packet
|
562
611
|
class Pubrel < MQTT::Packet
|
612
|
+
# Identifier for an individual publishing flow
|
563
613
|
attr_accessor :message_id
|
564
|
-
|
614
|
+
|
615
|
+
# Default attribute values
|
616
|
+
ATTR_DEFAULTS = {:message_id => 0}
|
565
617
|
|
566
618
|
# Create a new Publish Release packet
|
567
619
|
def initialize(args={})
|
568
|
-
super(
|
620
|
+
super(ATTR_DEFAULTS.merge(args))
|
569
621
|
end
|
570
622
|
|
571
623
|
# Get serialisation of packet's body
|
@@ -582,6 +634,7 @@ module MQTT
|
|
582
634
|
end
|
583
635
|
end
|
584
636
|
|
637
|
+
# Returns a human readable string, summarising the properties of the packet
|
585
638
|
def inspect
|
586
639
|
"\#<#{self.class}: 0x%2.2X>" % message_id
|
587
640
|
end
|
@@ -589,12 +642,15 @@ module MQTT
|
|
589
642
|
|
590
643
|
# Class representing an MQTT Publish Complete packet
|
591
644
|
class Pubcomp < MQTT::Packet
|
645
|
+
# Identifier for an individual publishing flow
|
592
646
|
attr_accessor :message_id
|
593
|
-
|
647
|
+
|
648
|
+
# Default attribute values
|
649
|
+
ATTR_DEFAULTS = {:message_id => 0}
|
594
650
|
|
595
651
|
# Create a new Publish Complete packet
|
596
652
|
def initialize(args={})
|
597
|
-
super(
|
653
|
+
super(ATTR_DEFAULTS.merge(args))
|
598
654
|
end
|
599
655
|
|
600
656
|
# Get serialisation of packet's body
|
@@ -611,6 +667,7 @@ module MQTT
|
|
611
667
|
end
|
612
668
|
end
|
613
669
|
|
670
|
+
# Returns a human readable string, summarising the properties of the packet
|
614
671
|
def inspect
|
615
672
|
"\#<#{self.class}: 0x%2.2X>" % message_id
|
616
673
|
end
|
@@ -618,13 +675,18 @@ module MQTT
|
|
618
675
|
|
619
676
|
# Class representing an MQTT Client Subscribe packet
|
620
677
|
class Subscribe < MQTT::Packet
|
678
|
+
# Identifier for an individual publishing flow
|
621
679
|
attr_accessor :message_id
|
680
|
+
|
681
|
+
# One or more topic names to subscribe to
|
622
682
|
attr_reader :topics
|
623
|
-
|
683
|
+
|
684
|
+
# Default attribute values
|
685
|
+
ATTR_DEFAULTS = {:message_id => 0}
|
624
686
|
|
625
687
|
# Create a new Subscribe packet
|
626
688
|
def initialize(args={})
|
627
|
-
super(
|
689
|
+
super(ATTR_DEFAULTS.merge(args))
|
628
690
|
@topics ||= []
|
629
691
|
@qos = 1 # Force a QOS of 1
|
630
692
|
end
|
@@ -696,8 +758,9 @@ module MQTT
|
|
696
758
|
end
|
697
759
|
end
|
698
760
|
|
761
|
+
# Returns a human readable string, summarising the properties of the packet
|
699
762
|
def inspect
|
700
|
-
|
763
|
+
_str = "\#<#{self.class}: 0x%2.2X, %s>" % [
|
701
764
|
message_id,
|
702
765
|
topics.map {|t| "'#{t[0]}':#{t[1]}"}.join(', ')
|
703
766
|
]
|
@@ -706,13 +769,18 @@ module MQTT
|
|
706
769
|
|
707
770
|
# Class representing an MQTT Subscribe Acknowledgment packet
|
708
771
|
class Suback < MQTT::Packet
|
772
|
+
# Identifier to tie the Subscribe request to the Suback response
|
709
773
|
attr_accessor :message_id
|
774
|
+
|
775
|
+
# The QoS level that was granted for the subscribe request
|
710
776
|
attr_reader :granted_qos
|
711
|
-
|
777
|
+
|
778
|
+
# Default attribute values
|
779
|
+
ATTR_DEFAULTS = {:message_id => 0}
|
712
780
|
|
713
781
|
# Create a new Subscribe Acknowledgment packet
|
714
782
|
def initialize(args={})
|
715
|
-
super(
|
783
|
+
super(ATTR_DEFAULTS.merge(args))
|
716
784
|
@granted_qos ||= []
|
717
785
|
end
|
718
786
|
|
@@ -747,6 +815,7 @@ module MQTT
|
|
747
815
|
end
|
748
816
|
end
|
749
817
|
|
818
|
+
# Returns a human readable string, summarising the properties of the packet
|
750
819
|
def inspect
|
751
820
|
"\#<#{self.class}: 0x%2.2X, qos=%s>" % [message_id, granted_qos.join(',')]
|
752
821
|
end
|
@@ -754,17 +823,23 @@ module MQTT
|
|
754
823
|
|
755
824
|
# Class representing an MQTT Client Unsubscribe packet
|
756
825
|
class Unsubscribe < MQTT::Packet
|
826
|
+
# One or more topics to unsubscribe from
|
757
827
|
attr_reader :topics
|
828
|
+
|
829
|
+
# Identifier to tie the Unsubscribe request to the Unsuback response
|
758
830
|
attr_accessor :message_id
|
759
|
-
|
831
|
+
|
832
|
+
# Default attribute values
|
833
|
+
ATTR_DEFAULTS = {:message_id => 0}
|
760
834
|
|
761
835
|
# Create a new Unsubscribe packet
|
762
836
|
def initialize(args={})
|
763
|
-
super(
|
837
|
+
super(ATTR_DEFAULTS.merge(args))
|
764
838
|
@topics ||= []
|
765
839
|
@qos = 1 # Force a QOS of 1
|
766
840
|
end
|
767
841
|
|
842
|
+
# Set one or more topics to unsubscribe from
|
768
843
|
def topics=(value)
|
769
844
|
if value.is_a?(Array)
|
770
845
|
@topics = value
|
@@ -792,8 +867,9 @@ module MQTT
|
|
792
867
|
end
|
793
868
|
end
|
794
869
|
|
870
|
+
# Returns a human readable string, summarising the properties of the packet
|
795
871
|
def inspect
|
796
|
-
|
872
|
+
"\#<#{self.class}: 0x%2.2X, %s>" % [
|
797
873
|
message_id,
|
798
874
|
topics.map {|t| "'#{t}'"}.join(', ')
|
799
875
|
]
|
@@ -802,12 +878,15 @@ module MQTT
|
|
802
878
|
|
803
879
|
# Class representing an MQTT Unsubscribe Acknowledgment packet
|
804
880
|
class Unsuback < MQTT::Packet
|
881
|
+
# Identifier to tie the Unsubscribe request to the Unsuback response
|
805
882
|
attr_accessor :message_id
|
806
|
-
|
883
|
+
|
884
|
+
# Default attribute values
|
885
|
+
ATTR_DEFAULTS = {:message_id => 0}
|
807
886
|
|
808
887
|
# Create a new Unsubscribe Acknowledgment packet
|
809
888
|
def initialize(args={})
|
810
|
-
super(
|
889
|
+
super(ATTR_DEFAULTS.merge(args))
|
811
890
|
end
|
812
891
|
|
813
892
|
# Get serialisation of packet's body
|
@@ -824,6 +903,7 @@ module MQTT
|
|
824
903
|
end
|
825
904
|
end
|
826
905
|
|
906
|
+
# Returns a human readable string, summarising the properties of the packet
|
827
907
|
def inspect
|
828
908
|
"\#<#{self.class}: 0x%2.2X>" % message_id
|
829
909
|
end
|