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