mqtt 0.0.2 → 0.0.3
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/NEWS +5 -0
- data/README +20 -9
- data/Rakefile +1 -1
- data/examples/livetext.rb +7 -11
- data/examples/simple_get.rb +6 -10
- data/examples/simple_publish.rb +2 -2
- data/lib/mqtt/client.rb +64 -11
- metadata +2 -2
data/NEWS
CHANGED
data/README
CHANGED
@@ -12,24 +12,35 @@ You may get the latest stable version from Rubyforge. Source gems are also avail
|
|
12
12
|
|
13
13
|
== Synopsis
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
require 'rubygems'
|
16
|
+
require 'mqtt'
|
17
|
+
|
18
|
+
# Publish example
|
19
|
+
mqtt = MQTT::Client.new('mqtt.example.com')
|
20
|
+
mqtt.connect do |c|
|
21
|
+
c.publish('topic','message')
|
22
|
+
end
|
23
|
+
|
24
|
+
# Subscribe example
|
25
|
+
mqtt = MQTT::Client.new('mqtt.example.com')
|
26
|
+
client.connect do
|
27
|
+
client.subscribe('test')
|
28
|
+
loop do
|
29
|
+
topic,message = client.get
|
30
|
+
puts "#{topic}: #{message}"
|
31
|
+
end
|
32
|
+
end
|
17
33
|
|
18
|
-
mqtt = MQTT::Client.new('mqtt.example.com')
|
19
|
-
mqtt.connect('clientid') do |c|
|
20
|
-
c.publish('topic','message')
|
21
|
-
end
|
22
34
|
|
23
35
|
== TODO
|
24
36
|
|
25
37
|
* Process acknowledgement packets
|
26
|
-
* Automatic uninque client identifier if none given
|
27
38
|
* Create classes for each type of packet?
|
28
39
|
* More validations of data/parameters
|
29
40
|
* Implement exception throwing
|
30
41
|
* Implement Will and Testament
|
31
|
-
* Add unit tests
|
32
42
|
* More examples
|
43
|
+
* Integration tests
|
33
44
|
* Refactor to add callbacks that are called from seperate thread
|
34
45
|
* Implement QOS Level 1
|
35
46
|
* Implement QOS Level 2
|
@@ -37,7 +48,7 @@ You may get the latest stable version from Rubyforge. Source gems are also avail
|
|
37
48
|
|
38
49
|
== Resources
|
39
50
|
|
40
|
-
http://mqtt.org
|
51
|
+
http://www.mqtt.org
|
41
52
|
|
42
53
|
== Contact
|
43
54
|
|
data/Rakefile
CHANGED
data/examples/livetext.rb
CHANGED
@@ -4,15 +4,11 @@ $:.unshift File.dirname(__FILE__)+'/../lib'
|
|
4
4
|
|
5
5
|
require 'mqtt'
|
6
6
|
|
7
|
-
|
8
7
|
client = MQTT::Client.new('hadrian.aelius.com')
|
9
|
-
client.connect
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
client.disconnect
|
8
|
+
client.connect do
|
9
|
+
client.subscribe('livetext/#')
|
10
|
+
loop do
|
11
|
+
topic,message = client.get
|
12
|
+
puts "#{topic}: #{message}"
|
13
|
+
end
|
14
|
+
end
|
data/examples/simple_get.rb
CHANGED
@@ -4,15 +4,11 @@ $:.unshift File.dirname(__FILE__)+'/../lib'
|
|
4
4
|
|
5
5
|
require 'mqtt'
|
6
6
|
|
7
|
-
|
8
7
|
client = MQTT::Client.new('mqtt.example.com')
|
9
|
-
client.connect
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
puts "#{topic}: #{message}"
|
8
|
+
client.connect do
|
9
|
+
client.subscribe('#')
|
10
|
+
loop do
|
11
|
+
topic,message = client.get
|
12
|
+
puts "#{topic}: #{message}"
|
13
|
+
end
|
16
14
|
end
|
17
|
-
|
18
|
-
client.disconnect
|
data/examples/simple_publish.rb
CHANGED
@@ -5,8 +5,8 @@ $:.unshift File.dirname(__FILE__)+'/../lib'
|
|
5
5
|
require 'mqtt'
|
6
6
|
|
7
7
|
client = MQTT::Client.new('mqtt.example.com')
|
8
|
-
client.connect
|
8
|
+
client.connect do |c|
|
9
9
|
|
10
|
-
c.publish('test',
|
10
|
+
c.publish('test', "The time is: #{Time.now}")
|
11
11
|
|
12
12
|
end
|
data/lib/mqtt/client.rb
CHANGED
@@ -4,6 +4,7 @@ require 'mqtt'
|
|
4
4
|
require 'mqtt/packet'
|
5
5
|
require 'thread'
|
6
6
|
require 'socket'
|
7
|
+
require 'timeout'
|
7
8
|
|
8
9
|
|
9
10
|
module MQTT
|
@@ -12,8 +13,10 @@ module MQTT
|
|
12
13
|
class Client
|
13
14
|
attr_reader :remote_host # Hostname of the remote broker
|
14
15
|
attr_reader :remote_port # Port number of the remote broker
|
15
|
-
attr_accessor :keep_alive # Time between pings to remote broker
|
16
|
+
attr_accessor :keep_alive # Time (in seconds) between pings to remote broker
|
16
17
|
attr_accessor :clean_start # Set the 'Clean Start' flag when connecting?
|
18
|
+
attr_accessor :client_id # Client Identifier
|
19
|
+
attr_accessor :ack_timeout # Number of seconds to wait for acknowledgement packets
|
17
20
|
|
18
21
|
# Timeout between select polls (in seconds)
|
19
22
|
SELECT_TIMEOUT = 0.5
|
@@ -22,9 +25,11 @@ module MQTT
|
|
22
25
|
def initialize(remote_host='localhost', remote_port=1883)
|
23
26
|
@remote_host = remote_host
|
24
27
|
@remote_port = remote_port
|
25
|
-
@message_id = 0
|
26
28
|
@keep_alive = 10
|
27
29
|
@clean_start = true
|
30
|
+
@client_id = random_letters(16)
|
31
|
+
@message_id = 0
|
32
|
+
@ack_timeout = 5
|
28
33
|
@last_pingreq = Time.now
|
29
34
|
@last_pingresp = Time.now
|
30
35
|
@socket = nil
|
@@ -35,16 +40,12 @@ module MQTT
|
|
35
40
|
|
36
41
|
# Connect to the MQTT broker
|
37
42
|
# If a block is given, then yield to that block and then disconnect again.
|
38
|
-
def connect(clientid)
|
43
|
+
def connect(clientid=nil)
|
44
|
+
@client_id = clientid unless clientid.nil?
|
45
|
+
|
39
46
|
if not connected?
|
40
47
|
# Create network socket
|
41
48
|
@socket = TCPSocket.new(@remote_host,@remote_port)
|
42
|
-
|
43
|
-
# Start packet reading thread
|
44
|
-
@read_thread = Thread.new(Thread.current) do |parent|
|
45
|
-
Thread.current[:parent] = parent
|
46
|
-
loop { receive_packet }
|
47
|
-
end
|
48
49
|
|
49
50
|
# Protocol name and version
|
50
51
|
packet = MQTT::Packet.new(:type => :connect)
|
@@ -61,10 +62,19 @@ module MQTT
|
|
61
62
|
packet.add_short(@keep_alive)
|
62
63
|
|
63
64
|
# Add the client identifier
|
64
|
-
packet.add_string(
|
65
|
+
packet.add_string(@client_id)
|
65
66
|
|
66
67
|
# Send packet
|
67
68
|
send_packet(packet)
|
69
|
+
|
70
|
+
# Receive response
|
71
|
+
receive_connack
|
72
|
+
|
73
|
+
# Start packet reading thread
|
74
|
+
@read_thread = Thread.new(Thread.current) do |parent|
|
75
|
+
Thread.current[:parent] = parent
|
76
|
+
loop { receive_packet }
|
77
|
+
end
|
68
78
|
end
|
69
79
|
|
70
80
|
# If a block is given, then yield and disconnect
|
@@ -82,7 +92,7 @@ module MQTT
|
|
82
92
|
packet = MQTT::Packet.new(:type => :disconnect)
|
83
93
|
send_packet(packet)
|
84
94
|
end
|
85
|
-
@read_thread.kill
|
95
|
+
@read_thread.kill if @read_thread and @read_thread.alive?
|
86
96
|
@read_thread = nil
|
87
97
|
@socket.close unless @socket.nil?
|
88
98
|
@socket = nil
|
@@ -222,6 +232,31 @@ module MQTT
|
|
222
232
|
end
|
223
233
|
end
|
224
234
|
|
235
|
+
# Read and check a connection acknowledgement packet
|
236
|
+
def receive_connack
|
237
|
+
Timeout.timeout(@ack_timeout) do
|
238
|
+
packet = MQTT::Packet.read(@socket)
|
239
|
+
if packet.type != :connack
|
240
|
+
raise MQTT::ProtocolException.new("Response wan't a connection acknowledgement: #{packet.type}")
|
241
|
+
end
|
242
|
+
|
243
|
+
# Read in the return code
|
244
|
+
byte1, return_code = packet.shift_bytes(2)
|
245
|
+
if return_code == 0x00
|
246
|
+
# Success
|
247
|
+
nil
|
248
|
+
elsif return_code == 0x01
|
249
|
+
raise MQTT::ProtocolException.new("Connection refused: unacceptable protocol version")
|
250
|
+
elsif return_code == 0x02
|
251
|
+
raise MQTT::ProtocolException.new("Connection refused: client identifier rejected")
|
252
|
+
elsif return_code == 0x03
|
253
|
+
raise MQTT::ProtocolException.new("Connection refused: broker unavailable")
|
254
|
+
else
|
255
|
+
raise MQTT::ProtocolException.new("Connection refused: #{return_code}")
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
225
260
|
# Send a packet to broker
|
226
261
|
def send_packet(data)
|
227
262
|
# Throw exception if we aren't connected
|
@@ -232,6 +267,24 @@ module MQTT
|
|
232
267
|
@socket.write(data)
|
233
268
|
end
|
234
269
|
end
|
270
|
+
|
271
|
+
# Generate a string of random letters (0-9,a-z)
|
272
|
+
def random_letters(count)
|
273
|
+
str = ''
|
274
|
+
count.times do
|
275
|
+
num = rand(36)
|
276
|
+
if (num<10)
|
277
|
+
# Number
|
278
|
+
num += 48
|
279
|
+
else
|
280
|
+
# Letter
|
281
|
+
num += 87
|
282
|
+
end
|
283
|
+
str += num.chr
|
284
|
+
end
|
285
|
+
return str
|
286
|
+
end
|
287
|
+
|
235
288
|
|
236
289
|
end
|
237
290
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mqtt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas J Humfrey
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-02-
|
12
|
+
date: 2009-02-08 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|