mqtt-rails 1.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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE +210 -0
- data/README.md +323 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/mqtt-rails.rb +144 -0
- data/lib/mqtt_rails/client.rb +414 -0
- data/lib/mqtt_rails/connection_helper.rb +172 -0
- data/lib/mqtt_rails/exception.rb +52 -0
- data/lib/mqtt_rails/handler.rb +274 -0
- data/lib/mqtt_rails/packet.rb +33 -0
- data/lib/mqtt_rails/packet/base.rb +315 -0
- data/lib/mqtt_rails/packet/connack.rb +102 -0
- data/lib/mqtt_rails/packet/connect.rb +183 -0
- data/lib/mqtt_rails/packet/disconnect.rb +38 -0
- data/lib/mqtt_rails/packet/pingreq.rb +29 -0
- data/lib/mqtt_rails/packet/pingresp.rb +38 -0
- data/lib/mqtt_rails/packet/puback.rb +44 -0
- data/lib/mqtt_rails/packet/pubcomp.rb +44 -0
- data/lib/mqtt_rails/packet/publish.rb +148 -0
- data/lib/mqtt_rails/packet/pubrec.rb +44 -0
- data/lib/mqtt_rails/packet/pubrel.rb +62 -0
- data/lib/mqtt_rails/packet/suback.rb +75 -0
- data/lib/mqtt_rails/packet/subscribe.rb +124 -0
- data/lib/mqtt_rails/packet/unsuback.rb +49 -0
- data/lib/mqtt_rails/packet/unsubscribe.rb +84 -0
- data/lib/mqtt_rails/publisher.rb +181 -0
- data/lib/mqtt_rails/sender.rb +129 -0
- data/lib/mqtt_rails/ssl_helper.rb +61 -0
- data/lib/mqtt_rails/subscriber.rb +166 -0
- data/lib/mqtt_rails/version.rb +3 -0
- data/mqtt-rails.gemspec +33 -0
- data/samples/client_blocking(reading).rb +29 -0
- data/samples/client_blocking(writing).rb +18 -0
- data/samples/getting_started.rb +49 -0
- data/samples/test_client.rb +69 -0
- metadata +126 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
### original file from the ruby-mqtt gem
|
3
|
+
### located at https://github.com/njh/ruby-mqtt/blob/master/lib/mqtt/packet.rb
|
4
|
+
### Copyright (c) 2009-2013 Nicholas J Humfrey
|
5
|
+
|
6
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
7
|
+
#
|
8
|
+
# All rights reserved. This program and the accompanying materials
|
9
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
10
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
11
|
+
#
|
12
|
+
# The Eclipse Public License is available at
|
13
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
14
|
+
# and the Eclipse Distribution License is available at
|
15
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
16
|
+
#
|
17
|
+
# Contributors:
|
18
|
+
# Pierre Goudet - initial committer
|
19
|
+
|
20
|
+
module MqttRails
|
21
|
+
module Packet
|
22
|
+
class Pubrec < MqttRails::Packet::Base
|
23
|
+
# Get serialisation of packet's body
|
24
|
+
def encode_body
|
25
|
+
encode_short(@id)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Parse the body (variable header and payload) of a packet
|
29
|
+
def parse_body(buffer)
|
30
|
+
super(buffer)
|
31
|
+
@id = shift_short(buffer)
|
32
|
+
unless buffer.empty?
|
33
|
+
raise MqttRails::PacketFormatException.new(
|
34
|
+
"Extra bytes at end of Publish Received packet")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns a human readable string, summarising the properties of the packet
|
39
|
+
def inspect
|
40
|
+
"\#<#{self.class}: 0x%2.2X>" % id
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
### original file from the ruby-mqtt gem
|
3
|
+
### located at https://github.com/njh/ruby-mqtt/blob/master/lib/mqtt/packet.rb
|
4
|
+
### Copyright (c) 2009-2013 Nicholas J Humfrey
|
5
|
+
|
6
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
7
|
+
#
|
8
|
+
# All rights reserved. This program and the accompanying materials
|
9
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
10
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
11
|
+
#
|
12
|
+
# The Eclipse Public License is available at
|
13
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
14
|
+
# and the Eclipse Distribution License is available at
|
15
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
16
|
+
#
|
17
|
+
# Contributors:
|
18
|
+
# Pierre Goudet - initial committer
|
19
|
+
|
20
|
+
module MqttRails
|
21
|
+
module Packet
|
22
|
+
class Pubrel < MqttRails::Packet::Base
|
23
|
+
# Default attribute values
|
24
|
+
ATTR_DEFAULTS = {
|
25
|
+
:flags => [false, true, false, false],
|
26
|
+
}
|
27
|
+
|
28
|
+
# Create a new Pubrel packet
|
29
|
+
def initialize(args={})
|
30
|
+
super(ATTR_DEFAULTS.merge(args))
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get serialisation of packet's body
|
34
|
+
def encode_body
|
35
|
+
encode_short(@id)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Parse the body (variable header and payload) of a packet
|
39
|
+
def parse_body(buffer)
|
40
|
+
super(buffer)
|
41
|
+
@id = shift_short(buffer)
|
42
|
+
unless buffer.empty?
|
43
|
+
raise "Extra bytes at end of Publish Release packet"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Check that fixed header flags are valid for this packet type
|
48
|
+
# @private
|
49
|
+
def validate_flags
|
50
|
+
if @flags != [false, true, false, false]
|
51
|
+
raise MqttRails::PacketFormatException.new(
|
52
|
+
"Invalid flags in #{type_name} packet header")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns a human readable string, summarising the properties of the packet
|
57
|
+
def inspect
|
58
|
+
"\#<#{self.class}: 0x%2.2X>" % id
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
### original file from the ruby-mqtt gem
|
3
|
+
### located at https://github.com/njh/ruby-mqtt/blob/master/lib/mqtt/packet.rb
|
4
|
+
### Copyright (c) 2009-2013 Nicholas J Humfrey
|
5
|
+
|
6
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
7
|
+
#
|
8
|
+
# All rights reserved. This program and the accompanying materials
|
9
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
10
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
11
|
+
#
|
12
|
+
# The Eclipse Public License is available at
|
13
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
14
|
+
# and the Eclipse Distribution License is available at
|
15
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
16
|
+
#
|
17
|
+
# Contributors:
|
18
|
+
# Pierre Goudet - initial committer
|
19
|
+
|
20
|
+
module MqttRails
|
21
|
+
module Packet
|
22
|
+
class Suback < MqttRails::Packet::Base
|
23
|
+
# An array of return codes, ordered by the topics that were subscribed to
|
24
|
+
attr_accessor :return_codes
|
25
|
+
|
26
|
+
# Default attribute values
|
27
|
+
ATTR_DEFAULTS = {
|
28
|
+
:return_codes => [],
|
29
|
+
}
|
30
|
+
|
31
|
+
# Create a new Subscribe Acknowledgment packet
|
32
|
+
def initialize(args={})
|
33
|
+
super(ATTR_DEFAULTS.merge(args))
|
34
|
+
end
|
35
|
+
|
36
|
+
# Set the granted QoS value for each of the topics that were subscribed to
|
37
|
+
# Can either be an integer or an array or integers.
|
38
|
+
def return_codes=(value)
|
39
|
+
if value.is_a?(Array)
|
40
|
+
@return_codes = value
|
41
|
+
elsif value.is_a?(Integer)
|
42
|
+
@return_codes = [value]
|
43
|
+
else
|
44
|
+
raise MqttRails::PacketFormatException.new(
|
45
|
+
"return_codes should be an integer or an array of return codes")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Get serialisation of packet's body
|
50
|
+
def encode_body
|
51
|
+
if @return_codes.empty?
|
52
|
+
raise MqttRails::PacketFormatException.new(
|
53
|
+
"No granted QoS given when serialising packet")
|
54
|
+
end
|
55
|
+
body = encode_short(@id)
|
56
|
+
return_codes.each { |qos| body += encode_bytes(qos) }
|
57
|
+
return body
|
58
|
+
end
|
59
|
+
|
60
|
+
# Parse the body (variable header and payload) of a packet
|
61
|
+
def parse_body(buffer)
|
62
|
+
super(buffer)
|
63
|
+
@id = shift_short(buffer)
|
64
|
+
while buffer.bytesize > 0
|
65
|
+
@return_codes << shift_byte(buffer)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns a human readable string, summarising the properties of the packet
|
70
|
+
def inspect
|
71
|
+
"\#<#{self.class}: 0x%2.2X, rc=%s>" % [id, return_codes.map { |rc| "0x%2.2X" % rc }.join(',')]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
### original file from the ruby-mqtt gem
|
3
|
+
### located at https://github.com/njh/ruby-mqtt/blob/master/lib/mqtt/packet.rb
|
4
|
+
### Copyright (c) 2009-2013 Nicholas J Humfrey
|
5
|
+
|
6
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
7
|
+
#
|
8
|
+
# All rights reserved. This program and the accompanying materials
|
9
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
10
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
11
|
+
#
|
12
|
+
# The Eclipse Public License is available at
|
13
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
14
|
+
# and the Eclipse Distribution License is available at
|
15
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
16
|
+
#
|
17
|
+
# Contributors:
|
18
|
+
# Pierre Goudet - initial committer
|
19
|
+
|
20
|
+
module MqttRails
|
21
|
+
module Packet
|
22
|
+
class Subscribe < MqttRails::Packet::Base
|
23
|
+
# One or more topic filters to subscribe to
|
24
|
+
attr_accessor :topics
|
25
|
+
|
26
|
+
# Default attribute values
|
27
|
+
ATTR_DEFAULTS = {
|
28
|
+
:topics => [],
|
29
|
+
:flags => [false, true, false, false],
|
30
|
+
}
|
31
|
+
|
32
|
+
# Create a new Subscribe packet
|
33
|
+
def initialize(args={})
|
34
|
+
super(ATTR_DEFAULTS.merge(args))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set one or more topic filters for the Subscribe packet
|
38
|
+
# The topics parameter should be one of the following:
|
39
|
+
# * String: subscribe to one topic with QoS 0
|
40
|
+
# * Array: subscribe to multiple topics with QoS 0
|
41
|
+
# * Hash: subscribe to multiple topics where the key is the topic and the value is the QoS level
|
42
|
+
#
|
43
|
+
# For example:
|
44
|
+
# packet.topics = 'a/b'
|
45
|
+
# packet.topics = ['a/b', 'c/d']
|
46
|
+
# packet.topics = [['a/b',0], ['c/d',1]]
|
47
|
+
# packet.topics = {'a/b' => 0, 'c/d' => 1}
|
48
|
+
#
|
49
|
+
def topics=(value)
|
50
|
+
# Get input into a consistent state
|
51
|
+
if value.is_a?(Array)
|
52
|
+
input = value.flatten
|
53
|
+
else
|
54
|
+
input = [value]
|
55
|
+
end
|
56
|
+
|
57
|
+
@topics = []
|
58
|
+
while(input.length>0)
|
59
|
+
item = input.shift
|
60
|
+
if item.is_a?(Hash)
|
61
|
+
# Convert hash into an ordered array of arrays
|
62
|
+
@topics += item.sort
|
63
|
+
elsif item.is_a?(String)
|
64
|
+
# Peek at the next item in the array, and remove it if it is an integer
|
65
|
+
if input.first.is_a?(Integer)
|
66
|
+
qos = input.shift
|
67
|
+
@topics << [item, qos]
|
68
|
+
else
|
69
|
+
@topics << [item, 0]
|
70
|
+
end
|
71
|
+
else
|
72
|
+
# Meh?
|
73
|
+
raise MqttRails::PacketFormatException.new(
|
74
|
+
"Invalid topics input: #{value.inspect}")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
@topics
|
78
|
+
end
|
79
|
+
|
80
|
+
# Get serialisation of packet's body
|
81
|
+
def encode_body
|
82
|
+
if @topics.empty?
|
83
|
+
raise MqttRails::PacketFormatException.new(
|
84
|
+
"No topics given when serialising packet")
|
85
|
+
end
|
86
|
+
body = encode_short(@id)
|
87
|
+
topics.each do |item|
|
88
|
+
body += encode_string(item[0])
|
89
|
+
body += encode_bytes(item[1])
|
90
|
+
end
|
91
|
+
return body
|
92
|
+
end
|
93
|
+
|
94
|
+
# Parse the body (variable header and payload) of a packet
|
95
|
+
def parse_body(buffer)
|
96
|
+
super(buffer)
|
97
|
+
@id = shift_short(buffer)
|
98
|
+
@topics = []
|
99
|
+
while(buffer.bytesize>0)
|
100
|
+
topic_name = shift_string(buffer)
|
101
|
+
topic_qos = shift_byte(buffer)
|
102
|
+
@topics << [topic_name, topic_qos]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Check that fixed header flags are valid for this packet type
|
107
|
+
# @private
|
108
|
+
def validate_flags
|
109
|
+
if @flags != [false, true, false, false]
|
110
|
+
raise MqttRails::PacketFormatException.new(
|
111
|
+
"Invalid flags in SUBSCRIBE packet header")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Returns a human readable string, summarising the properties of the packet
|
116
|
+
def inspect
|
117
|
+
_str = "\#<#{self.class}: 0x%2.2X, %s>" % [
|
118
|
+
id,
|
119
|
+
topics.map { |t| "'#{t[0]}':#{t[1]}" }.join(', ')
|
120
|
+
]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
### original file from the ruby-mqtt gem
|
3
|
+
### located at https://github.com/njh/ruby-mqtt/blob/master/lib/mqtt/packet.rb
|
4
|
+
### Copyright (c) 2009-2013 Nicholas J Humfrey
|
5
|
+
|
6
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
7
|
+
#
|
8
|
+
# All rights reserved. This program and the accompanying materials
|
9
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
10
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
11
|
+
#
|
12
|
+
# The Eclipse Public License is available at
|
13
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
14
|
+
# and the Eclipse Distribution License is available at
|
15
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
16
|
+
#
|
17
|
+
# Contributors:
|
18
|
+
# Pierre Goudet - initial committer
|
19
|
+
|
20
|
+
module MqttRails
|
21
|
+
module Packet
|
22
|
+
class Unsuback < MqttRails::Packet::Base
|
23
|
+
# Create a new Unsubscribe Acknowledgment packet
|
24
|
+
def initialize(args={})
|
25
|
+
super(args)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Get serialisation of packet's body
|
29
|
+
def encode_body
|
30
|
+
encode_short(@id)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Parse the body (variable header and payload) of a packet
|
34
|
+
def parse_body(buffer)
|
35
|
+
super(buffer)
|
36
|
+
@id = shift_short(buffer)
|
37
|
+
unless buffer.empty?
|
38
|
+
raise MqttRails::PacketFormatException.new(
|
39
|
+
"Extra bytes at end of Unsubscribe Acknowledgment packet")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns a human readable string, summarising the properties of the packet
|
44
|
+
def inspect
|
45
|
+
"\#<#{self.class}: 0x%2.2X>" % id
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
### original file from the ruby-mqtt gem
|
3
|
+
### located at https://github.com/njh/ruby-mqtt/blob/master/lib/mqtt/packet.rb
|
4
|
+
### Copyright (c) 2009-2013 Nicholas J Humfrey
|
5
|
+
|
6
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
7
|
+
#
|
8
|
+
# All rights reserved. This program and the accompanying materials
|
9
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
10
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
11
|
+
#
|
12
|
+
# The Eclipse Public License is available at
|
13
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
14
|
+
# and the Eclipse Distribution License is available at
|
15
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
16
|
+
#
|
17
|
+
# Contributors:
|
18
|
+
# Pierre Goudet - initial committer
|
19
|
+
|
20
|
+
module MqttRails
|
21
|
+
module Packet
|
22
|
+
class Unsubscribe < MqttRails::Packet::Base
|
23
|
+
# One or more topic paths to unsubscribe from
|
24
|
+
attr_accessor :topics
|
25
|
+
|
26
|
+
# Default attribute values
|
27
|
+
ATTR_DEFAULTS = {
|
28
|
+
:topics => [],
|
29
|
+
:flags => [false, true, false, false],
|
30
|
+
}
|
31
|
+
|
32
|
+
# Create a new Unsubscribe packet
|
33
|
+
def initialize(args={})
|
34
|
+
super(ATTR_DEFAULTS.merge(args))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set one or more topic paths to unsubscribe from
|
38
|
+
def topics=(value)
|
39
|
+
if value.is_a?(Array)
|
40
|
+
@topics = value
|
41
|
+
else
|
42
|
+
@topics = [value]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Get serialisation of packet's body
|
47
|
+
def encode_body
|
48
|
+
if @topics.empty?
|
49
|
+
raise MqttRails::PacketFormatException.new(
|
50
|
+
"No topics given when serialising packet")
|
51
|
+
end
|
52
|
+
body = encode_short(@id)
|
53
|
+
topics.each { |topic| body += encode_string(topic) }
|
54
|
+
return body
|
55
|
+
end
|
56
|
+
|
57
|
+
# Parse the body (variable header and payload) of a packet
|
58
|
+
def parse_body(buffer)
|
59
|
+
super(buffer)
|
60
|
+
@id = shift_short(buffer)
|
61
|
+
while buffer.bytesize > 0
|
62
|
+
@topics << shift_string(buffer)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Check that fixed header flags are valid for this packet type
|
67
|
+
# @private
|
68
|
+
def validate_flags
|
69
|
+
if @flags != [false, true, false, false]
|
70
|
+
raise MqttRails::PacketFormatException.new(
|
71
|
+
"Invalid flags in UNSUBSCRIBE packet header")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns a human readable string, summarising the properties of the packet
|
76
|
+
def inspect
|
77
|
+
"\#<#{self.class}: 0x%2.2X, %s>" % [
|
78
|
+
id,
|
79
|
+
topics.map { |t| "'#{t}'" }.join(', ')
|
80
|
+
]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
2
|
+
#
|
3
|
+
# All rights reserved. This program and the accompanying materials
|
4
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
5
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
6
|
+
#
|
7
|
+
# The Eclipse Public License is available at
|
8
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
9
|
+
# and the Eclipse Distribution License is available at
|
10
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
11
|
+
#
|
12
|
+
# Contributors:
|
13
|
+
# Pierre Goudet - initial committer
|
14
|
+
|
15
|
+
module MqttRails
|
16
|
+
class Publisher
|
17
|
+
|
18
|
+
def initialize(sender)
|
19
|
+
@waiting_puback = []
|
20
|
+
@waiting_pubrec = []
|
21
|
+
@waiting_pubrel = []
|
22
|
+
@waiting_pubcomp = []
|
23
|
+
@puback_mutex = Mutex.new
|
24
|
+
@pubrec_mutex = Mutex.new
|
25
|
+
@pubrel_mutex = Mutex.new
|
26
|
+
@pubcomp_mutex = Mutex.new
|
27
|
+
@sender = sender
|
28
|
+
end
|
29
|
+
|
30
|
+
def sender=(sender)
|
31
|
+
@sender = sender
|
32
|
+
end
|
33
|
+
|
34
|
+
def send_publish(topic, payload, retain, qos, new_id)
|
35
|
+
packet = MqttRails::Packet::Publish.new(
|
36
|
+
:id => new_id,
|
37
|
+
:topic => topic,
|
38
|
+
:payload => payload,
|
39
|
+
:retain => retain,
|
40
|
+
:qos => qos
|
41
|
+
)
|
42
|
+
begin
|
43
|
+
case qos
|
44
|
+
when 1
|
45
|
+
push_queue(@waiting_puback, @puback_mutex, MAX_QUEUE, packet, new_id)
|
46
|
+
when 2
|
47
|
+
push_queue(@waiting_pubrec, @pubrec_mutex, MAX_QUEUE, packet, new_id)
|
48
|
+
end
|
49
|
+
rescue FullQueueException
|
50
|
+
Rails.logger.warn("PUBLISH queue is full, waiting for publishing #{packet.inspect}")
|
51
|
+
sleep SELECT_TIMEOUT
|
52
|
+
retry
|
53
|
+
end
|
54
|
+
@sender.append_to_writing(packet)
|
55
|
+
MQTT_ERR_SUCCESS
|
56
|
+
end
|
57
|
+
|
58
|
+
def push_queue(waiting_queue, queue_mutex, max_packet, packet, new_id)
|
59
|
+
if waiting_queue.length >= max_packet
|
60
|
+
raise FullQueueException
|
61
|
+
end
|
62
|
+
queue_mutex.synchronize do
|
63
|
+
waiting_queue.push(:id => new_id, :packet => packet, :timestamp => Time.now)
|
64
|
+
end
|
65
|
+
MQTT_ERR_SUCCESS
|
66
|
+
end
|
67
|
+
|
68
|
+
def do_publish(qos, packet_id)
|
69
|
+
case qos
|
70
|
+
when 0
|
71
|
+
when 1
|
72
|
+
send_puback(packet_id)
|
73
|
+
when 2
|
74
|
+
send_pubrec(packet_id)
|
75
|
+
else
|
76
|
+
Rails.logger.error("The packet QoS value is invalid in publish.")
|
77
|
+
raise PacketException.new('Invalid publish QoS value')
|
78
|
+
end
|
79
|
+
MQTT_ERR_SUCCESS
|
80
|
+
end
|
81
|
+
|
82
|
+
def send_puback(packet_id)
|
83
|
+
packet = MqttRails::Packet::Puback.new(
|
84
|
+
:id => packet_id
|
85
|
+
)
|
86
|
+
@sender.append_to_writing(packet)
|
87
|
+
MQTT_ERR_SUCCESS
|
88
|
+
end
|
89
|
+
|
90
|
+
def do_puback(packet_id)
|
91
|
+
@puback_mutex.synchronize do
|
92
|
+
@waiting_puback.delete_if { |pck| pck[:id] == packet_id }
|
93
|
+
end
|
94
|
+
MQTT_ERR_SUCCESS
|
95
|
+
end
|
96
|
+
|
97
|
+
def send_pubrec(packet_id)
|
98
|
+
packet = MqttRails::Packet::Pubrec.new(
|
99
|
+
:id => packet_id
|
100
|
+
)
|
101
|
+
push_queue(@waiting_pubrel, @pubrel_mutex, MAX_QUEUE, packet, packet_id)
|
102
|
+
@sender.append_to_writing(packet)
|
103
|
+
MQTT_ERR_SUCCESS
|
104
|
+
end
|
105
|
+
|
106
|
+
def do_pubrec(packet_id)
|
107
|
+
@pubrec_mutex.synchronize do
|
108
|
+
@waiting_pubrec.delete_if { |pck| pck[:id] == packet_id }
|
109
|
+
end
|
110
|
+
send_pubrel(packet_id)
|
111
|
+
end
|
112
|
+
|
113
|
+
def send_pubrel(packet_id)
|
114
|
+
packet = MqttRails::Packet::Pubrel.new(
|
115
|
+
:id => packet_id
|
116
|
+
)
|
117
|
+
push_queue(@waiting_pubcomp, @pubcomp_mutex, MAX_QUEUE, packet, packet_id)
|
118
|
+
@sender.append_to_writing(packet)
|
119
|
+
MQTT_ERR_SUCCESS
|
120
|
+
end
|
121
|
+
|
122
|
+
def do_pubrel(packet_id)
|
123
|
+
@pubrel_mutex.synchronize do
|
124
|
+
@waiting_pubrel.delete_if { |pck| pck[:id] == packet_id }
|
125
|
+
end
|
126
|
+
send_pubcomp(packet_id)
|
127
|
+
end
|
128
|
+
|
129
|
+
def send_pubcomp(packet_id)
|
130
|
+
packet = MqttRails::Packet::Pubcomp.new(
|
131
|
+
:id => packet_id
|
132
|
+
)
|
133
|
+
@sender.append_to_writing(packet)
|
134
|
+
MQTT_ERR_SUCCESS
|
135
|
+
end
|
136
|
+
|
137
|
+
def do_pubcomp(packet_id)
|
138
|
+
@pubcomp_mutex.synchronize do
|
139
|
+
@waiting_pubcomp.delete_if { |pck| pck[:id] == packet_id }
|
140
|
+
end
|
141
|
+
MQTT_ERR_SUCCESS
|
142
|
+
end
|
143
|
+
|
144
|
+
def config_all_message_queue
|
145
|
+
config_message_queue(@waiting_puback, @puback_mutex)
|
146
|
+
config_message_queue(@waiting_pubrec, @pubrec_mutex)
|
147
|
+
config_message_queue(@waiting_pubrel, @pubrel_mutex)
|
148
|
+
config_message_queue(@waiting_pubcomp, @pubcomp_mutex)
|
149
|
+
end
|
150
|
+
|
151
|
+
def config_message_queue(queue, mutex)
|
152
|
+
mutex.synchronize do
|
153
|
+
queue.each do |pck|
|
154
|
+
pck[:timestamp] = Time.now
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def check_waiting_publisher
|
160
|
+
@sender.check_ack_alive(@waiting_puback, @puback_mutex)
|
161
|
+
@sender.check_ack_alive(@waiting_pubrec, @pubrec_mutex)
|
162
|
+
@sender.check_ack_alive(@waiting_pubrel, @pubrel_mutex)
|
163
|
+
@sender.check_ack_alive(@waiting_pubcomp, @pubcomp_mutex)
|
164
|
+
end
|
165
|
+
|
166
|
+
def flush_publisher
|
167
|
+
@puback_mutex.synchronize do
|
168
|
+
@waiting_puback = []
|
169
|
+
end
|
170
|
+
@pubrec_mutex.synchronize do
|
171
|
+
@waiting_pubrec = []
|
172
|
+
end
|
173
|
+
@pubrel_mutex.synchronize do
|
174
|
+
@waiting_pubrel = []
|
175
|
+
end
|
176
|
+
@pubcomp_mutex.synchronize do
|
177
|
+
@waiting_pubcomp = []
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|