mqtt 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS.md +22 -2
- data/README.md +126 -7
- data/lib/mqtt.rb +5 -5
- data/lib/mqtt/client.rb +92 -55
- data/lib/mqtt/packet.rb +305 -185
- data/lib/mqtt/proxy.rb +28 -28
- data/lib/mqtt/version.rb +2 -1
- data/spec/mqtt_client_spec.rb +252 -175
- data/spec/mqtt_packet_spec.rb +823 -401
- data/spec/mqtt_version_spec.rb +3 -3
- data/spec/zz_client_integration_spec.rb +16 -16
- metadata +102 -85
data/NEWS.md
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
Ruby MQTT NEWS
|
2
2
|
==============
|
3
3
|
|
4
|
+
Ruby MQTT Version 0.3.0 (2014-08-26)
|
5
|
+
------------------------------------
|
6
|
+
|
7
|
+
* Added support for MQTT protocol version 3.1.1
|
8
|
+
* Renamed a number of methods/attributes:
|
9
|
+
- Renamed ```:granted_qos``` to ```:return_codes```
|
10
|
+
- Renamed ```:remote_port``` to ```:port```
|
11
|
+
- Renamed ```:remote_host``` to ```:host```
|
12
|
+
- Renamed ```:message_id``` to ```:id```
|
13
|
+
- Renamed ```:protocol_version``` to ```:protocol_level```
|
14
|
+
- Renamed ```MQTT_SERVER``` environment variable to ```MQTT_SERVER```
|
15
|
+
* Added more checks to ensure that the 3.1.1 protocol specs are adhered to
|
16
|
+
* Added a Library Overview section to the README
|
17
|
+
* Added links to the protocol specification to README
|
18
|
+
* Improvements to the YARD API documentation
|
19
|
+
* Don't display payload in inspect if it contains non-visible ASCII characters
|
20
|
+
* Upgraded to rspec 3
|
21
|
+
* Various minor bug fixes and corrections
|
22
|
+
|
23
|
+
|
4
24
|
Ruby MQTT Version 0.2.0 (2014-04-02)
|
5
25
|
------------------------------------
|
6
26
|
|
7
27
|
* Added SSL/TLS support
|
8
28
|
* Added support for passing connection details using a URI
|
9
|
-
* Added support for using the MQTT_BROKER environment variable
|
29
|
+
* Added support for using the ```MQTT_BROKER``` environment variable
|
10
30
|
* Allow passing array of topics to Client#unsubscribe
|
11
31
|
* Allow more combinations of arguments to be passed to a new Client
|
12
|
-
* No longer defaults to ‘localhost’ if there is no
|
32
|
+
* No longer defaults to ‘localhost’ if there is no server configured
|
13
33
|
* Fixed more 'unused variable' warnings
|
14
34
|
* Documentation improvements
|
15
35
|
* Ruby 1.8 fixes
|
data/README.md
CHANGED
@@ -1,19 +1,35 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/njh/ruby-mqtt.svg)](https://travis-ci.org/njh/ruby-mqtt)
|
2
|
+
|
1
3
|
ruby-mqtt
|
2
4
|
=========
|
3
5
|
|
4
|
-
Pure Ruby gem that implements the MQTT protocol, a lightweight protocol for publish/subscribe messaging.
|
6
|
+
Pure Ruby gem that implements the [MQTT] protocol, a lightweight protocol for publish/subscribe messaging.
|
7
|
+
|
8
|
+
|
9
|
+
Table of Contents
|
10
|
+
-----------------
|
11
|
+
* [Installation](#installation)
|
12
|
+
* [Quick Start](#quick-start)
|
13
|
+
* [Library Overview](#library-overview)
|
14
|
+
* [Resources](#resources)
|
15
|
+
* [License](#license)
|
16
|
+
* [Contact](#contact)
|
5
17
|
|
6
18
|
|
7
|
-
|
8
|
-
|
19
|
+
Installation
|
20
|
+
------------
|
9
21
|
|
10
|
-
You may get the latest stable version from Rubygems:
|
22
|
+
You may get the latest stable version from [Rubygems]:
|
11
23
|
|
12
24
|
$ gem install mqtt
|
13
25
|
|
26
|
+
Alternatively, to use a development snapshot from GitHub using [Bundler]:
|
14
27
|
|
15
|
-
|
16
|
-
|
28
|
+
gem 'mqtt', :git => 'https://github.com/njh/ruby-mqtt.git'
|
29
|
+
|
30
|
+
|
31
|
+
Quick Start
|
32
|
+
-----------
|
17
33
|
|
18
34
|
require 'rubygems'
|
19
35
|
require 'mqtt'
|
@@ -32,18 +48,106 @@ Synopsis
|
|
32
48
|
end
|
33
49
|
|
34
50
|
|
51
|
+
|
52
|
+
Library Overview
|
53
|
+
----------------
|
54
|
+
|
55
|
+
### Connecting ###
|
56
|
+
|
57
|
+
A new client connection can be created by passing either a [MQTT URI], a host and port or by passing a hash of attributes.
|
58
|
+
|
59
|
+
client = MQTT::Client.connect('mqtt://myserver.example.com')
|
60
|
+
client = MQTT::Client.connect('mqtts://user:pass@myserver.example.com')
|
61
|
+
client = MQTT::Client.connect('myserver.example.com')
|
62
|
+
client = MQTT::Client.connect('myserver.example.com', 18830)
|
63
|
+
client = MQTT::Client.connect(:host => 'myserver.example.com', :port => 1883 ... )
|
64
|
+
|
65
|
+
TLS/SSL is not enabled by default, to enabled it, pass ```:ssl => true```:
|
66
|
+
|
67
|
+
client = MQTT::Client.connect(
|
68
|
+
:host => 'test.mosquitto.org',
|
69
|
+
:port => 8883
|
70
|
+
:ssl => true
|
71
|
+
)
|
72
|
+
|
73
|
+
Alternatively you can create a new Client object and then configure it by setting attributes. This example shows setting up client certificate based authentication:
|
74
|
+
|
75
|
+
client = MQTT::Client.new
|
76
|
+
client.host = 'myserver.example.com'
|
77
|
+
client.ssl = true
|
78
|
+
client.cert_file = path_to('client.pem')
|
79
|
+
client.key_file = path_to('client.key')
|
80
|
+
client.ca_file = path_to('root-ca.pem')
|
81
|
+
client.connect()
|
82
|
+
|
83
|
+
The connection can either be made without the use of a block:
|
84
|
+
|
85
|
+
client = MQTT::Client.connect('test.mosquitto.org')
|
86
|
+
# perform operations
|
87
|
+
client.disconnect()
|
88
|
+
|
89
|
+
Or, if using a block, with an implicit disconnection at the end of the block.
|
90
|
+
|
91
|
+
MQTT::Client.connect('test.mosquitto.org') do |client|
|
92
|
+
# perform operations
|
93
|
+
end
|
94
|
+
|
95
|
+
For more information, see and list of attributes for the [MQTT::Client] class and the [MQTT::Client.connect] method.
|
96
|
+
|
97
|
+
|
98
|
+
### Publishing ###
|
99
|
+
|
100
|
+
To send a message to a topic, use the ```publish``` method:
|
101
|
+
|
102
|
+
client.publish(topic, payload, retain=false)
|
103
|
+
|
104
|
+
The method will return once the message has been sent to the MQTT server.
|
105
|
+
|
106
|
+
For more information see the [MQTT::Client#publish] method.
|
107
|
+
|
108
|
+
|
109
|
+
### Subscribing ###
|
110
|
+
|
111
|
+
You can send a subscription request to the MQTT server using the subscribe method. One or more [Topic Filters] may be passed in:
|
112
|
+
|
113
|
+
client.subscribe( 'topic1' )
|
114
|
+
client.subscribe( 'topic1', 'topic2' )
|
115
|
+
client.subscribe( 'foo/#' )
|
116
|
+
|
117
|
+
For more information see the [MQTT::Client#subscribe] method.
|
118
|
+
|
119
|
+
|
120
|
+
### Receiving Messages ###
|
121
|
+
|
122
|
+
To receive a message, use the get method. This method will block until a message is available. The topic is the name of the topic the message was sent to. The message is a string:
|
123
|
+
|
124
|
+
topic,message = client.get
|
125
|
+
|
126
|
+
Alternatively, you can give the get method a block, which will be called for every message received and loop forever:
|
127
|
+
|
128
|
+
client.get do |topic,message|
|
129
|
+
# Block is executed for every message received
|
130
|
+
end
|
131
|
+
|
132
|
+
For more information see the [MQTT::Client#get] method.
|
133
|
+
|
134
|
+
|
135
|
+
|
35
136
|
Limitations
|
36
137
|
-----------
|
37
138
|
|
38
139
|
* Only QOS 0 currently supported
|
140
|
+
* Automatic re-connects to the server are not supported
|
39
141
|
|
40
142
|
|
41
143
|
Resources
|
42
144
|
---------
|
43
145
|
|
146
|
+
* API Documentation: http://rubydoc.info/gems/mqtt
|
147
|
+
* Protocol Specification v3.1.1: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html
|
148
|
+
* Protocol Specification v3.1: http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html
|
44
149
|
* MQTT Homepage: http://www.mqtt.org/
|
45
150
|
* GitHub Project: http://github.com/njh/ruby-mqtt
|
46
|
-
* API Documentation: http://rubydoc.info/gems/mqtt/frames
|
47
151
|
|
48
152
|
|
49
153
|
License
|
@@ -59,3 +163,18 @@ Contact
|
|
59
163
|
* Author: Nicholas J Humfrey
|
60
164
|
* Email: njh@aelius.com
|
61
165
|
* Home Page: http://www.aelius.com/njh/
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
[MQTT]: http://www.mqtt.org/
|
170
|
+
[Rubygems]: http://rubygems.org/
|
171
|
+
[Bundler]: http://bundler.io/
|
172
|
+
[MQTT URI]: https://github.com/mqtt/mqtt.github.io/wiki/URI-Scheme
|
173
|
+
[Topic Filters]: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html#_Toc388534397
|
174
|
+
|
175
|
+
[MQTT::Client]: http://rubydoc.info/gems/mqtt/MQTT/Client#instance_attr_details
|
176
|
+
[MQTT::Client.connect]: http://rubydoc.info/gems/mqtt/MQTT/Client.connect
|
177
|
+
[MQTT::Client#publish]: http://rubydoc.info/gems/mqtt/MQTT/Client:publish
|
178
|
+
[MQTT::Client#subscribe]: http://rubydoc.info/gems/mqtt/MQTT/Client:subscribe
|
179
|
+
[MQTT::Client#get]: http://rubydoc.info/gems/mqtt/MQTT/Client:get
|
180
|
+
|
data/lib/mqtt.rb
CHANGED
@@ -14,22 +14,22 @@ end
|
|
14
14
|
|
15
15
|
module MQTT
|
16
16
|
|
17
|
-
# Default port number for unencrypted connections
|
17
|
+
# Default port number for unencrypted connections
|
18
18
|
DEFAULT_PORT = 1883
|
19
|
-
|
20
|
-
# Default port number for TLS/SSL encrypted connections
|
19
|
+
|
20
|
+
# Default port number for TLS/SSL encrypted connections
|
21
21
|
DEFAULT_SSL_PORT = 8883
|
22
22
|
|
23
23
|
# Super-class for other MQTT related exceptions
|
24
24
|
class Exception < Exception
|
25
25
|
end
|
26
26
|
|
27
|
-
# A ProtocolException will be raised if there is a
|
27
|
+
# A ProtocolException will be raised if there is a
|
28
28
|
# problem with data received from a remote host
|
29
29
|
class ProtocolException < MQTT::Exception
|
30
30
|
end
|
31
31
|
|
32
|
-
# A NotConnectedException will be raised when trying to
|
32
|
+
# A NotConnectedException will be raised when trying to
|
33
33
|
# perform a function but no connection has been
|
34
34
|
# established
|
35
35
|
class NotConnectedException < MQTT::Exception
|
data/lib/mqtt/client.rb
CHANGED
@@ -2,52 +2,55 @@ autoload :OpenSSL, 'openssl'
|
|
2
2
|
autoload :URI, 'uri'
|
3
3
|
|
4
4
|
|
5
|
-
# Client class for talking to an MQTT
|
5
|
+
# Client class for talking to an MQTT server
|
6
6
|
class MQTT::Client
|
7
|
-
# Hostname of the remote
|
8
|
-
attr_accessor :
|
7
|
+
# Hostname of the remote server
|
8
|
+
attr_accessor :host
|
9
9
|
|
10
|
-
# Port number of the remote
|
11
|
-
attr_accessor :
|
10
|
+
# Port number of the remote server
|
11
|
+
attr_accessor :port
|
12
|
+
|
13
|
+
# The version number of the MQTT protocol to use (default 3.1.0)
|
14
|
+
attr_accessor :version
|
12
15
|
|
13
16
|
# Set to true to enable SSL/TLS encrypted communication
|
14
17
|
#
|
15
18
|
# Set to a symbol to use a specific variant of SSL/TLS.
|
16
|
-
# Allowed values include:
|
17
|
-
#
|
19
|
+
# Allowed values include:
|
20
|
+
#
|
18
21
|
# @example Using TLS 1.0
|
19
22
|
# client = Client.new('mqtt.example.com', :ssl => :TLSv1)
|
20
23
|
# @see OpenSSL::SSL::SSLContext::METHODS
|
21
24
|
attr_accessor :ssl
|
22
25
|
|
23
|
-
# Time (in seconds) between pings to remote
|
26
|
+
# Time (in seconds) between pings to remote server (default is 15 seconds)
|
24
27
|
attr_accessor :keep_alive
|
25
28
|
|
26
|
-
# Set the 'Clean Session' flag when connecting?
|
29
|
+
# Set the 'Clean Session' flag when connecting? (default is true)
|
27
30
|
attr_accessor :clean_session
|
28
31
|
|
29
32
|
# Client Identifier
|
30
33
|
attr_accessor :client_id
|
31
34
|
|
32
|
-
# Number of seconds to wait for acknowledgement packets
|
35
|
+
# Number of seconds to wait for acknowledgement packets (default is 5 seconds)
|
33
36
|
attr_accessor :ack_timeout
|
34
37
|
|
35
|
-
# Username to authenticate to the
|
38
|
+
# Username to authenticate to the server with
|
36
39
|
attr_accessor :username
|
37
40
|
|
38
|
-
# Password to authenticate to the
|
41
|
+
# Password to authenticate to the server with
|
39
42
|
attr_accessor :password
|
40
43
|
|
41
44
|
# The topic that the Will message is published to
|
42
45
|
attr_accessor :will_topic
|
43
46
|
|
44
|
-
# Contents of message that is sent by
|
47
|
+
# Contents of message that is sent by server when client disconnect
|
45
48
|
attr_accessor :will_payload
|
46
49
|
|
47
|
-
# The QoS level of the will message sent by the
|
50
|
+
# The QoS level of the will message sent by the server
|
48
51
|
attr_accessor :will_qos
|
49
52
|
|
50
|
-
# If the Will message should be retain by the
|
53
|
+
# If the Will message should be retain by the server after it is sent
|
51
54
|
attr_accessor :will_retain
|
52
55
|
|
53
56
|
|
@@ -56,8 +59,9 @@ class MQTT::Client
|
|
56
59
|
|
57
60
|
# Default attribute values
|
58
61
|
ATTR_DEFAULTS = {
|
59
|
-
:
|
60
|
-
:
|
62
|
+
:host => nil,
|
63
|
+
:port => nil,
|
64
|
+
:version => '3.1.0',
|
61
65
|
:keep_alive => 15,
|
62
66
|
:clean_session => true,
|
63
67
|
:client_id => nil,
|
@@ -89,7 +93,7 @@ class MQTT::Client
|
|
89
93
|
|
90
94
|
# Generate a random client identifier
|
91
95
|
# (using the characters 0-9 and a-z)
|
92
|
-
def self.generate_client_id(prefix='
|
96
|
+
def self.generate_client_id(prefix='ruby', length=16)
|
93
97
|
str = prefix.dup
|
94
98
|
length.times do
|
95
99
|
num = rand(36)
|
@@ -113,7 +117,7 @@ class MQTT::Client
|
|
113
117
|
# - a Hash containing attributes to be set on the new instance
|
114
118
|
#
|
115
119
|
# If no arguments are given then the method will look for a URI
|
116
|
-
# in the
|
120
|
+
# in the MQTT_SERVER environment variable.
|
117
121
|
#
|
118
122
|
# Examples:
|
119
123
|
# client = MQTT::Client.new
|
@@ -121,8 +125,8 @@ class MQTT::Client
|
|
121
125
|
# client = MQTT::Client.new('mqtt://user:pass@myserver.example.com')
|
122
126
|
# client = MQTT::Client.new('myserver.example.com')
|
123
127
|
# client = MQTT::Client.new('myserver.example.com', 18830)
|
124
|
-
# client = MQTT::Client.new(:
|
125
|
-
# client = MQTT::Client.new(:
|
128
|
+
# client = MQTT::Client.new(:host => 'myserver.example.com')
|
129
|
+
# client = MQTT::Client.new(:host => 'myserver.example.com', :keep_alive => 30)
|
126
130
|
#
|
127
131
|
def initialize(*args)
|
128
132
|
if args.last.is_a?(Hash)
|
@@ -132,8 +136,8 @@ class MQTT::Client
|
|
132
136
|
end
|
133
137
|
|
134
138
|
if args.length == 0
|
135
|
-
if ENV['
|
136
|
-
attr.merge!(parse_uri(ENV['
|
139
|
+
if ENV['MQTT_SERVER']
|
140
|
+
attr.merge!(parse_uri(ENV['MQTT_SERVER']))
|
137
141
|
end
|
138
142
|
end
|
139
143
|
|
@@ -144,12 +148,12 @@ class MQTT::Client
|
|
144
148
|
when %r|^mqtts?://|
|
145
149
|
attr.merge!(parse_uri(args[0]))
|
146
150
|
else
|
147
|
-
attr.merge!(:
|
151
|
+
attr.merge!(:host => args[0])
|
148
152
|
end
|
149
153
|
end
|
150
154
|
|
151
155
|
if args.length >= 2
|
152
|
-
attr.merge!(:
|
156
|
+
attr.merge!(:port => args[1]) unless args[1].nil?
|
153
157
|
end
|
154
158
|
|
155
159
|
if args.length >= 3
|
@@ -162,12 +166,12 @@ class MQTT::Client
|
|
162
166
|
end
|
163
167
|
|
164
168
|
# Set a default port number
|
165
|
-
if @
|
166
|
-
@
|
169
|
+
if @port.nil?
|
170
|
+
@port = @ssl ? MQTT::DEFAULT_SSL_PORT : MQTT::DEFAULT_PORT
|
167
171
|
end
|
168
172
|
|
169
173
|
# Initialise private instance variables
|
170
|
-
@
|
174
|
+
@packet_id = 0
|
171
175
|
@last_pingreq = Time.now
|
172
176
|
@last_pingresp = Time.now
|
173
177
|
@socket = nil
|
@@ -201,8 +205,8 @@ class MQTT::Client
|
|
201
205
|
|
202
206
|
# Set the Will for the client
|
203
207
|
#
|
204
|
-
# The will is a message that will be delivered by the
|
205
|
-
# The Will must be set before establishing a connection to the
|
208
|
+
# The will is a message that will be delivered by the server when the client dies.
|
209
|
+
# The Will must be set before establishing a connection to the server
|
206
210
|
def set_will(topic, payload, retain=false, qos=0)
|
207
211
|
self.will_topic = topic
|
208
212
|
self.will_payload = payload
|
@@ -210,7 +214,7 @@ class MQTT::Client
|
|
210
214
|
self.will_qos = qos
|
211
215
|
end
|
212
216
|
|
213
|
-
# Connect to the MQTT
|
217
|
+
# Connect to the MQTT server
|
214
218
|
# If a block is given, then yield to that block and then disconnect again.
|
215
219
|
def connect(clientid=nil)
|
216
220
|
unless clientid.nil?
|
@@ -219,19 +223,22 @@ class MQTT::Client
|
|
219
223
|
|
220
224
|
if @client_id.nil? or @client_id.empty?
|
221
225
|
if @clean_session
|
222
|
-
@
|
226
|
+
if @version == '3.1.0'
|
227
|
+
# Empty client id is not allowed for version 3.1.0
|
228
|
+
@client_id = MQTT::Client.generate_client_id
|
229
|
+
end
|
223
230
|
else
|
224
231
|
raise 'Must provide a client_id if clean_session is set to false'
|
225
232
|
end
|
226
233
|
end
|
227
234
|
|
228
|
-
if @
|
229
|
-
raise 'No MQTT
|
235
|
+
if @host.nil?
|
236
|
+
raise 'No MQTT server host set when attempting to connect'
|
230
237
|
end
|
231
238
|
|
232
239
|
if not connected?
|
233
240
|
# Create network socket
|
234
|
-
tcp_socket = TCPSocket.new(@
|
241
|
+
tcp_socket = TCPSocket.new(@host, @port)
|
235
242
|
|
236
243
|
if @ssl
|
237
244
|
# Set the protocol version
|
@@ -246,8 +253,9 @@ class MQTT::Client
|
|
246
253
|
@socket = tcp_socket
|
247
254
|
end
|
248
255
|
|
249
|
-
#
|
256
|
+
# Construct a connect packet
|
250
257
|
packet = MQTT::Packet::Connect.new(
|
258
|
+
:version => @version,
|
251
259
|
:clean_session => @clean_session,
|
252
260
|
:keep_alive => @keep_alive,
|
253
261
|
:client_id => @client_id,
|
@@ -281,8 +289,8 @@ class MQTT::Client
|
|
281
289
|
end
|
282
290
|
end
|
283
291
|
|
284
|
-
# Disconnect from the MQTT
|
285
|
-
# If you don't want to say goodbye to the
|
292
|
+
# Disconnect from the MQTT server.
|
293
|
+
# If you don't want to say goodbye to the server, set send_msg to false.
|
286
294
|
def disconnect(send_msg=true)
|
287
295
|
# Stop reading packets from the socket first
|
288
296
|
@read_thread.kill if @read_thread and @read_thread.alive?
|
@@ -299,7 +307,7 @@ class MQTT::Client
|
|
299
307
|
end
|
300
308
|
end
|
301
309
|
|
302
|
-
# Checks whether the client is connected to the
|
310
|
+
# Checks whether the client is connected to the server.
|
303
311
|
def connected?
|
304
312
|
(not @socket.nil?) and (not @socket.closed?)
|
305
313
|
end
|
@@ -314,21 +322,24 @@ class MQTT::Client
|
|
314
322
|
@last_pingreq = Time.now
|
315
323
|
end
|
316
324
|
|
317
|
-
# Publish a message on a particular topic to the MQTT
|
318
|
-
def publish(topic, payload, retain=false, qos=0)
|
325
|
+
# Publish a message on a particular topic to the MQTT server.
|
326
|
+
def publish(topic, payload='', retain=false, qos=0)
|
327
|
+
raise ArgumentError.new("Topic name cannot be nil") if topic.nil?
|
328
|
+
raise ArgumentError.new("Topic name cannot be empty") if topic.empty?
|
329
|
+
|
319
330
|
packet = MQTT::Packet::Publish.new(
|
331
|
+
:id => @packet_id.next,
|
320
332
|
:qos => qos,
|
321
333
|
:retain => retain,
|
322
334
|
:topic => topic,
|
323
|
-
:payload => payload
|
324
|
-
:message_id => @message_id.next
|
335
|
+
:payload => payload
|
325
336
|
)
|
326
337
|
|
327
338
|
# Send the packet
|
328
339
|
send_packet(packet)
|
329
340
|
end
|
330
341
|
|
331
|
-
# Send a subscribe message for one or more topics on the MQTT
|
342
|
+
# Send a subscribe message for one or more topics on the MQTT server.
|
332
343
|
# The topics parameter should be one of the following:
|
333
344
|
# * String: subscribe to one topic with QOS 0
|
334
345
|
# * Array: subscribe to multiple topics with QOS 0
|
@@ -342,13 +353,13 @@ class MQTT::Client
|
|
342
353
|
#
|
343
354
|
def subscribe(*topics)
|
344
355
|
packet = MQTT::Packet::Subscribe.new(
|
345
|
-
:
|
346
|
-
:
|
356
|
+
:id => @packet_id.next,
|
357
|
+
:topics => topics
|
347
358
|
)
|
348
359
|
send_packet(packet)
|
349
360
|
end
|
350
361
|
|
351
|
-
# Return the next message received from the MQTT
|
362
|
+
# Return the next message received from the MQTT server.
|
352
363
|
# An optional topic can be given to subscribe to.
|
353
364
|
#
|
354
365
|
# The method either returns the topic and message as an array:
|
@@ -376,7 +387,7 @@ class MQTT::Client
|
|
376
387
|
end
|
377
388
|
end
|
378
389
|
|
379
|
-
# Return the next packet object received from the MQTT
|
390
|
+
# Return the next packet object received from the MQTT server.
|
380
391
|
# An optional topic can be given to subscribe to.
|
381
392
|
#
|
382
393
|
# The method either returns a single packet:
|
@@ -414,7 +425,7 @@ class MQTT::Client
|
|
414
425
|
@read_queue.length
|
415
426
|
end
|
416
427
|
|
417
|
-
# Send a unsubscribe message for one or more topics on the MQTT
|
428
|
+
# Send a unsubscribe message for one or more topics on the MQTT server
|
418
429
|
def unsubscribe(*topics)
|
419
430
|
if topics.is_a?(Enumerable) and topics.count == 1
|
420
431
|
topics = topics.first
|
@@ -422,14 +433,14 @@ class MQTT::Client
|
|
422
433
|
|
423
434
|
packet = MQTT::Packet::Unsubscribe.new(
|
424
435
|
:topics => topics,
|
425
|
-
:
|
436
|
+
:id => @packet_id.next
|
426
437
|
)
|
427
438
|
send_packet(packet)
|
428
439
|
end
|
429
440
|
|
430
441
|
private
|
431
442
|
|
432
|
-
# Try to read a packet from the
|
443
|
+
# Try to read a packet from the server
|
433
444
|
# Also sends keep-alive ping packets.
|
434
445
|
def receive_packet
|
435
446
|
begin
|
@@ -470,7 +481,9 @@ private
|
|
470
481
|
Timeout.timeout(@ack_timeout) do
|
471
482
|
packet = MQTT::Packet.read(@socket)
|
472
483
|
if packet.class != MQTT::Packet::Connack
|
473
|
-
raise MQTT::ProtocolException.new(
|
484
|
+
raise MQTT::ProtocolException.new(
|
485
|
+
"Response wasn't a connection acknowledgement: #{packet.class}"
|
486
|
+
)
|
474
487
|
end
|
475
488
|
|
476
489
|
# Check the return code
|
@@ -480,7 +493,7 @@ private
|
|
480
493
|
end
|
481
494
|
end
|
482
495
|
|
483
|
-
# Send a packet to
|
496
|
+
# Send a packet to server
|
484
497
|
def send_packet(data)
|
485
498
|
# Throw exception if we aren't connected
|
486
499
|
raise MQTT::NotConnectedException if not connected?
|
@@ -503,12 +516,36 @@ private
|
|
503
516
|
end
|
504
517
|
|
505
518
|
{
|
506
|
-
:
|
507
|
-
:
|
519
|
+
:host => uri.host,
|
520
|
+
:port => uri.port || nil,
|
508
521
|
:username => uri.user,
|
509
522
|
:password => uri.password,
|
510
523
|
:ssl => ssl
|
511
524
|
}
|
512
525
|
end
|
513
526
|
|
527
|
+
|
528
|
+
# ---- Deprecated attributes and methods ---- #
|
529
|
+
public
|
530
|
+
|
531
|
+
# @deprecated Please use {#host} instead
|
532
|
+
def remote_host
|
533
|
+
host
|
534
|
+
end
|
535
|
+
|
536
|
+
# @deprecated Please use {#host=} instead
|
537
|
+
def remote_host=(args)
|
538
|
+
self.host = args
|
539
|
+
end
|
540
|
+
|
541
|
+
# @deprecated Please use {#port} instead
|
542
|
+
def remote_port
|
543
|
+
port
|
544
|
+
end
|
545
|
+
|
546
|
+
# @deprecated Please use {#port=} instead
|
547
|
+
def remote_port=(args)
|
548
|
+
self.port = args
|
549
|
+
end
|
550
|
+
|
514
551
|
end
|