@@ -48,7 +48,7 @@ import CBOR from 'cbor-js';
48
48
49
49
import ArduinoCloudError from './ArduinoCloudError' ;
50
50
51
- const connections = { } ;
51
+ let connection = null ;
52
52
const subscribedTopics = { } ;
53
53
const propertyCallback = { } ;
54
54
const arduinoCloudPort = 8443 ;
@@ -82,6 +82,10 @@ const connect = options => new Promise((resolve, reject) => {
82
82
onConnected : options . onConnected ,
83
83
} ;
84
84
85
+ if ( connection ) {
86
+ return reject ( new Error ( 'connection failed: connection already open' ) ) ;
87
+ }
88
+
85
89
if ( ! opts . host ) {
86
90
return reject ( new Error ( 'connection failed: you need to provide a valid host (broker)' ) ) ;
87
91
}
@@ -140,10 +144,8 @@ const connect = options => new Promise((resolve, reject) => {
140
144
if ( reconnect === true ) {
141
145
// This is a re-connection: re-subscribe to all topics subscribed before the
142
146
// connection loss
143
- Object . getOwnPropertySymbols ( subscribedTopics ) . forEach ( ( connectionId ) => {
144
- Object . values ( subscribedTopics [ connectionId ] ) . forEach ( ( subscribeParams ) => {
145
- subscribe ( connectionId , subscribeParams . topic , subscribeParams . cb ) ;
146
- } ) ;
147
+ Object . values ( subscribedTopics ) . forEach ( ( subscribeParams ) => {
148
+ subscribe ( subscribeParams . topic , subscribeParams . cb ) ;
147
149
} ) ;
148
150
}
149
151
@@ -170,9 +172,8 @@ const connect = options => new Promise((resolve, reject) => {
170
172
reconnect : true ,
171
173
keepAliveInterval : 30 ,
172
174
onSuccess : ( ) => {
173
- const id = Symbol ( clientID ) ;
174
- connections [ id ] = client ;
175
- return resolve ( id ) ;
175
+ connection = client ;
176
+ return resolve ( ) ;
176
177
} ,
177
178
onFailure : ( { errorCode, errorMessage } ) => reject (
178
179
new ArduinoCloudError ( errorCode , errorMessage ) ,
@@ -192,20 +193,19 @@ const connect = options => new Promise((resolve, reject) => {
192
193
} , reject ) ;
193
194
} ) ;
194
195
195
- const disconnect = id => new Promise ( ( resolve , reject ) => {
196
- const client = connections [ id ] ;
197
- if ( ! client ) {
198
- return reject ( new Error ( 'disconnection failed: client not found' ) ) ;
196
+ const disconnect = ( ) => new Promise ( ( resolve , reject ) => {
197
+ if ( ! connection ) {
198
+ return reject ( new Error ( 'disconnection failed: connection closed' ) ) ;
199
199
}
200
200
201
201
try {
202
- client . disconnect ( ) ;
202
+ connection . disconnect ( ) ;
203
203
} catch ( error ) {
204
204
return reject ( error ) ;
205
205
}
206
206
207
207
// Remove the connection
208
- delete connections [ id ] ;
208
+ connection = null ;
209
209
210
210
// Remove property callbacks to allow resubscribing in a later connect()
211
211
Object . keys ( propertyCallback ) . forEach ( ( topic ) => {
@@ -215,35 +215,36 @@ const disconnect = id => new Promise((resolve, reject) => {
215
215
} ) ;
216
216
217
217
// Clean up subscribed topics - a new connection might not need the same topics
218
- delete subscribedTopics [ id ] ;
218
+ Object . keys ( subscribedTopics ) . forEach ( ( topic ) => {
219
+ delete subscribedTopics [ topic ] ;
220
+ } ) ;
221
+
219
222
return resolve ( ) ;
220
223
} ) ;
221
224
222
- const subscribe = ( id , topic , cb ) => new Promise ( ( resolve , reject ) => {
223
- const client = connections [ id ] ;
224
- if ( ! client ) {
225
- return reject ( new Error ( 'subscription failed: client not found' ) ) ;
225
+ const subscribe = ( topic , cb ) => new Promise ( ( resolve , reject ) => {
226
+ if ( ! connection ) {
227
+ return reject ( new Error ( 'subscription failed: connection closed' ) ) ;
226
228
}
227
229
228
- return client . subscribe ( topic , {
230
+ return connection . subscribe ( topic , {
229
231
onSuccess : ( ) => {
230
- if ( ! client . topics [ topic ] ) {
231
- client . topics [ topic ] = [ ] ;
232
+ if ( ! connection . topics [ topic ] ) {
233
+ connection . topics [ topic ] = [ ] ;
232
234
}
233
- client . topics [ topic ] . push ( cb ) ;
235
+ connection . topics [ topic ] . push ( cb ) ;
234
236
return resolve ( topic ) ;
235
237
} ,
236
238
onFailure : ( ) => reject ( ) ,
237
239
} ) ;
238
240
} ) ;
239
241
240
- const unsubscribe = ( id , topic ) => new Promise ( ( resolve , reject ) => {
241
- const client = connections [ id ] ;
242
- if ( ! client ) {
243
- return reject ( new Error ( 'disconnection failed: client not found' ) ) ;
242
+ const unsubscribe = topic => new Promise ( ( resolve , reject ) => {
243
+ if ( ! connection ) {
244
+ return reject ( new Error ( 'disconnection failed: connection closed' ) ) ;
244
245
}
245
246
246
- return client . unsubscribe ( topic , {
247
+ return connection . unsubscribe ( topic , {
247
248
onSuccess : ( ) => resolve ( topic ) ,
248
249
onFailure : ( ) => reject ( ) ,
249
250
} ) ;
@@ -260,32 +261,31 @@ const arrayBufferToBase64 = (buffer) => {
260
261
return window . btoa ( binary ) ;
261
262
} ;
262
263
263
- const sendMessage = ( id , topic , message ) => new Promise ( ( resolve , reject ) => {
264
- const client = connections [ id ] ;
265
- if ( ! client ) {
266
- return reject ( new Error ( 'disconnection failed: client not found' ) ) ;
264
+ const sendMessage = ( topic , message ) => new Promise ( ( resolve , reject ) => {
265
+ if ( ! connection ) {
266
+ return reject ( new Error ( 'disconnection failed: connection closed' ) ) ;
267
267
}
268
268
269
- client . publish ( topic , message , 1 , false ) ;
269
+ connection . publish ( topic , message , 1 , false ) ;
270
270
return resolve ( ) ;
271
271
} ) ;
272
272
273
- const openCloudMonitor = ( id , deviceId , cb ) => {
273
+ const openCloudMonitor = ( deviceId , cb ) => {
274
274
const cloudMonitorOutputTopic = `/a/d/${ deviceId } /s/o` ;
275
- return subscribe ( id , cloudMonitorOutputTopic , cb ) ;
275
+ return subscribe ( cloudMonitorOutputTopic , cb ) ;
276
276
} ;
277
277
278
- const writeCloudMonitor = ( id , deviceId , message ) => {
278
+ const writeCloudMonitor = ( deviceId , message ) => {
279
279
const cloudMonitorInputTopic = `/a/d/${ deviceId } /s/i` ;
280
- return sendMessage ( id , cloudMonitorInputTopic , message ) ;
280
+ return sendMessage ( cloudMonitorInputTopic , message ) ;
281
281
} ;
282
282
283
- const closeCloudMonitor = ( id , deviceId ) => {
283
+ const closeCloudMonitor = ( deviceId ) => {
284
284
const cloudMonitorOutputTopic = `/a/d/${ deviceId } /s/o` ;
285
- return unsubscribe ( id , cloudMonitorOutputTopic ) ;
285
+ return unsubscribe ( cloudMonitorOutputTopic ) ;
286
286
} ;
287
287
288
- const sendProperty = ( connectionId , thingId , name , value , timestamp ) => {
288
+ const sendProperty = ( thingId , name , value , timestamp ) => {
289
289
const propertyInputTopic = `/a/t/${ thingId } /e/i` ;
290
290
291
291
if ( timestamp && ! Number . isInteger ( timestamp ) ) {
@@ -315,7 +315,7 @@ const sendProperty = (connectionId, thingId, name, value, timestamp) => {
315
315
break ;
316
316
}
317
317
318
- return sendMessage ( connectionId , propertyInputTopic , CBOR . encode ( [ cborValue ] ) ) ;
318
+ return sendMessage ( propertyInputTopic , CBOR . encode ( [ cborValue ] ) ) ;
319
319
} ;
320
320
321
321
const getSenml = ( deviceId , name , value , timestamp ) => {
@@ -357,7 +357,7 @@ const getCborValue = (senMl) => {
357
357
return arrayBufferToBase64 ( cborEncoded ) ;
358
358
} ;
359
359
360
- const sendPropertyAsDevice = ( connectionId , deviceId , thingId , name , value , timestamp ) => {
360
+ const sendPropertyAsDevice = ( deviceId , thingId , name , value , timestamp ) => {
361
361
const propertyInputTopic = `/a/t/${ thingId } /e/o` ;
362
362
363
363
if ( timestamp && ! Number . isInteger ( timestamp ) ) {
@@ -369,10 +369,10 @@ const sendPropertyAsDevice = (connectionId, deviceId, thingId, name, value, time
369
369
}
370
370
371
371
const senMlValue = getSenml ( deviceId , name , value , timestamp ) ;
372
- return sendMessage ( connectionId , propertyInputTopic , CBOR . encode ( [ senMlValue ] ) ) ;
372
+ return sendMessage ( propertyInputTopic , CBOR . encode ( [ senMlValue ] ) ) ;
373
373
} ;
374
374
375
- const onPropertyValue = ( connectionId , thingId , name , cb ) => {
375
+ const onPropertyValue = ( thingId , name , cb ) => {
376
376
if ( ! name ) {
377
377
throw new Error ( 'Invalid property name' ) ;
378
378
}
@@ -381,19 +381,15 @@ const onPropertyValue = (connectionId, thingId, name, cb) => {
381
381
}
382
382
const propOutputTopic = `/a/t/${ thingId } /e/o` ;
383
383
384
- if ( ! subscribedTopics [ connectionId ] ) {
385
- subscribedTopics [ connectionId ] = { } ;
386
- }
387
-
388
- subscribedTopics [ connectionId ] [ thingId ] = {
384
+ subscribedTopics [ thingId ] = {
389
385
topic : propOutputTopic ,
390
386
cb,
391
387
} ;
392
388
393
389
if ( ! propertyCallback [ propOutputTopic ] ) {
394
390
propertyCallback [ propOutputTopic ] = { } ;
395
391
propertyCallback [ propOutputTopic ] [ name ] = cb ;
396
- subscribe ( connectionId , propOutputTopic , cb ) ;
392
+ subscribe ( propOutputTopic , cb ) ;
397
393
} else if ( propertyCallback [ propOutputTopic ] && ! propertyCallback [ propOutputTopic ] [ name ] ) {
398
394
propertyCallback [ propOutputTopic ] [ name ] = cb ;
399
395
}
0 commit comments