@reactoo/watchtogether-sdk-js 2.7.96 → 2.7.98

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.
@@ -10,6 +10,7 @@
10
10
  <div class="content">
11
11
  <video id="thevideo" class="contentVideo" autoplay playsinline controls style="width: 400px" muted="muted" src="https://assetcdn.reactoo.com/watfordFc/Norwich_2010_B_roll_2min16_mute.mp4"></video>
12
12
  <div>
13
+ <button onclick="window.connectRoom()">Connect</button>
13
14
  <button onclick="window.startRoom()">Connect and publish</button>
14
15
  <button onclick="window.startRoom2()">Connect and publish with screen share</button>
15
16
  <button onclick="window.startRoom3()">Connect and publish with blank screen</button>
@@ -31,15 +32,31 @@
31
32
  <script type="module">
32
33
  import WatchTogetherSDK from '../dist/watchtogether-sdk.js';
33
34
 
35
+ function getQueryVar(varName){
36
+ const queryStr = decodeURI(window.location.search) + '&';
37
+ const regex = new RegExp('.*?[&\\?]' + varName + '=(.*?)&.*');
38
+ const val = queryStr.replace(regex, "$1");
39
+ return val === queryStr ? null : val;
40
+ }
41
+
34
42
  //https://studio.reactoo.com/room/edf441b3-7415-49c4-9557-273cb93bc746/LJj4W2Cz-nG3U-lb0R-TAaY-o7Thmb8xHSbE
35
43
 
36
44
  let roomId = "5703bcd6-a11e-4a73-bd14-12ed57227a8c"; // It will create room automatically if not set
37
45
  let pinHash = null;
46
+ let role = getQueryVar("role") || 'participant';
47
+
48
+ console.log('role', role);
38
49
 
39
50
  let participants = document.querySelector('.participants');
40
51
  var video = document.querySelector('.contentVideo');
41
52
  let constructId = 'test';
42
53
 
54
+ let sanitizeId = function (id) {
55
+ // remove ":,"
56
+ return id.replace(/[:]/g, '_').replace(/[,]/g, '_');
57
+ }
58
+
59
+
43
60
  // if(Hls.isSupported()) {
44
61
  // var hls = new Hls();
45
62
  // hls.loadSource('https://assetcdn.reactoo.com/watfordFc/Norwich_2010_B_roll_2min16_mute.mp4');
@@ -49,13 +66,6 @@
49
66
  // });
50
67
  // }
51
68
 
52
- function selectSubStream(handleId, substream, source) {
53
- return Instance.room.getSessionByConstructId(constructId).selectSubStream(handleId, substream, source);
54
- }
55
-
56
- function overrideSimulcastSettings(handleId, mid, source, settings) {
57
- return Instance.room.getSessionByConstructId(constructId).overrideSimulcastSettings(handleId, mid, source, settings);
58
- }
59
69
 
60
70
  function hento() {
61
71
  //Instance.system.getSettings();
@@ -72,17 +82,13 @@
72
82
 
73
83
  removeParticipant({id: data.id})
74
84
 
75
- if(!data.stream) {
76
- console.log('no stream for participant');
77
- return;
78
- }
79
-
85
+ const sid = sanitizeId(data.id)
80
86
  for(let key in data.streamMap) {
81
- let tracks = data.stream.getTracks().filter(t => data['streamMap'][key].includes(t.id));
87
+ let tracks = data.tracks.filter(t => data['streamMap'][key].includes(t.id));
82
88
  if(tracks.length) {
83
89
  let stream = new MediaStream();
84
90
  tracks.forEach(t => stream.addTrack(t));
85
- let id = `_p${data.id} part_${data.id}_${key}`;
91
+ let id = `_p${sid} part_${sid}_${key}`;
86
92
  let el = document.createElement("video");
87
93
  el.autoplay = true;
88
94
  el.playsInline = true;
@@ -100,7 +106,10 @@
100
106
  }
101
107
 
102
108
  function removeParticipant(data) {
103
- let id = `_p${data.id}`;
109
+
110
+ console.log('removing participant - participantData', data);
111
+
112
+ let id = `_p${sanitizeId(data.id)}`;
104
113
  let els = document.querySelectorAll(`.${id}`);
105
114
  console.log(id,els);
106
115
  els.length && els.forEach(el => el.parentNode.removeChild(el));
@@ -110,6 +119,10 @@
110
119
  Instance.room.getSessionByConstructId(constructId).disconnect()
111
120
  }
112
121
 
122
+ function connectRoom() {
123
+ Instance.room.getSessionByConstructId(constructId).connect()
124
+ }
125
+
113
126
  function startRoom() {
114
127
  let sess = Instance.room.getSessionByConstructId(constructId);
115
128
  sess.connect()
@@ -173,17 +186,6 @@
173
186
  Instance.room.getSessionByConstructId(constructId).toggleAudio()
174
187
  }
175
188
 
176
- function setListenIntercomChannels(groups) {
177
- Instance.room.getSessionByConstructId(constructId).setListenIntercomChannels(groups)
178
- }
179
-
180
- function setTalkIntercomChannels(groups) {
181
- Instance.room.getSessionByConstructId(constructId).setTalkIntercomChannels(groups)
182
- }
183
-
184
- function setRestrictSubscribeToUserIds(userIds) {
185
- Instance.room.getSessionByConstructId(constructId).setRestrictSubscribeToUserIds(userIds)
186
- }
187
189
 
188
190
  function iotLogout() {
189
191
  return Instance.iot.iotLogout()
@@ -248,7 +250,7 @@
248
250
  return r.data;
249
251
  })
250
252
  })
251
- .then(r => Instance.room.createSession({constructId, roomId:r.roomId, pinHash: r.pinHash, role:'participant', options: {
253
+ .then(r => Instance.room.createSession({constructId, roomId:r.roomId, pinHash: r.pinHash, role:role, options: {
252
254
  // simulcast: true,
253
255
  // simulcastSettings: {
254
256
  // "default" : {
@@ -361,8 +363,8 @@
361
363
  console.log('joined', status); // joined room
362
364
  });
363
365
 
364
- session.$on('published', ({status, hasStream}) => {
365
- console.log('published', status, hasStream); // published yourself (either with stream or dataChannel only, you're now able to sync the player)
366
+ session.$on('published', (status) => {
367
+ console.log('published', status); // published yourself (either with stream or dataChannel only, you're now able to sync the player)
366
368
  });
367
369
 
368
370
  session.$on('publishing', status => {
@@ -389,6 +391,14 @@
389
391
  removeParticipant(participant, true); // remote participant is gone
390
392
  });
391
393
 
394
+ session.$on('addRemoteObserver', (participant) => {
395
+ createParticipant(participant, true); // remote participant is available or updated
396
+ });
397
+
398
+ session.$on('removeRemoteObserver', (participant) => {
399
+ removeParticipant(participant, true); // remote participant is gone
400
+ });
401
+
392
402
  session.$on('userUpdate', (userId) => {
393
403
  console.log('userUpdate', userId); // User "${userId}" updated it's profile, we might do a get request to see what've changed
394
404
  });
@@ -455,6 +465,9 @@
455
465
 
456
466
  });
457
467
 
468
+ window.connectRoom = function () {
469
+ Instance.room.getSessionByConstructId(constructId).connect()
470
+ }
458
471
  // Make functions globally accessible
459
472
  window.startRoom = function() {
460
473
  let sess = Instance.room.getSessionByConstructId(constructId);
@@ -529,16 +542,36 @@
529
542
  }
530
543
 
531
544
  window.asset = function () {
532
- const test = Instance.asset.getAssetList({ ids: ['6304b890-321a-494b-b0e6-b0cee48026cd'], instanceType: 'reactooBackup', type:'ids'})
545
+ Instance.asset.getAssetList({ ids: ['6304b890-321a-494b-b0e6-b0cee48026cd'], instanceType: 'reactooBackup', type:'ids'})
533
546
  .then(r => {
534
547
  console.log(r);
535
- return r;
536
548
  })
537
- test.then(r => {
538
- console.log(r);
539
- })
540
549
  }
541
550
 
551
+ window.selectSubstream = function (id, substream, source) {
552
+ let sess = Instance.room.getSessionByConstructId(constructId);
553
+ sess.selectSubStream(id, substream, source)
554
+ .then((r) => {
555
+ console.log('substream selected', r);
556
+ })
557
+ .catch(e => {
558
+ console.log('substream select error', e);
559
+ })
560
+ }
561
+
562
+ window.setListenIntercomChannels = function(groups) {
563
+ Instance.room.getSessionByConstructId(constructId).setListenIntercomChannels(groups)
564
+ }
565
+
566
+ window.setTalkIntercomChannels = function(groups) {
567
+ Instance.room.getSessionByConstructId(constructId).setTalkIntercomChannels(groups)
568
+ }
569
+
570
+ window.setRestrictSubscribeToUserIds = function(userIds) {
571
+ Instance.room.getSessionByConstructId(constructId).setRestrictSubscribeToUserIds(userIds)
572
+ }
573
+
574
+
542
575
  </script>
543
576
 
544
577
  </body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactoo/watchtogether-sdk-js",
3
- "version": "2.7.96",
3
+ "version": "2.7.98",
4
4
  "description": "Javascript SDK for Reactoo",
5
5
  "main": "dist/watchtogether-sdk.min.js",
6
6
  "module": "dist/watchtogether-sdk.min.js",
@@ -36,6 +36,7 @@
36
36
  "@babel/plugin-proposal-class-properties": "^7.18.6",
37
37
  "@babel/plugin-proposal-optional-chaining": "^7.21.0",
38
38
  "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
39
+ "@babel/plugin-transform-private-methods": "^7.25.9",
39
40
  "@babel/preset-env": "^7.22.10",
40
41
  "babel-loader": "^9.1.3",
41
42
  "buffer": "^6.0.3",
@@ -66,8 +66,7 @@ let asset = function() {
66
66
  if (onProgress && xhr.upload) {
67
67
  xhr.upload.onprogress = (event) => {
68
68
  if (event.lengthComputable) {
69
- const percentComplete = (event.loaded / event.total) * 100;
70
- onProgress(percentComplete, event.loaded, event.total);
69
+ onProgress(event.loaded, event.total);
71
70
  }
72
71
  };
73
72
  }
@@ -106,6 +105,11 @@ let asset = function() {
106
105
  downloadAsset: (url, options = {}) => {
107
106
  return this.__privates.auth.__client
108
107
  .then(client => client.http({url, method: 'GET', ...options}))
108
+ },
109
+
110
+ createStreamAsset: (id, title, streamType, regionalPreference, ingestType, source, profile) => {
111
+ return this.__privates.auth.__client
112
+ .then(client => client.apis.asset.publishAsset({id}, {requestBody: {assetType: 'stream', title, stream: {streamType, regionalPreference, ingestType, source, profile}}}));
109
113
  }
110
114
  }
111
115
  };
@@ -47,6 +47,10 @@ let roomSession = function ({roomId, pinHash, role, options = {}}, room, wt) {
47
47
  }, 2000);
48
48
  });
49
49
 
50
+ room.on('requestMuteStatus', () => {
51
+ ___.__requestMuteStatus();
52
+ });
53
+
50
54
  room.on('localMuted', ({type, value, source, mid}) => {
51
55
  ___.sendSystemMessage('remote_muted', {type, value, source, mid})
52
56
  });
@@ -105,12 +109,18 @@ let roomSession = function ({roomId, pinHash, role, options = {}}, room, wt) {
105
109
  role
106
110
  }, abortController?.signal)
107
111
  .then(roomData => {
112
+
108
113
  // Happens when we reroute user to a different room
109
114
  if(roomData?.data?.reactooRoomId !== roomId) {
110
115
  roomId = roomData.data.reactooRoomId;
111
116
  emitter.emit('changeRoomId', roomId);
112
117
  }
118
+
113
119
  room.setRoomType(roomData.data.roomType);
120
+
121
+ const roomSettingSimulcastEnabled = !!roomData?.data?.simulcast;
122
+ const roomSettingSimulcastConfig = roomData?.data?.simulcast||{};
123
+
114
124
  return room.connect(
115
125
  roomData.data.roomId,
116
126
  roomData.data.pin,
@@ -123,8 +133,8 @@ let roomSession = function ({roomId, pinHash, role, options = {}}, room, wt) {
123
133
  roomData.data.webrtcVersion,
124
134
  (roomData.data.bitrate ? parseInt(roomData.data.bitrate) : 0),
125
135
  roomData.data.recordingFilename,
126
- simulcast !== null ? simulcast : !!roomData?.data?.simulcast,
127
- simulcastSettings !== null ? simulcastSettings : roomData?.data?.simulcast,
136
+ simulcast !== null ? simulcast : roomSettingSimulcastEnabled,
137
+ simulcastSettings !== null ? simulcastSettings : roomSettingSimulcastConfig,
128
138
  enableDtx !== null ? enableDtx : roomData?.data?.enableDtx,
129
139
  )
130
140
  })
@@ -373,8 +383,8 @@ let roomSession = function ({roomId, pinHash, role, options = {}}, room, wt) {
373
383
  return room.requestKeyFrame(handleId, mid);
374
384
  },
375
385
 
376
- selectSubStream: (handleId, substream, source, mid) => {
377
- return room.selectSubStream(handleId, substream, source, mid, true);
386
+ selectSubStream: (id, substream, source, mid) => {
387
+ return room.selectSubStream(id, substream, source, mid, true);
378
388
  },
379
389
 
380
390
  setBitrateCap: (bitrate) => {
@@ -389,9 +399,6 @@ let roomSession = function ({roomId, pinHash, role, options = {}}, room, wt) {
389
399
  }).catch(() => null)
390
400
  },
391
401
 
392
- overrideSimulcastSettings: (handleId, mid, source, settings) => {
393
- return room.overrideSimulcastSettings(handleId, mid, source, settings);
394
- },
395
402
 
396
403
  sendSystemMessage: (action, value = {}, to, set_master) => {
397
404
  return room.sendMessage(room.handleId, {
@@ -1,7 +1,7 @@
1
1
  import { mqtt5, iot } from 'aws-iot-device-sdk-v2';
2
2
  console.log('Worker: Starting up');
3
3
 
4
- let connection = null;
4
+ let client = null;
5
5
  let currentConnectionId = 1;
6
6
 
7
7
  self.onmessage = function(event) {
@@ -37,29 +37,29 @@ function connect(params, stamp) {
37
37
  console.log('Worker: Attempting to connect');
38
38
  const { apiMqttUrl, apiMqttClientId, region, accessKeyId, secretAccessKey, sessionToken } = params;
39
39
 
40
- const configBuilder = iot.AwsIotMqttConnectionConfigBuilder.new_with_websockets();
40
+ const configBuilder = iot.AwsIotMqtt5ClientConfigBuilder.new_with_websockets();
41
41
 
42
42
  configBuilder.with_clean_session(true);
43
43
  configBuilder.with_client_id(apiMqttClientId);
44
44
  configBuilder.with_endpoint(apiMqttUrl);
45
45
  configBuilder.with_credentials(region, accessKeyId, secretAccessKey, sessionToken);
46
- configBuilder.with_keep_alive_seconds(30);
47
46
  configBuilder.with_ping_timeout_ms(3000);
48
- configBuilder.with_reconnect_max_sec(5);
49
- configBuilder.with_reconnect_min_sec(1);
47
+ configBuilder.with_connect_properties({
48
+ keepAliveIntervalSeconds: 30,
49
+ sessionExpiryIntervalSeconds: 300
50
+ });
50
51
 
51
52
  const config = configBuilder.build();
52
- const client = new mqtt5.MqttClient(); // Use MQTT 5.0 client
53
53
 
54
- connection = client.new_connection(config);
54
+ // MQTT5 uses a single client instance
55
+ client = new mqtt5.Mqtt5Client(config);
55
56
  currentConnectionId++;
56
57
 
57
58
  setupConnectionListeners(currentConnectionId);
58
59
 
59
- connection.connect()
60
+ client.start()
60
61
  .then(() => {
61
62
  console.log('Worker: Connection successful');
62
- connection.start(); // Start the client to maintain connectivity
63
63
  self.postMessage({ type: 'connect_result', data: {success: true, connectionId: currentConnectionId, stamp} });
64
64
  })
65
65
  .catch((error) => {
@@ -69,38 +69,42 @@ function connect(params, stamp) {
69
69
  }
70
70
 
71
71
  function disconnect(stamp) {
72
- if (connection) {
72
+ if (client) {
73
73
  const connectionId = currentConnectionId;
74
- connection.stop(); // Stop the client before disconnecting
75
- connection.disconnect()
74
+ client.stop()
76
75
  .then(() => {
77
- if (connectionId !== currentConnectionId) {
76
+ if(connectionId !== currentConnectionId) {
78
77
  console.log('Worker: Connection Id mismatch, ignoring disconnect result', connectionId, currentConnectionId);
79
78
  return;
80
79
  }
81
80
  self.postMessage({ type: 'disconnect_result', data: {success: true, stamp} });
82
81
  })
83
82
  .catch((error) => {
84
- if (connectionId !== currentConnectionId) {
83
+ if(connectionId !== currentConnectionId) {
85
84
  console.log('Worker: Connection Id mismatch, ignoring disconnect result', connectionId, currentConnectionId);
86
85
  return;
87
86
  }
88
87
  self.postMessage({ type: 'disconnect_result', data: { success: false, error: error.message, stamp} });
89
88
  });
90
- connection = null;
89
+ client = null;
91
90
  } else {
92
91
  self.postMessage({ type: 'disconnect_result', data: {success: true, stamp} });
93
92
  }
94
93
  }
95
94
 
96
95
  function isConnected() {
97
- const connected = connection && connection.currentState === 0 && connection.desiredState === 0;
96
+ const connected = client && client.getIsConnected();
98
97
  self.postMessage({ type: 'is_connected_result', data:{connected} });
99
98
  }
100
99
 
101
100
  function subscribe(topic, stamp) {
102
- if (connection && connection.currentState === 0 && connection.desiredState === 0) {
103
- connection.subscribe(topic, mqtt5.QoS.AtLeastOnce)
101
+ if (client && client.getIsConnected()) {
102
+ const subscription = {
103
+ qos: mqtt5.QoS.AtLeastOnce,
104
+ topicFilter: topic
105
+ };
106
+
107
+ client.subscribe(subscription)
104
108
  .then(() => {
105
109
  self.postMessage({ type: 'subscribe_result', data: {success: true, stamp} });
106
110
  })
@@ -113,8 +117,8 @@ function subscribe(topic, stamp) {
113
117
  }
114
118
 
115
119
  function unsubscribe(topic, stamp) {
116
- if (connection && connection.currentState === 0 && connection.desiredState === 0) {
117
- connection.unsubscribe(topic)
120
+ if (client && client.getIsConnected()) {
121
+ client.unsubscribe({ topicFilter: topic })
118
122
  .then(() => {
119
123
  self.postMessage({ type: 'unsubscribe_result', data: {success: true, stamp} });
120
124
  })
@@ -127,65 +131,80 @@ function unsubscribe(topic, stamp) {
127
131
  }
128
132
 
129
133
  function send(topic, message) {
130
- if (connection && connection.currentState === 0 && connection.desiredState === 0) {
131
- connection.publish(topic, message, mqtt5.QoS.AtLeastOnce, false, {
132
- // Example of adding user properties
133
- userProperties: {
134
- // Add your properties here
135
- }
136
- });
134
+ if (client && client.getIsConnected()) {
135
+ const publish = {
136
+ qos: mqtt5.QoS.AtLeastOnce,
137
+ topicName: topic,
138
+ payload: message,
139
+ retain: false
140
+ };
141
+ client.publish(publish);
137
142
  } else {
138
143
  console.error('Cannot send message: Not connected');
139
144
  }
140
145
  }
141
146
 
142
147
  function setupConnectionListeners(connectionId) {
143
- connection.on(mqtt5.Mqtt5Client.ATTEMPTING_CONNECT, () => {
144
- console.log('Worker: Attempting to connect');
145
- });
146
-
147
- connection.on(mqtt5.Mqtt5Client.CONNECTION_SUCCESS, (event) => {
148
- if (connectionId !== currentConnectionId) {
149
- console.log('Worker: Connection Id mismatch, ignoring connection success event', connectionId, currentConnectionId);
148
+ client.on('connectionSuccess', (eventData) => {
149
+ if(connectionId !== currentConnectionId) {
150
+ console.log('Worker: Connection Id mismatch, ignoring connectionSuccess event', connectionId, currentConnectionId);
150
151
  return;
151
152
  }
152
- self.postMessage({ type: 'connect', connectionId: connectionId, settings: event.settings });
153
+ self.postMessage({
154
+ type: 'connection_success',
155
+ data: {
156
+ sessionPresent: eventData.sessionPresent,
157
+ negotiatedSettings: eventData.negotiatedSettings
158
+ },
159
+ connectionId: connectionId
160
+ });
153
161
  });
154
162
 
155
- connection.on(mqtt5.Mqtt5Client.CONNECTION_FAILURE, (event) => {
156
- if (connectionId !== currentConnectionId) {
157
- console.log('Worker: Connection Id mismatch, ignoring connection failure event', connectionId, currentConnectionId);
163
+ client.on('connectionFailure', (error) => {
164
+ if(connectionId !== currentConnectionId) {
165
+ console.log('Worker: Connection Id mismatch, ignoring connectionFailure event', connectionId, currentConnectionId);
158
166
  return;
159
167
  }
160
- self.postMessage({ type: 'connection_failure', error: event.error });
168
+ self.postMessage({ type: 'connection_failure', data: error, connectionId: connectionId });
161
169
  });
162
170
 
163
- connection.on(mqtt5.Mqtt5Client.DISCONNECTION, (event) => {
164
- if (connectionId !== currentConnectionId) {
165
- console.log('Worker: Connection Id mismatch, ignoring disconnection event', connectionId, currentConnectionId);
171
+ client.on('disconnection', (eventData) => {
172
+ if(connectionId !== currentConnectionId) {
173
+ console.log('Worker: Connection Id mismatch, ignoring disconnect event', connectionId, currentConnectionId);
166
174
  return;
167
175
  }
168
- self.postMessage({ type: 'disconnect', error: event.error });
176
+ self.postMessage({
177
+ type: 'disconnect',
178
+ data: { reason: eventData.errorCode },
179
+ connectionId: connectionId
180
+ });
169
181
  });
170
182
 
171
- connection.on(mqtt5.Mqtt5Client.MESSAGE_RECEIVED, (event) => {
172
- if (connectionId !== currentConnectionId) {
183
+ client.on('messageReceived', (eventData) => {
184
+ if(connectionId !== currentConnectionId) {
173
185
  console.log('Worker: Connection Id mismatch, ignoring message event', connectionId, currentConnectionId);
174
186
  return;
175
187
  }
176
- self.postMessage({ type: 'message', data: event.message });
188
+ self.postMessage({
189
+ type: 'message',
190
+ data: {
191
+ topic: eventData.message.topicName,
192
+ payload: eventData.message.payload,
193
+ qos: eventData.message.qos,
194
+ retain: eventData.message.retain,
195
+ properties: eventData.message.properties
196
+ },
197
+ connectionId: connectionId
198
+ });
177
199
  });
178
200
 
179
- // Additional events can be added as needed
180
- }
181
-
182
- // Ensure to call close when the worker is terminated or no longer needed
183
- function cleanup() {
184
- if (connection) {
185
- connection.close(); // Clean up resources
186
- connection = null;
187
- }
201
+ client.on('error', (error) => {
202
+ if(connectionId !== currentConnectionId) {
203
+ console.log('Worker: Connection Id mismatch, ignoring error event', connectionId, currentConnectionId);
204
+ return;
205
+ }
206
+ self.postMessage({ type: 'error', data: error });
207
+ });
188
208
  }
189
209
 
190
- // Add this at the end of the file
191
210
  console.log('Worker: Setup complete');
@@ -1,5 +1,5 @@
1
1
  import emitter from './wt-emitter';
2
- import { decodeJanusDisplay } from "../models/utils";
2
+ import {decodeJanusDisplay, generateUUID} from "../models/utils";
3
3
  import Worker from './wt-iot-worker.worker.js';
4
4
 
5
5
  class Iot {
@@ -55,12 +55,12 @@ class Iot {
55
55
  this.startCredentialsExpirationCheck(expiration);
56
56
  this.lastConnectParams = { apiMqttUrl, apiMqttClientId, region, accessKeyId, secretAccessKey, sessionToken, expiration };
57
57
  return new Promise((resolve, reject) => {
58
- const stamp = new Date().getTime();
58
+ const stamp = new Date().getTime() +'_'+ generateUUID();
59
59
 
60
60
  const handleConnectResult = (event) => {
61
61
 
62
62
  if(event.stamp !== stamp) {
63
- this.log('connect event stamp mismatch', event.stamp, stamp);
63
+ this.log('connect event stamp mismatch, ignoring', event.stamp, stamp);
64
64
  return;
65
65
  }
66
66
 
@@ -101,11 +101,11 @@ class Iot {
101
101
 
102
102
  return new Promise((resolve, reject) => {
103
103
 
104
- const stamp = new Date().getTime();
104
+ const stamp = new Date().getTime()+'_'+ generateUUID();
105
105
 
106
106
  const handleDisconnectResult = (event) => {
107
107
  if(event.stamp !== stamp) {
108
- this.log('disconnect event stamp mismatch', event.stamp, stamp);
108
+ this.log('disconnect event stamp mismatch, ignoring', event.stamp, stamp);
109
109
  return;
110
110
  }
111
111
  clearTimeout(timeoutId);
@@ -164,11 +164,11 @@ class Iot {
164
164
  }
165
165
 
166
166
  return new Promise((resolve, reject) => {
167
- const stamp = new Date().getTime();
167
+ const stamp = new Date().getTime()+'_'+ generateUUID();
168
168
  const handleSubscribeResult = (event) => {
169
169
 
170
170
  if(event.stamp !== stamp) {
171
- this.log('subscribe event stamp mismatch', event.stamp, stamp);
171
+ this.log('subscribe event stamp mismatch, ignoring', event.stamp, stamp);
172
172
  return;
173
173
  }
174
174
 
@@ -200,12 +200,12 @@ class Iot {
200
200
 
201
201
  return new Promise((resolve, reject) => {
202
202
 
203
- const stamp = new Date().getTime();
203
+ const stamp = new Date().getTime()+'_'+ generateUUID();;
204
204
 
205
205
  const handleUnsubscribeResult = (event) => {
206
206
 
207
207
  if(event.stamp !== stamp) {
208
- this.log('unsubscribe event stamp mismatch', event.stamp, stamp);
208
+ this.log('unsubscribe event stamp mismatch, ignoring', event.stamp, stamp);
209
209
  return;
210
210
  }
211
211