mqtt-sub_handler 0.1.6 → 0.1.6.8

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: 22d57768280da99134fc12c1ab6d07b441df823f59992d88411a1bc8b88cfe16
4
- data.tar.gz: 34ead01f1186b52591969071404c2812badd339e17a404178b44295d6d6ed8e8
2
+ SHA1:
3
+ metadata.gz: 9be8cc94d063f20f4e602ca44c33e1f063fcd8db
4
+ data.tar.gz: b115b3aa01cdb8aceab2ba442d1e8748c25ce3e1
5
5
  SHA512:
6
- metadata.gz: 11569eef332d8d8c186b6c246bfd32bea0643270152e27c06b1e92e560c93a091809a2994c3424fd36ed9e0d2898defcc8f45e7e57da3879a276e837d6e2b663
7
- data.tar.gz: a1d962a3af87a942f45af28540b5902903cf0e37a569d7b174793dd471183c8337fc95f1bd4f0a06a9b9997cb04da78e60ed663be399968bddced5e641ad0aad
6
+ metadata.gz: 18305fa0dbabdaea4762c0b53adec091bd0db67f06ef23aca414ab136ccc35e50c26641f5d21cd6d70554a6b213f87295b23ceaab1f07d9ff04f0e17fef53770
7
+ data.tar.gz: 8b1aa38aad47777c42538ef19d17db3cf9cd49259d177863664d8ae561406d0691a7e80b774e1f6dd5f6d09d8ce6c8bda7a23a933a2f68b593e29daf857aa7fe
@@ -0,0 +1,355 @@
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;
305
+
306
+ @mqttWasStartedClean = true if extra_opts[:client_id].nil?
307
+ else
308
+ @mqtt = mqttClient;
309
+ end
310
+
311
+ init_x_log("MQTT #{@mqtt.host}", logger);
312
+ self.log_level = Logger::INFO;
313
+
314
+ @conChangeMutex = Mutex.new();
315
+ @connected = false;
316
+ @reconnectCount = 0;
317
+
318
+ @mqtt.client_id ||= extra_opts[:client_id] || MQTT::Client.generate_client_id("MQTT_Sub_", 8);
319
+
320
+ @packetQueue = Array.new();
321
+ @packetQueueMutex = Mutex.new();
322
+
323
+ @publisherThreadWaiting = false;
324
+
325
+ @subscribedTopics = Hash.new();
326
+
327
+ @trackerHash = Hash.new();
328
+
329
+ @listenerThread = Thread.new do
330
+ ensure_clean_start();
331
+ mqtt_resub_thread();
332
+ end
333
+ @listenerThread.abort_on_exception = true;
334
+
335
+ begin
336
+ Timeout.timeout(5) {
337
+ until(@connected)
338
+ sleep 0.1;
339
+ end
340
+ }
341
+ rescue Timeout::Error
342
+ x_loge("Broker did not connect!");
343
+ end
344
+
345
+ @publisherThread = Thread.new do
346
+ mqtt_push_thread();
347
+ end
348
+ @publisherThread.abort_on_exception = true;
349
+
350
+ at_exit {
351
+ destroy!()
352
+ }
353
+ end
354
+ end
355
+ end
@@ -1,121 +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}"
78
- end
79
- topicHasReceivers = true;
80
- end
81
- end
82
-
83
- @mqtt.unsubscribe(topic) unless topicHasReceivers;
84
- end
85
- private :call_interested
86
-
87
- # Handle sending a subscription-message to the server
88
- def raw_subscribe_to(topic, qos: 1)
89
- @subscribeQueue << [topic, qos];
90
- @publisherThread.run();
91
- end
92
- private :raw_subscribe_to
93
-
94
- # @!group Custom subscription handling
95
-
96
- # Unregister a subscription. Removes it from the callback list and
97
- # unsubscribes from the topic if no other subscriptions for it are present.
98
- # @param subObject [MQTT::Subscriptions::Subscription]
99
- # The subscription-object to remove
100
- # @return void
101
- def unregister_subscription(subObject)
102
- raise ArgumentError, "Object is not a subscription!" unless subObject.is_a? MQTT::Subscriptions::Subscription
103
- return unless @callbackList.include? subObject;
104
-
105
- @callbackList.delete(subObject);
106
- end
107
- # Register a custom subscription, and send a subscription message to the server.
108
- # @param subObject [MQTT::Subscriptions::Subscription]
109
- # An instance of a MQTT Subscription object
110
- # @return void
111
- def register_subscription(subObject)
112
- raise ArgumentError, "Object is not a subscription!" unless subObject.is_a? MQTT::Subscriptions::Subscription
113
- return if @callbackList.include? subObject;
114
-
115
- @callbackList << subObject;
116
- raw_subscribe_to(subObject.topic, qos: subObject.qos);
117
- end
118
-
119
22
  # @!group Subscribing
120
23
 
121
24
  # Synchronously wait for data.
@@ -211,110 +114,15 @@ class SubHandler
211
114
  data = data.to_json
212
115
  end
213
116
 
214
- @publishQueue << {topic: topic, data: data, qos: qos, retain: retain}
215
- @publisherThread.run();
216
- end
217
- alias publishTo publish_to
218
-
219
- def ensure_clean_start()
220
- @mqttWasStartedClean = @mqtt.clean_session
221
- if @mqttWasStartedClean
222
- begin
223
- @mqtt.connect();
224
- @mqtt.disconnect();
225
- rescue MQTT::Exception
226
- sleep 1;
227
- retry
228
- rescue SocketError, SystemCallError
229
- sleep 5
230
- retry
231
- end
232
- @mqtt.clean_session=false;
117
+ if(qos > 1)
118
+ qos = 1
119
+ x_logw("push with QOS > 1 was attempted, this is not supported yet!") unless $MQTTPubQOSWarned
120
+ $MQTTPubQOSWarned = true;
233
121
  end
234
- end
235
- private :ensure_clean_start
236
122
 
237
- def ensure_clean_exit()
238
- if(@mqttWasStartedClean)
239
- print "Logging out of mqtt server... "
240
- begin
241
- Timeout.timeout(3) {
242
- begin
243
- @mqtt.clean_session = true;
244
- @mqtt.disconnect();
245
- @mqtt.connect();
246
- rescue MQTT::Exception, SocketError, SystemCallError
247
- sleep 0.3
248
- retry;
249
- end
250
- }
251
- rescue Timeout::Error
252
- puts "Timed out, aborting!";
253
- else
254
- puts "Done."
255
- end
256
- end
257
- end
258
- private :ensure_clean_exit
259
-
260
- def mqtt_push_thread
261
- loop do
262
- Thread.stop();
263
-
264
- next unless @connected
265
-
266
- begin
267
- until @subscribeQueue.empty? do
268
- h = @subscribeQueue[-1];
269
- Timeout.timeout(3) {
270
- @mqtt.subscribe(h[0] => h[1]);
271
- }
272
- @subscribeQueue.pop;
273
- sleep 0.01
274
- end
275
- until @publishQueue.empty? do
276
- h = @publishQueue[-1];
277
- Timeout.timeout(3) {
278
- @mqtt.publish(h[:topic], h[:data], h[:retain], h[:qos]);
279
- }
280
- @publishQueue.pop;
281
- sleep 0.01
282
- end
283
- rescue MQTT::Exception, SocketError, SystemCallError, Timeout::Error
284
- @conChangeMutex.synchronize {
285
- @connected = false;
286
- }
287
- @mqtt.disconnect();
288
- end
289
- end
123
+ queue_packet({type: :pub, topic: topic, data: data, qos: qos, retain: retain});
290
124
  end
291
- private :mqtt_push_thread
292
-
293
- def mqtt_resub_thread
294
- while(true)
295
- begin
296
- Timeout.timeout(4) {
297
- @mqtt.connect()
298
- }
299
- STDERR.puts("MQTT: #{@mqtt.host} connected!".green)
300
- @conChangeMutex.synchronize {
301
- @connected = true;
302
- }
303
- @publisherThread.run();
304
- @mqtt.get do |topic, message|
305
- call_interested(topic, message);
306
- end
307
- rescue MQTT::Exception, Timeout::Error, SocketError, SystemCallError
308
- STDERR.puts("MQTT #{@mqtt.host} disconnected!".red);
309
- @connected = false;
310
-
311
- @conChangeMutex.unlock if @conChangeMutex.owned?
312
- @mqtt.clean_session = false;
313
- sleep 2
314
- end
315
- end
316
- end
317
- private :mqtt_resub_thread
125
+ alias publishTo publish_to
318
126
 
319
127
  # Pause the main thread and wait for messages.
320
128
  # This is mainly useful when the code has set everything up, but doesn't just want to end.
@@ -324,85 +132,15 @@ class SubHandler
324
132
  exit 0
325
133
  }
326
134
 
327
- puts "Main thread paused."
135
+ x_logi("Main thread paused.")
328
136
  Thread.stop();
329
137
  end
330
- def flush_pubqueue()
331
- unless @publishQueue.empty?
332
- print "Finishing sending of MQTT messages ... "
333
- begin
334
- Timeout.timeout(4) {
335
- until @publishQueue.empty? do
336
- sleep 0.05;
337
- end
338
- }
339
- rescue Timeout::Error
340
- puts "Timed out, aborting."
341
- else
342
- puts "Done."
343
- end
344
- end
345
- end
346
- private :flush_pubqueue
138
+ alias lock_and_listen lockAndListen
347
139
 
348
- # Initialize a new MQTT::SubHandler
349
- # The handler immediately connects to the server, and begins receciving and sending.
350
- # @param mqttClient [String, MQTT::Client] Either a URI to connect to, or a MQTT::Client
351
- # The URI can be of the form "mqtts://Password@User:URL:port".
352
- # The MQTT client instance can be fully configured, as specified by the MQTT Gem. It must *not* already be connected!
353
- # @param jsonify [Boolean] Should Hashes and Arrays input into publish_to be converted to JSON?
354
- # This can be useful to have one less .to_json call. Default is true.
355
- # @example Starting the handler
356
- # mqtt = MQTT::SubHandler.new('iot.eclipse.org');
357
- # mqtt = MQTT::SubHandler.new(MQTT::Client.new("Your.Client.Opts"))
358
140
  def initialize(mqttClient, jsonify: true)
359
- @callbackList = Array.new();
360
- if mqttClient.is_a? String
361
- @mqtt = MQTT::Client.new(mqttClient);
362
- else
363
- @mqtt = mqttClient;
364
- end
141
+ super(mqttClient);
365
142
 
366
143
  @jsonifyHashes = jsonify;
367
-
368
- @conChangeMutex = Mutex.new();
369
- @connected = false;
370
-
371
- @mqtt.client_id ||= MQTT::Client.generate_client_id("MQTT_Sub_", 8);
372
-
373
- @publishQueue = Array.new();
374
- @subscribeQueue = Array.new();
375
- @subscribedTopics = Hash.new();
376
-
377
- @trackerHash = Hash.new();
378
-
379
- @listenerThread = Thread.new do
380
- ensure_clean_start();
381
- mqtt_resub_thread();
382
- end
383
- @listenerThread.abort_on_exception = true;
384
-
385
- @publisherThread = Thread.new do
386
- mqtt_push_thread();
387
- end
388
- @publisherThread.abort_on_exception = true;
389
-
390
- begin
391
- Timeout.timeout(3) {
392
- until(@connected)
393
- sleep 0.1;
394
- end
395
- }
396
- rescue Timeout::Error
397
- STDERR.puts "MQTT: #{@mqtt.host} did not connect!".red
398
- end
399
-
400
- at_exit {
401
- flush_pubqueue();
402
- @listenerThread.kill();
403
- @publisherThread.kill();
404
- ensure_clean_exit();
405
- }
406
144
  end
407
145
  end
408
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
4
+ version: 0.1.6.8
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