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.
File without changes
@@ -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
 
@@ -1,8 +1,7 @@
1
1
  ruby-mqtt
2
2
  =========
3
3
 
4
- Pure Ruby gem that implements the MQTT (Message Queue Telemetry Transport) protocol,
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
 
@@ -14,15 +14,24 @@ end
14
14
 
15
15
  module MQTT
16
16
 
17
- DEFAULT_HOST = 'localhost'
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
 
@@ -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
- attr_reader :remote_host # Hostname of the remote broker
4
- attr_reader :remote_port # Port number of the remote broker
5
- attr_accessor :keep_alive # Time (in seconds) between pings to remote broker
6
- attr_accessor :clean_session # Set the 'Clean Session' flag when connecting?
7
- attr_accessor :client_id # Client Identifier
8
- attr_accessor :ack_timeout # Number of seconds to wait for acknowledgement packets
9
- attr_accessor :username # Username to authenticate to the broker with
10
- attr_accessor :password # Password to authenticate to the broker with
11
- attr_accessor :will_topic # The topic that the Will message is published to
12
- attr_accessor :will_payload # Contents of message that is sent by broker when client disconnect
13
- attr_accessor :will_qos # The QoS level of the will message sent by the broker
14
- attr_accessor :will_retain # If the Will message should be retain by the broker after it is sent
15
-
16
- # OLD deprecated clean_start
17
- alias :clean_start :clean_session
18
- alias :clean_start= :clean_session=
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 => MQTT::DEFAULT_HOST,
26
- :remote_port => MQTT::DEFAULT_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.count == 0
82
- args = {}
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(args).each_pair do |k,v|
95
- instance_variable_set("@#{k}", v)
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
- if !clientid.nil?
216
+ unless clientid.nil?
119
217
  @client_id = clientid
120
- elsif @client_id.nil?
121
- @client_id = MQTT::Client.generate_client_id
122
- @clean_session = true
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
- @socket = TCPSocket.new(@remote_host,@remote_port)
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
- loop { receive_packet }
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], nil, nil, SELECT_TIMEOUT)
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
@@ -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
- attr_reader :duplicate # Duplicate delivery flag
9
- attr_reader :retain # Retain flag
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
- DEFAULTS = {
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(DEFAULTS.merge(args))
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
- DEFAULTS = {
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(DEFAULTS.merge(args))
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
- # OLD deprecated clean_start
344
- alias :clean_start :clean_session
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(DEFAULTS.merge(args))
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
- DEFAULTS = {:return_code => 0x00}
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(DEFAULTS.merge(args))
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
- DEFAULTS = {:message_id => 0}
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(DEFAULTS.merge(args))
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
- DEFAULTS = {:message_id => 0}
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(DEFAULTS.merge(args))
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
- DEFAULTS = {:message_id => 0}
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(DEFAULTS.merge(args))
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
- DEFAULTS = {:message_id => 0}
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(DEFAULTS.merge(args))
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
- DEFAULTS = {:message_id => 0}
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(DEFAULTS.merge(args))
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
- str = "\#<#{self.class}: 0x%2.2X, %s>" % [
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
- DEFAULTS = {:message_id => 0}
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(DEFAULTS.merge(args))
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
- DEFAULTS = {:message_id => 0}
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(DEFAULTS.merge(args))
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
- str = "\#<#{self.class}: 0x%2.2X, %s>" % [
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
- DEFAULTS = {:message_id => 0}
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(DEFAULTS.merge(args))
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