mqtt 0.0.1

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/COPYING ADDED
@@ -0,0 +1,56 @@
1
+ ruby-mqtt is copyrighted free software by Nicholas J Humfrey <njh@aelius.com>.
2
+ You can redistribute it and/or modify it under either the terms of the GPL
3
+ version 2 (see the file GPL), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) give non-standard binaries non-standard names, with
21
+ instructions on where to get the original software distribution.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or binary form,
26
+ provided that you do at least ONE of the following:
27
+
28
+ a) distribute the binaries and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c) give non-standard binaries non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under these terms.
43
+
44
+ For the list of those files and their copying conditions, see the
45
+ file LEGAL.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
data/NEWS ADDED
@@ -0,0 +1,5 @@
1
+ = Ruby MQTT NEWS
2
+
3
+ == Ruby MQTT Version 0.0.1 (2009-01-??)
4
+
5
+ Initial Release.
data/README ADDED
@@ -0,0 +1,47 @@
1
+ = ruby-mqtt
2
+
3
+ Pure Ruby gem that implements the MQTT (Message Queue Telemetry Transport) protocol, a lightweight protocol for publish/subscribe messaging.
4
+
5
+ RubyForge Project Page http://rubyforge.org/projects/mqtt/
6
+
7
+ == Installing
8
+
9
+ You may get the latest stable version from Rubyforge. Source gems are also available.
10
+
11
+ $ gem install mqtt
12
+
13
+ == Synopsis
14
+
15
+ require 'rubygems'
16
+ require 'mqtt'
17
+
18
+ mqtt = MQTT::Client.new('mqtt.example.com')
19
+ mqtt.connect('clientid') do |c|
20
+ c.publish('topic','message')
21
+ end
22
+
23
+ == TODO
24
+
25
+ * Support payloads longer than 128 bytes
26
+ * Process acknowledgement packets
27
+ * Create classes for each type of packet?
28
+ * More validations of data/parameters
29
+ * Implement exception throwing
30
+ * Implement Will and Testament
31
+ * Add unit tests
32
+ * More examples
33
+ * Refactor to add callbacks that are called from seperate thread
34
+ * Implement QOS Level 1
35
+ * Implement QOS Level 2
36
+ * Add support for binding socket to specific local address
37
+
38
+ == Resources
39
+
40
+ http://mqtt.org
41
+
42
+ == Contact
43
+
44
+ Author:: Nicholas J Humfrey
45
+ Email:: njh@aelius.com
46
+ Home Page:: http://www.aelius.com/njh/
47
+ License:: Distributes under the same terms as Ruby
data/Rakefile ADDED
@@ -0,0 +1,112 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/rdoctask'
6
+ require 'spec/rake/spectask'
7
+ require 'spec/rake/verify_rcov'
8
+
9
+
10
+ NAME = "mqtt"
11
+ VERS = "0.0.1"
12
+ CLEAN.include ['pkg', 'rdoc']
13
+
14
+ spec = Gem::Specification.new do |s|
15
+ s.name = NAME
16
+ s.version = VERS
17
+ s.author = "Nicholas J Humfrey"
18
+ s.email = "njh@aelius.com"
19
+ s.homepage = "http://mqtt.rubyforge.org"
20
+ s.platform = Gem::Platform::RUBY
21
+ s.summary = "Implementation of the MQTT (Message Queue Telemetry Transport) protocol"
22
+ s.rubyforge_project = "mqtt"
23
+ s.description = "Pure Ruby gem that implements the MQTT (Message Queue Telemetry Transport) protocol, a lightweight protocol for publish/subscribe messaging."
24
+ s.files = FileList["Rakefile", "lib/*.rb", "lib/mqtt/*.rb", "examples/*"]
25
+ s.require_path = "lib"
26
+
27
+ # rdoc
28
+ s.has_rdoc = true
29
+ s.extra_rdoc_files = ["README", "NEWS", "COPYING"]
30
+
31
+ # Build Dependencies
32
+ #s.add_dependency 'rake' '~> 0.8'
33
+ #s.add_dependency 'rspec', '~> 1.1'
34
+ #s.add_dependency 'rcov', '~> 0.8'
35
+ #s.add_dependency 'mocha', '~> 0.9'
36
+ end
37
+
38
+ desc "Default: test the gem."
39
+ task :default => [:check_syntax, :rdoc]
40
+
41
+ task :build_package => [:repackage]
42
+ Rake::GemPackageTask.new(spec) do |pkg|
43
+ pkg.need_zip = false
44
+ pkg.need_tar = true
45
+ pkg.gem_spec = spec
46
+ end
47
+
48
+ desc "Run :package and install the resulting .gem"
49
+ task :install => :package do
50
+ sh %{sudo gem install --local pkg/#{NAME}-#{VERS}.gem}
51
+ end
52
+
53
+ desc "Run :clean and uninstall the .gem"
54
+ task :uninstall => :clean do
55
+ sh %{sudo gem uninstall #{NAME}}
56
+ end
57
+
58
+
59
+
60
+ ## Testing
61
+ desc "Run all the specification tests"
62
+ Spec::Rake::SpecTask.new(:spec) do |t|
63
+ t.spec_files = FileList['spec/*_spec.rb']
64
+ t.spec_opts = ["--colour"]
65
+ end
66
+
67
+ desc "Check the syntax of all ruby files"
68
+ task :check_syntax do
69
+ `find . -name "*.rb" |xargs -n1 ruby -c |grep -v "Syntax OK"`
70
+ puts "* Done"
71
+ end
72
+
73
+ namespace :spec do
74
+ desc "Generate RCov report"
75
+ Spec::Rake::SpecTask.new(:rcov) do |t|
76
+ t.spec_files = FileList['spec/*_spec.rb']
77
+ t.rcov = true
78
+ t.rcov_dir = 'coverage'
79
+ t.rcov_opts = ['--text-report', '--exclude', "spec/"]
80
+ end
81
+
82
+ desc "Generate specdoc"
83
+ Spec::Rake::SpecTask.new(:doc) do |t|
84
+ t.spec_files = FileList['spec/*_spec.rb']
85
+ t.spec_opts = ["--format", "specdoc"]
86
+ end
87
+
88
+ namespace :doc do
89
+ desc "Generate html specdoc"
90
+ Spec::Rake::SpecTask.new(:html) do |t|
91
+ t.spec_files = FileList['spec/*_spec.rb']
92
+ t.spec_opts = ["--format", "html:rspec_report.html", "--diff"]
93
+ end
94
+ end
95
+ end
96
+
97
+
98
+
99
+ ## Documentation
100
+ desc "Generate documentation for the library"
101
+ Rake::RDocTask.new("rdoc") { |rdoc|
102
+ rdoc.rdoc_dir = 'rdoc'
103
+ rdoc.title = "mqtt Documentation"
104
+ rdoc.options << '--line-numbers' << '--inline-source'
105
+ rdoc.main = "README"
106
+ rdoc.rdoc_files.include("README", "NEWS", "COPYING", "lib/*.rb", "lib/mqtt/*.rb")
107
+ }
108
+
109
+ desc "Upload rdoc to rubyforge"
110
+ task :upload_rdoc => [:rdoc] do
111
+ sh %{/usr/bin/scp -r -p rdoc/* mqtt.rubyforge.org:/var/www/gforge-projects/mqtt}
112
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.dirname(__FILE__)+'/../lib'
4
+
5
+ require 'mqtt'
6
+
7
+
8
+ client = MQTT::Client.new('mqtt.example.com')
9
+ client.connect('simple_get')
10
+
11
+ client.subscribe('$SYS/#')
12
+
13
+ loop do
14
+ topic,message = client.get
15
+ puts "#{topic}: #{message}"
16
+ end
17
+
18
+ client.disconnect
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.dirname(__FILE__)+'/../lib'
4
+
5
+ require 'mqtt'
6
+
7
+ client = MQTT::Client.new('mqtt.example.com')
8
+ client.connect('simple_publish_example') do |c|
9
+
10
+ c.publish('test', "The time is: #{Time.now}")
11
+
12
+ end
@@ -0,0 +1,238 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'mqtt'
4
+ require 'mqtt/packet'
5
+ require 'thread'
6
+ require 'socket'
7
+
8
+
9
+ module MQTT
10
+
11
+ # Client class for talking to an MQTT broker
12
+ class Client
13
+ attr_reader :remote_host # Hostname of the remote broker
14
+ attr_reader :remote_port # Port number of the remote broker
15
+ attr_accessor :keep_alive # Time between pings to remote broker
16
+ attr_accessor :clean_start # Set the 'Clean Start' flag when connecting?
17
+
18
+ # Timeout between select polls (in seconds)
19
+ SELECT_TIMEOUT = 0.5
20
+
21
+ # Create a new MQTT Client instance
22
+ def initialize(remote_host='localhost', remote_port=1883)
23
+ @remote_host = remote_host
24
+ @remote_port = remote_port
25
+ @message_id = 0
26
+ @keep_alive = 10
27
+ @clean_start = true
28
+ @last_pingreq = Time.now
29
+ @last_pingresp = Time.now
30
+ @socket = nil
31
+ @read_queue = Queue.new
32
+ @read_thread = nil
33
+ @write_semaphore = Mutex.new
34
+ end
35
+
36
+ # Connect to the MQTT broker
37
+ # If a block is given, then yield to that block and then disconnect again.
38
+ def connect(clientid)
39
+ if not connected?
40
+ # Create network socket
41
+ @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
+ # Protocol name and version
50
+ packet = MQTT::Packet.new(:type => :connect)
51
+ packet.add_string('MQIsdp')
52
+ packet.add_bytes(0x03)
53
+
54
+ # Connect flags
55
+ connect_flags = 0x00
56
+ connect_flags ||= 0x02 if @clean_start
57
+ # FIXME: implement Will and Testament
58
+ packet.add_bytes(connect_flags)
59
+
60
+ # Keep Alive timer: 10 seconds
61
+ packet.add_short(@keep_alive)
62
+
63
+ # Add the client identifier
64
+ packet.add_string(clientid)
65
+
66
+ # Send packet
67
+ send_packet(packet)
68
+ end
69
+
70
+ # If a block is given, then yield and disconnect
71
+ if block_given?
72
+ yield(self)
73
+ disconnect
74
+ end
75
+ end
76
+
77
+ # Disconnect from the MQTT broker.
78
+ # If you don't want to say goodbye to the broker, set send_msg to false.
79
+ def disconnect(send_msg=true)
80
+ if connected?
81
+ if send_msg
82
+ packet = MQTT::Packet.new(:type => :disconnect)
83
+ send_packet(packet)
84
+ end
85
+ @read_thread.kill unless @read_thread.nil?
86
+ @read_thread = nil
87
+ @socket.close unless @socket.nil?
88
+ @socket = nil
89
+ end
90
+ end
91
+
92
+ # Checks whether the client is connected to the broker.
93
+ def connected?
94
+ not @socket.nil?
95
+ end
96
+
97
+ # Send a MQTT ping message to indicate that the MQTT client is alive.
98
+ def ping
99
+ packet = MQTT::Packet.new(:type => :pingreq)
100
+ send_packet(packet)
101
+ @last_pingreq = Time.now
102
+ end
103
+
104
+ # Publish a message on a particular topic to the MQTT broker.
105
+ def publish(topic, payload, retain=false, qos=0)
106
+ packet = MQTT::Packet.new(
107
+ :type => :publish,
108
+ :qos => qos,
109
+ :retain => retain
110
+ )
111
+
112
+ # Add the topic name
113
+ packet.add_string(topic)
114
+
115
+ # Add Message ID for qos1 and qos2
116
+ unless qos == 0
117
+ packet.add_short(@message_id.next)
118
+ end
119
+
120
+ # Add the packet payload
121
+ packet.add_data(payload)
122
+
123
+ # Send the packet
124
+ send_packet(packet)
125
+ end
126
+
127
+ # Send a subscribe message for one or more topics on the MQTT broker.
128
+ # The topics parameter should be one of the following:
129
+ # * String: subscribe to one topic with QOS 0
130
+ # * Array: subscribe to multiple topics with QOS 0
131
+ # * Hash: subscribe to multiple topics where the key is the topic and the value is the QOS level
132
+ #
133
+ # For example:
134
+ # client.subscribe( 'a/b' )
135
+ # client.subscribe( 'a/b', 'c/d' )
136
+ # client.subscribe( ['a/b',0], ['c/d',1] )
137
+ # client.subscribe( 'a/b' => 0, 'c/d' => 1 )
138
+ #
139
+ def subscribe(*topics)
140
+ array = []
141
+ topics.each do |item|
142
+ if item.is_a?(Hash)
143
+ # Convert hash into an ordered array of arrays
144
+ array += item.sort
145
+ elsif item.is_a?(Array)
146
+ # Already in [topic,qos] format
147
+ array.push item
148
+ else
149
+ # Default to QOS 0
150
+ array.push [item.to_s,0]
151
+ end
152
+ end
153
+
154
+ # Create the packet
155
+ packet = MQTT::Packet.new(:type => :subscribe, :qos => 1)
156
+ packet.add_short(@message_id.next)
157
+ array.each do |item|
158
+ packet.add_string(item[0])
159
+ packet.add_bytes(item[1])
160
+ end
161
+ send_packet(packet)
162
+ end
163
+
164
+ # Return the next message recieved from the MQTT broker.
165
+ # This method blocks until a message is available.
166
+ #
167
+ # The method returns the topic and message as an array:
168
+ # topic,message = client.get
169
+ #
170
+ def get
171
+ # Wait for a packet to be available
172
+ packet = @read_queue.pop
173
+
174
+ # Parse the variable header
175
+ topic = packet.shift_string
176
+ msg_id = packet.shift_short unless (packet.qos == 0)
177
+ return topic,packet.body
178
+ end
179
+
180
+ # Send a unsubscribe message for one or more topics on the MQTT broker
181
+ def unsubscribe(*topics)
182
+ packet = MQTT::Packet.new(:type => :unsubscribe, :qos => 1)
183
+ topics.each { |topic| packet.add_string(topic) }
184
+ send_packet(packet)
185
+ end
186
+
187
+ private
188
+
189
+ # Try to read a packet from the broker
190
+ # Also sends keep-alive ping packets.
191
+ def receive_packet
192
+ begin
193
+ # Poll socket - is there data waiting?
194
+ result = IO.select([@socket], nil, nil, SELECT_TIMEOUT)
195
+ unless result.nil?
196
+ # Yes - read in the packet
197
+ packet = MQTT::Packet.read(@socket)
198
+ if packet.type == :publish
199
+ # Add to queue
200
+ @read_queue.push(packet)
201
+ else
202
+ # Ignore all other packets
203
+ nil
204
+ # FIXME: implement responses for QOS 1 and 2
205
+ end
206
+ end
207
+
208
+ # Time to send a keep-alive ping request?
209
+ if Time.now > @last_pingreq + @keep_alive
210
+ ping
211
+ end
212
+
213
+ # FIXME: check we received a ping response recently?
214
+
215
+ # Pass exceptions up to parent thread
216
+ rescue Exception => exp
217
+ unless @socket.nil?
218
+ @socket.close
219
+ @socket = nil
220
+ end
221
+ Thread.current[:parent].raise(exp)
222
+ end
223
+ end
224
+
225
+ # Send a packet to broker
226
+ def send_packet(data)
227
+ # Throw exception if we aren't connected
228
+ raise MQTT::NotConnectedException if not connected?
229
+
230
+ # Only allow one thread to write to socket at a time
231
+ @write_semaphore.synchronize do
232
+ @socket.write(data)
233
+ end
234
+ end
235
+
236
+ end
237
+
238
+ end
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'mqtt'
4
+
5
+ module MQTT
6
+
7
+ # Class representing a MQTT Packet
8
+ # Performs binary encoding and decoding of headers
9
+ class Packet #:nodoc: all
10
+ attr_reader :type # The packet type
11
+ attr_reader :dup # Duplicate delivery flag
12
+ attr_reader :retain # Retain flag
13
+ attr_reader :qos # Quality of Service level
14
+ attr_reader :body # Packet's body (everything after fixed header)
15
+
16
+ # Read in a packet from a socket
17
+ def self.read(sock)
18
+ header = sock.read(2)
19
+ raise MQTT::ProtocolException if header.nil?
20
+ byte1,byte2 = header.unpack('C*')
21
+
22
+ # FIXME: support decoding of multi-byte length header
23
+
24
+ packet = MQTT::Packet.new(
25
+ :type => ((byte1 & 0xF0) >> 4),
26
+ :dup => ((byte1 & 0x08) >> 3),
27
+ :qos => ((byte1 & 0x06) >> 1),
28
+ :retain => ((byte1 & 0x01) >> 0)
29
+ )
30
+ packet.body = sock.read(byte2)
31
+
32
+ return packet
33
+ end
34
+
35
+ # Create a new empty packet
36
+ def initialize(args={})
37
+ self.type = args[:type] || :invalid
38
+ self.dup = args[:dup] || false
39
+ self.qos = args[:qos] || 0
40
+ self.retain = args[:retain] || false
41
+ self.body = args[:body] || ''
42
+ end
43
+
44
+ def type=(arg)
45
+ if arg.kind_of?(Integer)
46
+ # Convert type identifier to symbol
47
+ @type = MQTT::PACKET_TYPES[arg]
48
+ else
49
+ @type = arg.to_sym
50
+ # FIXME: raise exception if packet type is invalid?
51
+ end
52
+ end
53
+
54
+ # Return the identifer for this packet type
55
+ def type_id
56
+ raise "No packet type set for this packet" if @type.nil?
57
+ index = MQTT::PACKET_TYPES.index(@type)
58
+ raise "Invalid packet type: #{@type}" if index.nil?
59
+ return index
60
+ end
61
+
62
+ def dup=(arg)
63
+ if arg.kind_of?(Integer)
64
+ @dup = (arg != 0 ? true : false)
65
+ else
66
+ @dup = arg
67
+ end
68
+ end
69
+
70
+ def retain=(arg)
71
+ if arg.kind_of?(Integer)
72
+ @retain = (arg != 0 ? true : false)
73
+ else
74
+ @retain = arg
75
+ end
76
+ end
77
+
78
+ def qos=(arg)
79
+ @qos = arg.to_i
80
+ end
81
+
82
+ def body=(arg)
83
+ @body = arg.to_s
84
+ end
85
+
86
+
87
+
88
+
89
+
90
+ # Add an array of bytes to the end of the packet's body
91
+ def add_bytes(*bytes)
92
+ @body += bytes.pack('C*')
93
+ end
94
+
95
+ # Add a 16-bit unsigned integer to the end of the packet's body
96
+ def add_short(val)
97
+ @body += [val.to_i].pack('n')
98
+ end
99
+
100
+ # Add some raw data to the end of the packet's body
101
+ def add_data(data)
102
+ data = data.to_s unless data.is_a?(String)
103
+ @body += data
104
+ end
105
+
106
+ # Add a string to the end of the packet's body
107
+ # (preceded by the length of the string)
108
+ def add_string(str)
109
+ str = str.to_s unless str.is_a?(String)
110
+ add_short(str.size)
111
+ add_data(str)
112
+ end
113
+
114
+
115
+ # Remove a 16-bit unsigned integer from the front on the body
116
+ def shift_short
117
+ bytes = @body.slice!(0..1)
118
+ bytes.unpack('n').first
119
+ end
120
+
121
+ # Remove n bytes from the front on the body
122
+ def shift_bytes(bytes)
123
+ @body.slice!(0...bytes).unpack('C*')
124
+ end
125
+
126
+ # Remove n bytes from the front on the body
127
+ def shift_data(bytes)
128
+ @body.slice!(0...bytes)
129
+ end
130
+
131
+ # Remove string from the front on the body
132
+ def shift_string
133
+ len = shift_short
134
+ shift_data(len)
135
+ end
136
+
137
+
138
+ # Serialise the packet
139
+ def to_s
140
+ # Encode the 2-byte fixed header
141
+ header = [
142
+ ((type_id.to_i & 0x0F) << 4) |
143
+ ((dup ? 0x1 : 0x0) << 3) |
144
+ ((qos.to_i & 0x03) << 1) |
145
+ (retain ? 0x1 : 0x0),
146
+ (@body.length & 0x7F)
147
+ ]
148
+ # FIXME: support multi-byte length header
149
+ header.pack('C*') + @body
150
+ end
151
+
152
+ def inspect
153
+ format("#<MQTT::Packet:0x%01x ", object_id)+
154
+ "type=#{@type}, dup=#{@dup}, retain=#{@retain}, "+
155
+ "qos=#{@qos}, body.size=#{@body.size}>"
156
+ end
157
+
158
+ end
159
+
160
+ end
data/lib/mqtt.rb ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'mqtt/client'
4
+
5
+ # Pure-ruby implementation of the MQTT protocol
6
+ module MQTT
7
+
8
+ PACKET_TYPES = [
9
+ nil,
10
+ :connect, # Client request to connect to Broker
11
+ :connack, # Connect Acknowledgment
12
+ :publish, # Publish message
13
+ :puback, # Publish Acknowledgment
14
+ :pubrec, # Publish Received (assured delivery part 1)
15
+ :pubrel, # Publish Release (assured delivery part 2)
16
+ :pubcomp, # Publish Complete (assured delivery part 3)
17
+ :subscribe, # Client Subscribe request
18
+ :suback, # Subscribe Acknowledgment
19
+ :unsubscribe, # Client Unsubscribe request
20
+ :unsuback, # Unsubscribe Acknowledgment
21
+ :pingreq, # PING Request
22
+ :pingresp, # PING Response
23
+ :disconnect, # Client is Disconnecting
24
+ nil
25
+ ]
26
+
27
+ class Exception < Exception
28
+
29
+ end
30
+
31
+ class ProtocolException < MQTT::Exception
32
+
33
+ end
34
+
35
+ class NotConnectedException < MQTT::Exception
36
+
37
+ end
38
+
39
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mqtt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nicholas J Humfrey
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-01 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Pure Ruby gem that implements the MQTT (Message Queue Telemetry Transport) protocol, a lightweight protocol for publish/subscribe messaging.
17
+ email: njh@aelius.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ - NEWS
25
+ - COPYING
26
+ files:
27
+ - Rakefile
28
+ - lib/mqtt.rb
29
+ - lib/mqtt/client.rb
30
+ - lib/mqtt/packet.rb
31
+ - examples/simple_get.rb
32
+ - examples/simple_publish.rb
33
+ - README
34
+ - NEWS
35
+ - COPYING
36
+ has_rdoc: true
37
+ homepage: http://mqtt.rubyforge.org
38
+ post_install_message:
39
+ rdoc_options: []
40
+
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project: mqtt
58
+ rubygems_version: 1.3.1
59
+ signing_key:
60
+ specification_version: 2
61
+ summary: Implementation of the MQTT (Message Queue Telemetry Transport) protocol
62
+ test_files: []
63
+