mqtt-sub_handler 0.1.6.2 → 0.1.6.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: bfe901d34d1a891840006f77467ef0929bfb9ff1363ccc3ece47cf35454178b0
4
- data.tar.gz: 1e601e44349b5e360068d3e07a4a59caa0254cfc2aaee1e1f870fe1069041e96
2
+ SHA1:
3
+ metadata.gz: 35fd43af3792d80dd5b218ad0b3e55c61c4d750d
4
+ data.tar.gz: afd508d2b76d30428d3c6c74ad44f12a7428b123
5
5
  SHA512:
6
- metadata.gz: 589b2c0307aa5ec6aa0e253805d8b095ce73997bd9461bc7abc060d306ac6f1b5c8ff18ddee861a1c2d43d6b7e3685bacb9b4994360b106c1ad19791c91bd511
7
- data.tar.gz: 4d5d90483bfa7ce80c4c6359d5fb38faad29a08f447d987cebf1779597190c4e7d692950a0bafa1d63b98d5d76d5fcdedd696b6385ab170a5c917da0c4ef0ac0
6
+ metadata.gz: ec4ef80c35649a5ed3c56666d7797c9436a2f5aba2e02bfeea433c01be85e5343d7a5fb68fab03fde76953a1787527929ccf1f8f74138fb2913846901e21c3b6
7
+ data.tar.gz: '0200581a1aa3da0d1a33519d725e3b0d5c987fd54f6e9466e69f8638de2a3844abab71ba4384a8121539e03889961fe201977086a319ad2147c4516b0956e27c'
@@ -0,0 +1,353 @@
1
+
2
+ require 'timeout'
3
+ require 'mqtt'
4
+ require 'colorize'
5
+
6
+ require 'xasin_logger'
7
+
8
+ module MQTT
9
+ class BaseHandler
10
+ include XasLogger::Mix
11
+
12
+ # Split a Topic into a Topic-Array
13
+ # @param topicName [String] The string topic which to split
14
+ # @return [Array<String>] A list of individual topic-branches
15
+ # @note This function is mainly used for background processing.
16
+ def self.get_topic_split(topicName)
17
+ return topicName.scan(/[^\/]+/);
18
+ end
19
+
20
+ # Match a topic string to a topic pattern
21
+ # @param receivedTopicString [String] The string (as
22
+ # returned by MQTT.get) to compare
23
+ # @param topicPattern [Array<String>] The Topic-Array (as
24
+ # returned by .get_topic_split) to compare against
25
+ # @return [nil, Array<String>] Nil if no match was found.
26
+ # An Array of matched wildcard topic branches (can be empty) when
27
+ # successfully matched
28
+ # @note (see .get_topic_split)
29
+ def self.getTopicMatch(receivedTopicString, topicPattern)
30
+ receivedTopicList = get_topic_split receivedTopicString;
31
+
32
+ outputTopicList = Array.new();
33
+
34
+ return nil unless receivedTopicList.length >= topicPattern.length;
35
+
36
+ topicPattern.each_index do |i|
37
+ if(topicPattern[i] == "+")
38
+ outputTopicList << receivedTopicList[i];
39
+
40
+ elsif(topicPattern[i] == "#")
41
+ outputTopicList.concat receivedTopicList[i..-1];
42
+ return outputTopicList;
43
+
44
+ elsif topicPattern[i] != receivedTopicList[i];
45
+ return nil;
46
+
47
+ end
48
+ end
49
+
50
+ return outputTopicList if topicPattern.length == receivedTopicList.length;
51
+ return nil;
52
+ end
53
+
54
+ # Call all existing callbacks whose topic-list matches `topic`
55
+ def call_interested(topic, data)
56
+ topicHasReceivers = false;
57
+ @callbackList.each do |h|
58
+ tMatch = BaseHandler.getTopicMatch(topic, h.topic_split);
59
+ if tMatch
60
+ begin
61
+ Timeout.timeout(10) {
62
+ h.offer(tMatch, data)
63
+ }
64
+ rescue Timeout::Error
65
+ x_loge("Timeout on callback #{h}");
66
+ rescue => e
67
+ x_logf("Uncaught error on #{h}");
68
+ x_logf(e.inspect);
69
+ end
70
+ topicHasReceivers = true;
71
+ end
72
+ end
73
+
74
+ @mqtt.unsubscribe(topic) unless topicHasReceivers;
75
+ end
76
+ private :call_interested
77
+
78
+ def queue_packet(data)
79
+ return if @destroying
80
+
81
+ @packetQueueMutex.synchronize {
82
+ @packetQueue << data;
83
+ if(@packetQueue.size == 999)
84
+ x_logf("Packet queue congested, dropping packets!");
85
+ end
86
+ if(@packetQueue.size > 1000)
87
+ @packetQueue.shift
88
+ end
89
+
90
+ @publisherThread.run() if @publisherThreadWaiting;
91
+ }
92
+ end
93
+ private :queue_packet
94
+
95
+ # @!group Custom subscription handling
96
+
97
+ # Unregister a subscription. Removes it from the callback list and
98
+ # unsubscribes from the topic if no other subscriptions for it are present.
99
+ # @param subObject [MQTT::Subscriptions::Subscription]
100
+ # The subscription-object to remove
101
+ # @return void
102
+ def unregister_subscription(subObject)
103
+ raise ArgumentError, "Object is not a subscription!" unless subObject.is_a? MQTT::Subscriptions::Subscription
104
+ return unless @callbackList.include? subObject;
105
+
106
+ queue_packet({type: :unsub, topic: subObject.topic});
107
+ @callbackList.delete(subObject);
108
+ end
109
+ # Register a custom subscription, and send a subscription message to the server.
110
+ # @param subObject [MQTT::Subscriptions::Subscription]
111
+ # An instance of a MQTT Subscription object
112
+ # @return void
113
+ def register_subscription(subObject)
114
+ raise ArgumentError, "Object is not a subscription!" unless subObject.is_a? MQTT::Subscriptions::Subscription
115
+ return if @callbackList.include? subObject;
116
+
117
+ @callbackList << subObject;
118
+ queue_packet({type: :sub, topic: subObject.topic, qos: subObject.qos});
119
+ end
120
+
121
+ # @!endgroup
122
+
123
+ def ensure_clean_start()
124
+ @mqttWasStartedClean = @mqtt.clean_session
125
+ if @mqttWasStartedClean
126
+ begin
127
+ @mqtt.connect();
128
+ @mqtt.disconnect();
129
+ rescue MQTT::Exception
130
+ sleep 1;
131
+ retry
132
+ rescue SocketError, SystemCallError
133
+ sleep 5
134
+ retry
135
+ end
136
+ @mqtt.clean_session=false;
137
+ end
138
+ end
139
+ private :ensure_clean_start
140
+
141
+ def ensure_clean_exit()
142
+ if(@mqttWasStartedClean)
143
+ x_logi("Logging out.")
144
+ begin
145
+ Timeout.timeout(3) {
146
+ begin
147
+ @mqtt.clean_session = true;
148
+ @mqtt.disconnect();
149
+ @mqtt.connect();
150
+ rescue MQTT::Exception, SocketError, SystemCallError
151
+ sleep 0.3
152
+ retry;
153
+ end
154
+ }
155
+ rescue Timeout::Error
156
+ x_loge("Timed out, aborting!");
157
+ else
158
+ x_logi("Done");
159
+ end
160
+ end
161
+ end
162
+ private :ensure_clean_exit
163
+
164
+ def attempt_packet_publish()
165
+ until @packetQueue.empty? do
166
+ h = nil;
167
+ @packetQueueMutex.synchronize {
168
+ h = @packetQueue[0];
169
+ }
170
+ Timeout.timeout(3) {
171
+ if(h[:type] == :sub)
172
+ @mqtt.subscribe(h[:topic] => h[:qos]);
173
+ elsif(h[:type] == :pub)
174
+ @mqtt.publish(h[:topic], h[:data], h[:retain], h[:qos]);
175
+ end
176
+ }
177
+ @packetQueueMutex.synchronize {
178
+ @packetQueue.shift();
179
+ }
180
+ end
181
+ end
182
+
183
+ def mqtt_push_thread
184
+ @push_error_count = 0;
185
+
186
+ loop do
187
+ @packetQueueMutex.synchronize {
188
+ @publisherThreadWaiting = true;
189
+ }
190
+ x_logd("Push thread stopping")
191
+ sleep 1
192
+ x_logd("Push thread active")
193
+ @packetQueueMutex.synchronize {
194
+ @publisherThreadWaiting = false;
195
+ }
196
+ break if @destroying
197
+
198
+ next unless @connected
199
+
200
+ begin
201
+ attempt_packet_publish();
202
+ rescue MQTT::Exception, SocketError, SystemCallError, Timeout::Error => e
203
+ x_loge("Push error!");
204
+ x_loge(e.inspect);
205
+
206
+ @push_error_count += 1;
207
+ if(@push_error_count >= 10)
208
+ @mqtt.disconnect();
209
+ end
210
+
211
+ sleep 0.5
212
+ else
213
+ @push_error_count = 0;
214
+ end
215
+ end
216
+
217
+ x_logd("Push thread exited!");
218
+ end
219
+ private :mqtt_push_thread
220
+
221
+ def mqtt_resub_thread
222
+ loop do
223
+ begin
224
+ return if @destroying
225
+
226
+ x_logw("Trying to reconnect...");
227
+ Timeout.timeout(4) {
228
+ @mqtt.connect()
229
+ }
230
+ x_logi("Connected!");
231
+ @conChangeMutex.synchronize {
232
+ @connected = true;
233
+ @reconnectCount = 0;
234
+ }
235
+
236
+ @packetQueueMutex.synchronize {
237
+ @publisherThread.run() if (@publisherThread && @publisherThreadWaiting)
238
+ }
239
+
240
+ x_logd("Sub thread reading...");
241
+ @mqtt.get do |topic, message|
242
+ call_interested(topic, message);
243
+ end
244
+ rescue MQTT::Exception, Timeout::Error, SocketError, SystemCallError
245
+ x_loge("Disconnected!") if @connected
246
+ @connected = false;
247
+ @reconnectCount += 1;
248
+
249
+ @conChangeMutex.unlock if @conChangeMutex.owned?
250
+ @mqtt.clean_session = false;
251
+ sleep [0.1, 0.5, 1, 1, 5, 5, 5, 10, 10, 10, 10][@reconnectCount] || 30;
252
+ end
253
+ end
254
+
255
+ x_logd("Sub thread exited");
256
+ end
257
+ private :mqtt_resub_thread
258
+
259
+ def destroy!()
260
+ return if @destroying
261
+ @destroying = true;
262
+
263
+ unless @packetQueue.empty?
264
+ x_logd "Finishing sending of MQTT messages ... "
265
+ @publisherThread.run() if @publisherThreadWaiting
266
+ begin
267
+ Timeout.timeout(4) {
268
+ until @packetQueue.empty? do
269
+ sleep 0.05;
270
+ end
271
+ }
272
+ rescue Timeout::Error
273
+ x_logw "Not all messages were published";
274
+ else
275
+ x_logd "Publish clean finished"
276
+ end
277
+ end
278
+
279
+ @publisherThread.run();
280
+ @publisherThread.join();
281
+ @listenerThread.kill();
282
+
283
+ @mqtt.disconnect() if @connected
284
+
285
+ ensure_clean_exit();
286
+
287
+ x_logi("Fully disconnected!");
288
+ end
289
+
290
+ # Initialize a new MQTT::SubHandler
291
+ # The handler immediately connects to the server, and begins receciving and sending.
292
+ # @param mqttClient [String, MQTT::Client] Either a URI to connect to, or a MQTT::Client
293
+ # The URI can be of the form "mqtts://Password@User:URL:port".
294
+ # The MQTT client instance can be fully configured, as specified by the MQTT Gem. It must *not* already be connected!
295
+ # @param jsonify [Boolean] Should Hashes and Arrays input into publish_to be converted to JSON?
296
+ # This can be useful to have one less .to_json call. Default is true.
297
+ # @example Starting the handler
298
+ # mqtt = MQTT::SubHandler.new('mqtt.eclipse.org');
299
+ # mqtt = MQTT::SubHandler.new(MQTT::Client.new("Your.Client.Opts"))
300
+ def initialize(mqttClient, logger: nil, **extra_opts)
301
+ @callbackList = Array.new();
302
+ if mqttClient.is_a? String
303
+ @mqtt = MQTT::Client.new(mqttClient);
304
+ @mqtt.clean_session = false unless extra_opts[:client_id].nil?
305
+ else
306
+ @mqtt = mqttClient;
307
+ end
308
+
309
+ init_x_log("MQTT #{@mqtt.host}", logger);
310
+ self.log_level = Logger::INFO;
311
+
312
+ @conChangeMutex = Mutex.new();
313
+ @connected = false;
314
+ @reconnectCount = 0;
315
+
316
+ @mqtt.client_id ||= extra_opts[:client_id] || MQTT::Client.generate_client_id("MQTT_Sub_", 8);
317
+
318
+ @packetQueue = Array.new();
319
+ @packetQueueMutex = Mutex.new();
320
+
321
+ @publisherThreadWaiting = false;
322
+
323
+ @subscribedTopics = Hash.new();
324
+
325
+ @trackerHash = Hash.new();
326
+
327
+ @listenerThread = Thread.new do
328
+ ensure_clean_start();
329
+ mqtt_resub_thread();
330
+ end
331
+ @listenerThread.abort_on_exception = true;
332
+
333
+ begin
334
+ Timeout.timeout(5) {
335
+ until(@connected)
336
+ sleep 0.1;
337
+ end
338
+ }
339
+ rescue Timeout::Error
340
+ x_loge("Broker did not connect!");
341
+ end
342
+
343
+ @publisherThread = Thread.new do
344
+ mqtt_push_thread();
345
+ end
346
+ @publisherThread.abort_on_exception = true;
347
+
348
+ at_exit {
349
+ destroy!()
350
+ }
351
+ end
352
+ end
353
+ end
@@ -1,129 +1,24 @@
1
1
 
2
- require 'timeout'
3
- require 'mqtt'
4
- require 'json'
5
2
 
6
- require 'colorize'
3
+ require 'json'
7
4
 
8
5
  require_relative 'subscription_classes.rb'
6
+ require_relative 'base_handler.rb'
9
7
 
10
8
  # @author Xasin
11
9
  module MQTT
12
10
  # A shortcut-function to quickly connect to the public Eclipse MQTT Broker.
13
- # @return [MQTT::SubHandler] Sub-Handler connected to `iot.eclipse.org`
11
+ # @return [MQTT::SubHandler] Sub-Handler connected to `mqtt.eclipse.org`
14
12
  def self.Eclipse()
15
- @EclipseMQTT ||= SubHandler.new('iot.eclipse.org');
13
+ @EclipseMQTT ||= SubHandler.new('mqtt.eclipse.org');
16
14
  return @EclipseMQTT;
17
15
  end
18
16
 
19
17
 
20
- class SubHandler
18
+ class SubHandler < BaseHandler
21
19
  # Whether or not hashes and arrays should be converted to JSON when sending
22
20
  attr_accessor :jsonifyHashes
23
21
 
24
- # Split a Topic into a Topic-Array
25
- # @param topicName [String] The string topic which to split
26
- # @return [Array<String>] A list of individual topic-branches
27
- # @note This function is mainly used for background processing.
28
- def self.get_topic_split(topicName)
29
- return topicName.scan(/[^\/]+/);
30
- end
31
-
32
- # Match a topic string to a topic pattern
33
- # @param receivedTopicString [String] The string (as
34
- # returned by MQTT.get) to compare
35
- # @param topicPattern [Array<String>] The Topic-Array (as
36
- # returned by .get_topic_split) to compare against
37
- # @return [nil, Array<String>] Nil if no match was found.
38
- # An Array of matched wildcard topic branches (can be empty) when
39
- # successfully matched
40
- # @note (see .get_topic_split)
41
- def self.getTopicMatch(receivedTopicString, topicPattern)
42
- receivedTopicList = get_topic_split receivedTopicString;
43
-
44
- outputTopicList = Array.new();
45
-
46
- return nil unless receivedTopicList.length >= topicPattern.length;
47
-
48
- topicPattern.each_index do |i|
49
- if(topicPattern[i] == "+")
50
- outputTopicList << receivedTopicList[i];
51
-
52
- elsif(topicPattern[i] == "#")
53
- outputTopicList.concat receivedTopicList[i..-1];
54
- return outputTopicList;
55
-
56
- elsif topicPattern[i] != receivedTopicList[i];
57
- return nil;
58
-
59
- end
60
- end
61
-
62
- return outputTopicList if topicPattern.length == receivedTopicList.length;
63
- return nil;
64
- end
65
-
66
- # Call all existing callbacks whose topic-list matches `topic`
67
- def call_interested(topic, data)
68
- topicHasReceivers = false;
69
- @callbackList.each do |h|
70
- tMatch = SubHandler.getTopicMatch(topic, h.topic_split);
71
- if tMatch
72
- begin
73
- Timeout.timeout(5) {
74
- h.offer(tMatch, data)
75
- }
76
- rescue Timeout::Error
77
- STDERR.puts "MQTT: Callback Timeout #{h}".red
78
- end
79
- topicHasReceivers = true;
80
- end
81
- end
82
-
83
- @mqtt.unsubscribe(topic) unless topicHasReceivers;
84
- end
85
- private :call_interested
86
-
87
- def queue_packet(data)
88
- @packetQueueMutex.synchronize {
89
- @packetQueue << data;
90
- @packetQueue.shift if @packetQueue.size > 100
91
-
92
- @publisherThread.run() if @publisherThreadWaiting;
93
- }
94
- end
95
-
96
- # Handle sending a subscription-message to the server
97
- def raw_subscribe_to(topic, qos: 1)
98
- queue_packet({topic: topic, qos: qos, type: :sub});
99
- end
100
- private :raw_subscribe_to
101
-
102
- # @!group Custom subscription handling
103
-
104
- # Unregister a subscription. Removes it from the callback list and
105
- # unsubscribes from the topic if no other subscriptions for it are present.
106
- # @param subObject [MQTT::Subscriptions::Subscription]
107
- # The subscription-object to remove
108
- # @return void
109
- def unregister_subscription(subObject)
110
- raise ArgumentError, "Object is not a subscription!" unless subObject.is_a? MQTT::Subscriptions::Subscription
111
- return unless @callbackList.include? subObject;
112
-
113
- @callbackList.delete(subObject);
114
- end
115
- # Register a custom subscription, and send a subscription message to the server.
116
- # @param subObject [MQTT::Subscriptions::Subscription]
117
- # An instance of a MQTT Subscription object
118
- # @return void
119
- def register_subscription(subObject)
120
- raise ArgumentError, "Object is not a subscription!" unless subObject.is_a? MQTT::Subscriptions::Subscription
121
- return if @callbackList.include? subObject;
122
-
123
- @callbackList << subObject;
124
- raw_subscribe_to(subObject.topic, qos: subObject.qos);
125
- end
126
-
127
22
  # @!group Subscribing
128
23
 
129
24
  # Synchronously wait for data.
@@ -221,8 +116,7 @@ class SubHandler
221
116
 
222
117
  if(qos > 1)
223
118
  qos = 1
224
- STDERR.puts("MQTT push with QOS > 1 was attempted, this is not supported yet!".yellow) unless $MQTTPubQOSWarned
225
-
119
+ x_logw("push with QOS > 1 was attempted, this is not supported yet!") unless $MQTTPubQOSWarned
226
120
  $MQTTPubQOSWarned = true;
227
121
  end
228
122
 
@@ -230,117 +124,6 @@ class SubHandler
230
124
  end
231
125
  alias publishTo publish_to
232
126
 
233
- def ensure_clean_start()
234
- @mqttWasStartedClean = @mqtt.clean_session
235
- if @mqttWasStartedClean
236
- begin
237
- @mqtt.connect();
238
- @mqtt.disconnect();
239
- rescue MQTT::Exception
240
- sleep 1;
241
- retry
242
- rescue SocketError, SystemCallError
243
- sleep 5
244
- retry
245
- end
246
- @mqtt.clean_session=false;
247
- end
248
- end
249
- private :ensure_clean_start
250
-
251
- def ensure_clean_exit()
252
- if(@mqttWasStartedClean)
253
- print "Logging out of mqtt server... "
254
- begin
255
- Timeout.timeout(3) {
256
- begin
257
- @mqtt.clean_session = true;
258
- @mqtt.disconnect();
259
- @mqtt.connect();
260
- rescue MQTT::Exception, SocketError, SystemCallError
261
- sleep 0.3
262
- retry;
263
- end
264
- }
265
- rescue Timeout::Error
266
- puts "Timed out, aborting!";
267
- else
268
- puts "Done."
269
- end
270
- end
271
- end
272
- private :ensure_clean_exit
273
-
274
- def mqtt_push_thread
275
- loop do
276
- @packetQueueMutex.synchronize {
277
- @publisherThreadWaiting = true;
278
- }
279
- Thread.stop();
280
- @packetQueueMutex.synchronize {
281
- @publisherThreadWaiting = false;
282
- }
283
-
284
- next unless @connected
285
-
286
- begin
287
- until @packetQueue.empty? do
288
- h = nil;
289
- @packetQueueMutex.synchronize {
290
- h = @packetQueue[0];
291
- }
292
- Timeout.timeout(3) {
293
- if(h[:type] == :sub)
294
- @mqtt.subscribe(h[:topic] => h[:qos]);
295
- elsif(h[:type] == :pub)
296
- @mqtt.publish(h[:topic], h[:data], h[:retain], h[:qos]);
297
- end
298
- }
299
- @packetQueueMutex.synchronize {
300
- @packetQueue.shift();
301
- }
302
- end
303
- rescue MQTT::Exception, SocketError, SystemCallError, Timeout::Error => e
304
- STDERR.puts("MQTT: #{@mqtt.host} push error, disconnecting!".red) if @connected
305
- STDERR.puts(e.inspect);
306
-
307
- sleep 1
308
- end
309
- end
310
- end
311
- private :mqtt_push_thread
312
-
313
- def mqtt_resub_thread
314
- loop do
315
- begin
316
- STDERR.puts("MQTT: #{@mqtt.host} trying reconnect...".yellow)
317
- Timeout.timeout(4) {
318
- @mqtt.connect()
319
- }
320
- STDERR.puts("MQTT: #{@mqtt.host} connected!".green)
321
- @conChangeMutex.synchronize {
322
- @connected = true;
323
- }
324
-
325
- @packetQueueMutex.synchronize {
326
- @publisherThread.run() if (@publisherThread && @publisherThreadWaiting)
327
- }
328
-
329
- @mqtt.get do |topic, message|
330
- call_interested(topic, message);
331
- end
332
- rescue MQTT::Exception, Timeout::Error, SocketError, SystemCallError
333
- STDERR.puts("MQTT: #{@mqtt.host} disconnected!".red) if @connected
334
- @connected = false;
335
-
336
- @conChangeMutex.unlock if @conChangeMutex.owned?
337
- @mqtt.clean_session = false;
338
- sleep 2
339
- end
340
- end
341
- end
342
- private :mqtt_resub_thread
343
-
344
127
  # Pause the main thread and wait for messages.
345
128
  # This is mainly useful when the code has set everything up, but doesn't just want to end.
346
129
  # "INT" is trapped, ensuring a smooth exit on Ctrl-C
@@ -349,87 +132,15 @@ class SubHandler
349
132
  exit 0
350
133
  }
351
134
 
352
- puts "Main thread paused."
135
+ x_logi("Main thread paused.")
353
136
  Thread.stop();
354
137
  end
355
- def flush_pubqueue()
356
- unless @packetQueue.empty?
357
- print "Finishing sending of MQTT messages ... "
358
- begin
359
- Timeout.timeout(4) {
360
- until @packetQueue.empty? do
361
- sleep 0.05;
362
- end
363
- }
364
- rescue Timeout::Error
365
- puts "Timed out, aborting."
366
- else
367
- puts "Done."
368
- end
369
- end
370
- end
371
- private :flush_pubqueue
138
+ alias lock_and_listen lockAndListen
372
139
 
373
- # Initialize a new MQTT::SubHandler
374
- # The handler immediately connects to the server, and begins receciving and sending.
375
- # @param mqttClient [String, MQTT::Client] Either a URI to connect to, or a MQTT::Client
376
- # The URI can be of the form "mqtts://Password@User:URL:port".
377
- # The MQTT client instance can be fully configured, as specified by the MQTT Gem. It must *not* already be connected!
378
- # @param jsonify [Boolean] Should Hashes and Arrays input into publish_to be converted to JSON?
379
- # This can be useful to have one less .to_json call. Default is true.
380
- # @example Starting the handler
381
- # mqtt = MQTT::SubHandler.new('iot.eclipse.org');
382
- # mqtt = MQTT::SubHandler.new(MQTT::Client.new("Your.Client.Opts"))
383
- def initialize(mqttClient, jsonify: true)
384
- @callbackList = Array.new();
385
- if mqttClient.is_a? String
386
- @mqtt = MQTT::Client.new(mqttClient);
387
- else
388
- @mqtt = mqttClient;
389
- end
140
+ def initialize(mqttClient, jsonify: true, **extra_opts)
141
+ super(mqttClient, **extra_opts);
390
142
 
391
143
  @jsonifyHashes = jsonify;
392
-
393
- @conChangeMutex = Mutex.new();
394
- @connected = false;
395
-
396
- @mqtt.client_id ||= MQTT::Client.generate_client_id("MQTT_Sub_", 8);
397
-
398
- @packetQueue = Array.new();
399
- @packetQueueMutex = Mutex.new();
400
- @publisherThreadWaiting = false;
401
-
402
- @subscribedTopics = Hash.new();
403
-
404
- @trackerHash = Hash.new();
405
-
406
- @listenerThread = Thread.new do
407
- ensure_clean_start();
408
- mqtt_resub_thread();
409
- end
410
- @listenerThread.abort_on_exception = true;
411
-
412
- begin
413
- Timeout.timeout(5) {
414
- until(@connected)
415
- sleep 0.1;
416
- end
417
- }
418
- rescue Timeout::Error
419
- STDERR.puts "MQTT: #{@mqtt.host} did not connect!".red
420
- end
421
-
422
- @publisherThread = Thread.new do
423
- mqtt_push_thread();
424
- end
425
- @publisherThread.abort_on_exception = true;
426
-
427
- at_exit {
428
- flush_pubqueue();
429
- @connected = false;
430
- @listenerThread.kill();
431
- ensure_clean_exit();
432
- }
433
144
  end
434
145
  end
435
146
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mqtt-sub_handler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6.2
4
+ version: 0.1.6.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xasin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-06 00:00:00.000000000 Z
11
+ date: 2021-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mqtt
@@ -28,30 +28,30 @@ dependencies:
28
28
  name: json
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '2.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '2.2'
41
41
  - !ruby/object:Gem::Dependency
42
- name: colorize
42
+ name: xasin-logger
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '0.1'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '0.1'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: minitest
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -103,6 +103,7 @@ extra_rdoc_files: []
103
103
  files:
104
104
  - README.md
105
105
  - lib/mqtt/Waitpoint.rb
106
+ - lib/mqtt/base_handler.rb
106
107
  - lib/mqtt/mqtt_hash.rb
107
108
  - lib/mqtt/persistence.rb
108
109
  - lib/mqtt/persistence_extensions.rb
@@ -128,7 +129,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
129
  - !ruby/object:Gem::Version
129
130
  version: '0'
130
131
  requirements: []
131
- rubygems_version: 3.0.6
132
+ rubyforge_project:
133
+ rubygems_version: 2.5.2.1
132
134
  signing_key:
133
135
  specification_version: 4
134
136
  summary: Asynchronous, topic-based MQTT gem