mini_mqtt 0.1.0 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +14 -15
- data/lib/mini_mqtt.rb +13 -0
- data/lib/mini_mqtt/client.rb +35 -45
- data/lib/mini_mqtt/connack_packet.rb +30 -0
- data/lib/mini_mqtt/connect_packet.rb +3 -2
- data/lib/mini_mqtt/disconnect_packet.rb +5 -0
- data/lib/mini_mqtt/packet.rb +19 -180
- data/lib/mini_mqtt/packet_handler.rb +2 -18
- data/lib/mini_mqtt/pingreq_packet.rb +5 -0
- data/lib/mini_mqtt/pingresp_packet.rb +5 -0
- data/lib/mini_mqtt/puback_packet.rb +6 -0
- data/lib/mini_mqtt/pubcomp_packet.rb +6 -0
- data/lib/mini_mqtt/publish_packet.rb +53 -0
- data/lib/mini_mqtt/pubrec_packet.rb +6 -0
- data/lib/mini_mqtt/pubrel_packet.rb +10 -0
- data/lib/mini_mqtt/suback_packet.rb +14 -0
- data/lib/mini_mqtt/subscribe_packet.rb +25 -0
- data/lib/mini_mqtt/unsuback_packet.rb +6 -0
- data/lib/mini_mqtt/unsubscribe_packet.rb +25 -0
- metadata +25 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 122329e41615462566527851764e5f1120bde96e
|
4
|
+
data.tar.gz: 22a3417ee3be5c3911fff0233a766e01f4fdb7e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 149e5b17a38167dab79812ad5f9a652cccb21f52f69c78cc69fd740d375469fba1d8e5652ddcaa3b4eacc83aebe7a5799adb336824259bddae51bb69c18f1ad1
|
7
|
+
data.tar.gz: f49d83a7b2f26be8951afa6981f9bcea1e68e8d94523d4808d5e2d02db7f7ebcf8c0f315af985b0f382ab32951533d49a453785444dc2fc8e5a5dbaec9208504
|
data/README.md
CHANGED
@@ -1,33 +1,31 @@
|
|
1
|
+
[](https://codeclimate.com/github/antico5/mini_mqtt)
|
2
|
+
[](https://codeclimate.com/github/antico5/mini_mqtt/coverage)
|
3
|
+
[](https://codeclimate.com/github/antico5/mini_mqtt)
|
4
|
+
[](https://travis-ci.org/antico5/mini_mqtt)
|
5
|
+
|
1
6
|
# MiniMqtt
|
2
7
|
|
3
8
|
A full ruby implementation of the client side of MQTT protocol.
|
4
9
|
|
5
10
|
The philosophy behind this gem is to keep the code as minimal and tidy as possible, and to completely avoid dependencies.
|
6
11
|
|
7
|
-
cloc lib
|
8
|
-
|
9
|
-
---------------------------------------------------------------------
|
10
|
-
Language files blank comment code
|
11
|
-
---------------------------------------------------------------------
|
12
|
-
Ruby 6 103 14 449
|
13
|
-
---------------------------------------------------------------------
|
14
12
|
|
15
13
|
## Features
|
16
14
|
|
17
15
|
* Supports all MQTT features up to QoS 1.
|
18
|
-
*
|
19
|
-
*
|
16
|
+
* 450 lines of code
|
17
|
+
* 98% test coverage
|
18
|
+
* Doesn't store messages once the connection has been closed/lost.
|
20
19
|
|
21
20
|
## Installation
|
22
21
|
|
23
|
-
|
22
|
+
`gem 'mini_mqtt'`
|
23
|
+
|
24
24
|
|
25
25
|
## How to test
|
26
|
-
|
26
|
+
Integration tests will hit mosquitto's test broker test.mosquitto.org.
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
rake test
|
28
|
+
`rake test`
|
31
29
|
|
32
30
|
## Usage
|
33
31
|
|
@@ -85,7 +83,7 @@ client.subscribe '/topic', '/qos_topic' => 1
|
|
85
83
|
```
|
86
84
|
|
87
85
|
### Get messages
|
88
|
-
The caller of these methods
|
86
|
+
The caller of these methods is blocked until a message arrives, or the connection is lost.
|
89
87
|
|
90
88
|
```ruby
|
91
89
|
# Get a single message
|
@@ -99,5 +97,6 @@ end
|
|
99
97
|
```
|
100
98
|
|
101
99
|
### Gracefully disconnect
|
100
|
+
```ruby
|
102
101
|
client.disconnect
|
103
102
|
```
|
data/lib/mini_mqtt.rb
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
require 'mini_mqtt/bin_helper'
|
2
2
|
require 'mini_mqtt/packet'
|
3
3
|
require 'mini_mqtt/connect_packet'
|
4
|
+
require 'mini_mqtt/connack_packet'
|
5
|
+
require 'mini_mqtt/publish_packet'
|
6
|
+
require 'mini_mqtt/puback_packet'
|
7
|
+
require 'mini_mqtt/pubrec_packet'
|
8
|
+
require 'mini_mqtt/pubrel_packet'
|
9
|
+
require 'mini_mqtt/pubcomp_packet'
|
10
|
+
require 'mini_mqtt/subscribe_packet'
|
11
|
+
require 'mini_mqtt/suback_packet'
|
12
|
+
require 'mini_mqtt/unsubscribe_packet'
|
13
|
+
require 'mini_mqtt/unsuback_packet'
|
14
|
+
require 'mini_mqtt/pingreq_packet'
|
15
|
+
require 'mini_mqtt/pingresp_packet'
|
16
|
+
require 'mini_mqtt/disconnect_packet'
|
4
17
|
require 'mini_mqtt/packet_handler'
|
5
18
|
require 'mini_mqtt/client'
|
6
19
|
|
data/lib/mini_mqtt/client.rb
CHANGED
@@ -17,16 +17,16 @@ module MiniMqtt
|
|
17
17
|
def connect options = {}
|
18
18
|
# Create socket and packet handler
|
19
19
|
@socket = TCPSocket.new @host, @port
|
20
|
-
@
|
20
|
+
@handler = PacketHandler.new @socket
|
21
21
|
|
22
22
|
# Send ConnectPacket
|
23
|
-
|
23
|
+
@handler.write_packet ConnectPacket.new user: @user,
|
24
24
|
password: @password, keep_alive: @keep_alive, client_id: @client_id,
|
25
25
|
clean_session: @clean_session, will_topic: options[:will_topic],
|
26
26
|
will_message: options[:will_message], will_retain: options[:will_retain]
|
27
27
|
|
28
28
|
# Receive connack packet
|
29
|
-
connack =
|
29
|
+
connack = @handler.get_packet
|
30
30
|
|
31
31
|
if connack.accepted?
|
32
32
|
@received_messages = Queue.new
|
@@ -46,22 +46,22 @@ module MiniMqtt
|
|
46
46
|
end
|
47
47
|
topics = topics.inject :merge
|
48
48
|
packet = SubscribePacket.new topics: topics
|
49
|
-
|
49
|
+
@handler.write_packet packet
|
50
50
|
end
|
51
51
|
|
52
52
|
def unsubscribe *topics
|
53
|
-
|
53
|
+
@handler.write_packet UnsubscribePacket.new topics: topics
|
54
54
|
end
|
55
55
|
|
56
56
|
def publish topic, message, options = {}
|
57
57
|
packet = PublishPacket.new topic: topic, message: message.to_s,
|
58
58
|
retain: options[:retain], qos: options[:qos]
|
59
|
-
|
59
|
+
@handler.write_packet packet
|
60
60
|
end
|
61
61
|
|
62
62
|
def disconnect
|
63
63
|
# Send DisconnectPacket, then kill threads and close socket
|
64
|
-
|
64
|
+
@handler.write_packet DisconnectPacket.new
|
65
65
|
@read_thread.kill
|
66
66
|
@keepalive_thread.kill
|
67
67
|
@socket.close
|
@@ -83,53 +83,43 @@ module MiniMqtt
|
|
83
83
|
|
84
84
|
private
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
@
|
92
|
-
|
93
|
-
|
94
|
-
def handle_received_packet packet
|
95
|
-
case packet
|
96
|
-
when PingrespPacket
|
97
|
-
@last_ping_response = Time.now
|
98
|
-
|
99
|
-
when PublishPacket
|
100
|
-
@received_messages << packet
|
101
|
-
if packet.qos > 0
|
102
|
-
send_packet PubackPacket.new packet_id: packet.packet_id
|
103
|
-
end
|
104
|
-
|
105
|
-
when PubackPacket
|
86
|
+
def handle_received_packet packet
|
87
|
+
case packet
|
88
|
+
when PingrespPacket
|
89
|
+
@last_ping_response = Time.now
|
90
|
+
when PublishPacket
|
91
|
+
@received_messages << packet
|
92
|
+
if packet.qos > 0
|
93
|
+
@handler.write_packet PubackPacket.new packet_id: packet.packet_id
|
106
94
|
end
|
95
|
+
when PubackPacket
|
107
96
|
end
|
97
|
+
end
|
108
98
|
|
109
|
-
|
110
|
-
|
111
|
-
|
99
|
+
def generate_client_id
|
100
|
+
"client_#{ rand(10000000) }"
|
101
|
+
end
|
112
102
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
end
|
118
|
-
@received_messages << nil
|
103
|
+
def spawn_read_thread!
|
104
|
+
@read_thread = Thread.new do
|
105
|
+
while connected? do
|
106
|
+
handle_received_packet @handler.get_packet
|
119
107
|
end
|
108
|
+
@received_messages << nil
|
120
109
|
end
|
110
|
+
end
|
121
111
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
end
|
112
|
+
def spawn_keepalive_thread!
|
113
|
+
@keepalive_thread = Thread.new do
|
114
|
+
while connected? do
|
115
|
+
@handler.write_packet PingreqPacket.new
|
116
|
+
sleep @keep_alive
|
117
|
+
if Time.now - @last_ping_response > 2 * @keep_alive
|
118
|
+
puts "Error: MQTT Server not responding to ping. Disconnecting."
|
119
|
+
@socket.close
|
131
120
|
end
|
132
121
|
end
|
133
122
|
end
|
123
|
+
end
|
134
124
|
end
|
135
125
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module MiniMqtt
|
2
|
+
class ConnackPacket < Packet
|
3
|
+
attr_reader :return_code
|
4
|
+
register_packet_type 2
|
5
|
+
|
6
|
+
ERRORS = { 1 => "unacceptable protocol version",
|
7
|
+
2 => "identifier rejected",
|
8
|
+
3 => "server unavailable",
|
9
|
+
4 => "bad username or password",
|
10
|
+
5 => "not authorized" }
|
11
|
+
|
12
|
+
|
13
|
+
def read_variable_header
|
14
|
+
@session_present = @stream.readbyte & 0x01
|
15
|
+
@return_code = @stream.readbyte
|
16
|
+
end
|
17
|
+
|
18
|
+
def session_present?
|
19
|
+
@session_present == 1
|
20
|
+
end
|
21
|
+
|
22
|
+
def accepted?
|
23
|
+
@return_code == 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def error_message
|
27
|
+
ERRORS[@return_code]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module MiniMqtt
|
2
2
|
class ConnectPacket < Packet
|
3
|
+
register_packet_type 1
|
4
|
+
|
3
5
|
def initialize options = {}
|
4
6
|
@user = options[:user]
|
5
7
|
@password = options[:password]
|
@@ -29,8 +31,7 @@ module MiniMqtt
|
|
29
31
|
end
|
30
32
|
|
31
33
|
def build_payload
|
32
|
-
payload =
|
33
|
-
payload << mqtt_utf8_encode(@client_id)
|
34
|
+
payload = mqtt_utf8_encode(@client_id)
|
34
35
|
if @will_message
|
35
36
|
payload << mqtt_utf8_encode(@will_topic)
|
36
37
|
payload << mqtt_utf8_encode(@will_message)
|
data/lib/mini_mqtt/packet.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
class InvalidFlagsError < StandardError ; end
|
2
|
-
|
3
1
|
module MiniMqtt
|
4
2
|
class Packet
|
5
3
|
include BinHelper
|
6
4
|
|
7
5
|
@@last_packet_id = 0
|
6
|
+
@@packet_classes = {}
|
8
7
|
|
9
8
|
def decode stream, flags = 0
|
10
9
|
@stream = stream
|
@@ -22,218 +21,58 @@ module MiniMqtt
|
|
22
21
|
0b000
|
23
22
|
end
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
def new_packet_id
|
28
|
-
@@last_packet_id += 1
|
29
|
-
@@last_packet_id %= 65535
|
30
|
-
1 + @@last_packet_id
|
31
|
-
end
|
32
|
-
|
33
|
-
def read_variable_header
|
34
|
-
end
|
35
|
-
|
36
|
-
def read_payload
|
37
|
-
end
|
38
|
-
|
39
|
-
def handle_flags flags
|
40
|
-
end
|
41
|
-
|
42
|
-
def build_variable_header
|
43
|
-
""
|
44
|
-
end
|
45
|
-
|
46
|
-
def build_payload
|
47
|
-
""
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
module AckPacket
|
53
|
-
attr_accessor :packet_id
|
54
|
-
|
55
|
-
def initialize params = {}
|
56
|
-
@packet_id = params[:packet_id]
|
57
|
-
end
|
58
|
-
|
59
|
-
def read_variable_header
|
60
|
-
@packet_id = read_ushort @stream
|
61
|
-
end
|
62
|
-
|
63
|
-
def build_variable_header
|
64
|
-
ushort @packet_id
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
class ConnackPacket < Packet
|
69
|
-
attr_reader :return_code
|
70
|
-
|
71
|
-
ERRORS = { 1 => "unacceptable protocol version",
|
72
|
-
2 => "identifier rejected",
|
73
|
-
3 => "server unavailable",
|
74
|
-
4 => "bad username or password",
|
75
|
-
5 => "not authorized" }
|
76
|
-
|
77
|
-
|
78
|
-
def read_variable_header
|
79
|
-
@session_present = @stream.readbyte & 0x01
|
80
|
-
@return_code = @stream.readbyte
|
24
|
+
def self.packet_type_id
|
25
|
+
@packet_type_id
|
81
26
|
end
|
82
27
|
|
83
|
-
def
|
84
|
-
|
28
|
+
def self.get_packet_class packet_type_id
|
29
|
+
@@packet_classes[packet_type_id]
|
85
30
|
end
|
86
31
|
|
87
|
-
|
88
|
-
@return_code == 0
|
89
|
-
end
|
32
|
+
private
|
90
33
|
|
91
|
-
def
|
92
|
-
|
34
|
+
def self.register_packet_type packet_type_id
|
35
|
+
@packet_type_id = packet_type_id
|
36
|
+
@@packet_classes[packet_type_id] = self
|
93
37
|
end
|
94
38
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
def handle_flags flags
|
101
|
-
@dup = flags & 0b1000 != 0
|
102
|
-
@qos = (flags & 0b0110) >> 1
|
103
|
-
@retain = flags & 0b0001 != 0
|
39
|
+
def new_packet_id
|
40
|
+
@@last_packet_id += 1
|
41
|
+
@@last_packet_id %= 65535
|
42
|
+
1 + @@last_packet_id
|
104
43
|
end
|
105
44
|
|
106
45
|
def read_variable_header
|
107
|
-
@topic = read_mqtt_encoded_string @stream
|
108
|
-
if @qos > 0
|
109
|
-
@packet_id = read_ushort @stream
|
110
|
-
end
|
111
46
|
end
|
112
47
|
|
113
48
|
def read_payload
|
114
|
-
@message = @stream.read
|
115
|
-
end
|
116
|
-
|
117
|
-
def initialize params = {}
|
118
|
-
@topic = params[:topic] || ""
|
119
|
-
@message = params[:message] || ""
|
120
|
-
@qos = params[:qos] || 0
|
121
|
-
@dup = params[:dup] || false
|
122
|
-
@retain = params[:retain] || false
|
123
|
-
@packet_id = params[:packet_id]
|
124
49
|
end
|
125
50
|
|
126
|
-
def flags
|
127
|
-
flags = 0
|
128
|
-
flags |= 0b0001 if @retain
|
129
|
-
flags |= qos << 1
|
130
|
-
flags |= 0b1000 if @dup
|
131
|
-
flags
|
51
|
+
def handle_flags flags
|
132
52
|
end
|
133
53
|
|
134
54
|
def build_variable_header
|
135
|
-
|
136
|
-
if @qos > 0
|
137
|
-
@packet_id ||= new_packet_id
|
138
|
-
header << ushort(@packet_id)
|
139
|
-
end
|
140
|
-
header
|
55
|
+
""
|
141
56
|
end
|
142
57
|
|
143
58
|
def build_payload
|
144
|
-
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
148
|
-
|
149
|
-
class PubackPacket < Packet
|
150
|
-
include AckPacket
|
151
|
-
end
|
152
|
-
|
153
|
-
class PubrecPacket < Packet
|
154
|
-
include AckPacket
|
155
|
-
end
|
156
|
-
|
157
|
-
class PubrelPacket < Packet
|
158
|
-
include AckPacket
|
159
|
-
|
160
|
-
def flags
|
161
|
-
0b0010
|
59
|
+
""
|
162
60
|
end
|
163
61
|
end
|
164
62
|
|
165
|
-
|
166
|
-
|
167
|
-
end
|
168
|
-
|
169
|
-
class SubscribePacket < Packet
|
170
|
-
attr_accessor :packet_id, :topics
|
63
|
+
module AckPacket
|
64
|
+
attr_accessor :packet_id
|
171
65
|
|
172
66
|
def initialize params = {}
|
173
|
-
@
|
174
|
-
end
|
175
|
-
|
176
|
-
def flags
|
177
|
-
0b0010
|
178
|
-
end
|
179
|
-
|
180
|
-
def build_variable_header
|
181
|
-
@packet_id ||= new_packet_id
|
182
|
-
ushort @packet_id
|
183
|
-
end
|
184
|
-
|
185
|
-
def build_payload
|
186
|
-
@topics.map do |topic, qos|
|
187
|
-
mqtt_utf8_encode(topic) + uchar(qos)
|
188
|
-
end.join
|
67
|
+
@packet_id = params[:packet_id]
|
189
68
|
end
|
190
|
-
end
|
191
|
-
|
192
|
-
class SubackPacket < Packet
|
193
|
-
attr_accessor :packet_id, :max_qos_accepted
|
194
69
|
|
195
70
|
def read_variable_header
|
196
71
|
@packet_id = read_ushort @stream
|
197
72
|
end
|
198
73
|
|
199
|
-
def read_payload
|
200
|
-
@max_qos_accepted = @stream.read.unpack 'C*'
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
class UnsubscribePacket < Packet
|
205
|
-
attr_accessor :packet_id, :topics
|
206
|
-
|
207
|
-
def flags
|
208
|
-
0b0010
|
209
|
-
end
|
210
|
-
|
211
|
-
def initialize params = {}
|
212
|
-
@topics = params[:topics]
|
213
|
-
end
|
214
|
-
|
215
74
|
def build_variable_header
|
216
|
-
@packet_id ||= new_packet_id
|
217
75
|
ushort @packet_id
|
218
76
|
end
|
219
|
-
|
220
|
-
def build_payload
|
221
|
-
@topics.map do |topic|
|
222
|
-
mqtt_utf8_encode(topic)
|
223
|
-
end.join
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
class UnsubackPacket < Packet
|
228
|
-
include AckPacket
|
229
|
-
end
|
230
|
-
|
231
|
-
class PingreqPacket < Packet
|
232
|
-
end
|
233
|
-
|
234
|
-
class PingrespPacket < Packet
|
235
|
-
end
|
236
|
-
|
237
|
-
class DisconnectPacket < Packet
|
238
77
|
end
|
239
78
|
end
|
@@ -1,22 +1,6 @@
|
|
1
1
|
require 'stringio'
|
2
2
|
|
3
3
|
module MiniMqtt
|
4
|
-
PACKET_CLASSES = { 1 => ConnectPacket,
|
5
|
-
2 => ConnackPacket,
|
6
|
-
3 => PublishPacket,
|
7
|
-
4 => PubackPacket,
|
8
|
-
5 => PubrecPacket,
|
9
|
-
6 => PubrelPacket,
|
10
|
-
7 => PubcompPacket,
|
11
|
-
8 => SubscribePacket,
|
12
|
-
9 => SubackPacket,
|
13
|
-
10 => UnsubscribePacket,
|
14
|
-
11 => UnsubackPacket,
|
15
|
-
12 => PingreqPacket,
|
16
|
-
13 => PingrespPacket,
|
17
|
-
14 => DisconnectPacket }
|
18
|
-
PACKET_CODES = PACKET_CLASSES.invert
|
19
|
-
|
20
4
|
class PacketHandler
|
21
5
|
include BinHelper
|
22
6
|
|
@@ -36,7 +20,7 @@ module MiniMqtt
|
|
36
20
|
def get_packet
|
37
21
|
# First byte contains packet type and flags. 4 bits each.
|
38
22
|
first_byte = @stream.readbyte
|
39
|
-
packet_class =
|
23
|
+
packet_class = Packet.get_packet_class(first_byte >> 4)
|
40
24
|
flags = first_byte & 0xf
|
41
25
|
|
42
26
|
#Decode length using algorithm, and read packet body.
|
@@ -55,7 +39,7 @@ module MiniMqtt
|
|
55
39
|
def write_packet packet
|
56
40
|
# Write type and flags, then encoded packet length, then packet
|
57
41
|
@mutex.synchronize do
|
58
|
-
type_and_flags =
|
42
|
+
type_and_flags = packet.class.packet_type_id << 4
|
59
43
|
type_and_flags += packet.flags
|
60
44
|
@stream.write uchar(type_and_flags)
|
61
45
|
encoded_packet = packet.encode
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module MiniMqtt
|
2
|
+
class PublishPacket < Packet
|
3
|
+
attr_accessor :dup, :qos, :retain, :packet_id, :topic, :message
|
4
|
+
register_packet_type 3
|
5
|
+
|
6
|
+
def handle_flags flags
|
7
|
+
@dup = flags & 0b1000 != 0
|
8
|
+
@qos = (flags & 0b0110) >> 1
|
9
|
+
@retain = flags & 0b0001 != 0
|
10
|
+
end
|
11
|
+
|
12
|
+
def read_variable_header
|
13
|
+
@topic = read_mqtt_encoded_string @stream
|
14
|
+
if @qos > 0
|
15
|
+
@packet_id = read_ushort @stream
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def read_payload
|
20
|
+
@message = @stream.read
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize params = {}
|
24
|
+
@topic = params[:topic] || ""
|
25
|
+
@message = params[:message] || ""
|
26
|
+
@qos = params[:qos] || 0
|
27
|
+
@dup = params[:dup] || false
|
28
|
+
@retain = params[:retain] || false
|
29
|
+
@packet_id = params[:packet_id]
|
30
|
+
end
|
31
|
+
|
32
|
+
def flags
|
33
|
+
flags = 0
|
34
|
+
flags |= 0b0001 if @retain
|
35
|
+
flags |= qos << 1
|
36
|
+
flags |= 0b1000 if @dup
|
37
|
+
flags
|
38
|
+
end
|
39
|
+
|
40
|
+
def build_variable_header
|
41
|
+
header = mqtt_utf8_encode @topic
|
42
|
+
if @qos > 0
|
43
|
+
@packet_id ||= new_packet_id
|
44
|
+
header << ushort(@packet_id)
|
45
|
+
end
|
46
|
+
header
|
47
|
+
end
|
48
|
+
|
49
|
+
def build_payload
|
50
|
+
@message
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module MiniMqtt
|
2
|
+
class SubackPacket < Packet
|
3
|
+
attr_accessor :packet_id, :max_qos_accepted
|
4
|
+
register_packet_type 9
|
5
|
+
|
6
|
+
def read_variable_header
|
7
|
+
@packet_id = read_ushort @stream
|
8
|
+
end
|
9
|
+
|
10
|
+
def read_payload
|
11
|
+
@max_qos_accepted = @stream.read.unpack 'C*'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module MiniMqtt
|
2
|
+
class SubscribePacket < Packet
|
3
|
+
attr_accessor :packet_id, :topics
|
4
|
+
register_packet_type 8
|
5
|
+
|
6
|
+
def initialize params = {}
|
7
|
+
@topics = params[:topics]
|
8
|
+
end
|
9
|
+
|
10
|
+
def flags
|
11
|
+
0b0010
|
12
|
+
end
|
13
|
+
|
14
|
+
def build_variable_header
|
15
|
+
@packet_id ||= new_packet_id
|
16
|
+
ushort @packet_id
|
17
|
+
end
|
18
|
+
|
19
|
+
def build_payload
|
20
|
+
@topics.map do |topic, qos|
|
21
|
+
mqtt_utf8_encode(topic) + uchar(qos)
|
22
|
+
end.join
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module MiniMqtt
|
2
|
+
class UnsubscribePacket < Packet
|
3
|
+
attr_accessor :packet_id, :topics
|
4
|
+
register_packet_type 10
|
5
|
+
|
6
|
+
def flags
|
7
|
+
0b0010
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize params = {}
|
11
|
+
@topics = params[:topics]
|
12
|
+
end
|
13
|
+
|
14
|
+
def build_variable_header
|
15
|
+
@packet_id ||= new_packet_id
|
16
|
+
ushort @packet_id
|
17
|
+
end
|
18
|
+
|
19
|
+
def build_payload
|
20
|
+
@topics.map do |topic|
|
21
|
+
mqtt_utf8_encode(topic)
|
22
|
+
end.join
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mini_mqtt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Armando Andini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -90,9 +90,22 @@ files:
|
|
90
90
|
- lib/mini_mqtt.rb
|
91
91
|
- lib/mini_mqtt/bin_helper.rb
|
92
92
|
- lib/mini_mqtt/client.rb
|
93
|
+
- lib/mini_mqtt/connack_packet.rb
|
93
94
|
- lib/mini_mqtt/connect_packet.rb
|
95
|
+
- lib/mini_mqtt/disconnect_packet.rb
|
94
96
|
- lib/mini_mqtt/packet.rb
|
95
97
|
- lib/mini_mqtt/packet_handler.rb
|
98
|
+
- lib/mini_mqtt/pingreq_packet.rb
|
99
|
+
- lib/mini_mqtt/pingresp_packet.rb
|
100
|
+
- lib/mini_mqtt/puback_packet.rb
|
101
|
+
- lib/mini_mqtt/pubcomp_packet.rb
|
102
|
+
- lib/mini_mqtt/publish_packet.rb
|
103
|
+
- lib/mini_mqtt/pubrec_packet.rb
|
104
|
+
- lib/mini_mqtt/pubrel_packet.rb
|
105
|
+
- lib/mini_mqtt/suback_packet.rb
|
106
|
+
- lib/mini_mqtt/subscribe_packet.rb
|
107
|
+
- lib/mini_mqtt/unsuback_packet.rb
|
108
|
+
- lib/mini_mqtt/unsubscribe_packet.rb
|
96
109
|
- test/client_test.rb
|
97
110
|
- test/connack_packet_test.rb
|
98
111
|
- test/connect_packet_test.rb
|
@@ -134,19 +147,19 @@ signing_key:
|
|
134
147
|
specification_version: 4
|
135
148
|
summary: MQTT Client for Ruby.
|
136
149
|
test_files:
|
137
|
-
- test/
|
138
|
-
- test/disconnect_packet_test.rb
|
139
|
-
- test/publish_packet_test.rb
|
150
|
+
- test/pubrel_packet_test.rb
|
140
151
|
- test/ping_packets_test.rb
|
141
|
-
- test/
|
152
|
+
- test/disconnect_packet_test.rb
|
153
|
+
- test/unsuback_packet_test.rb
|
154
|
+
- test/puback_packet_test.rb
|
142
155
|
- test/unsubscribe_packet_test.rb
|
143
|
-
- test/connect_packet_test.rb
|
144
156
|
- test/test_helper.rb
|
145
|
-
- test/
|
146
|
-
- test/
|
157
|
+
- test/connect_packet_test.rb
|
158
|
+
- test/publish_packet_test.rb
|
147
159
|
- test/suback_packet_test.rb
|
148
|
-
- test/
|
160
|
+
- test/pubcomp_packet_test.rb
|
161
|
+
- test/subscribe_packet_test.rb
|
162
|
+
- test/connack_packet_test.rb
|
163
|
+
- test/packet_handler_test.rb
|
149
164
|
- test/client_test.rb
|
150
|
-
- test/pubrel_packet_test.rb
|
151
165
|
- test/pubrec_packet_test.rb
|
152
|
-
- test/packet_handler_test.rb
|