@reactoo/watchtogether-sdk-js 2.7.49 → 2.7.50
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.
- package/dist/0.watchtogether-sdk.js +52792 -0
- package/dist/0.watchtogether-sdk.js.map +1 -0
- package/dist/f8d53dc60757998a740a.js +222 -0
- package/dist/src_modules_wt-iot-worker_worker_js.watchtogether-sdk.js +581 -0
- package/dist/src_modules_wt-iot-worker_worker_js.watchtogether-sdk.js.map +1 -0
- package/dist/vendors-node_modules_aws-iot-device-sdk-v2_dist_browser_js.watchtogether-sdk.js +52792 -0
- package/dist/vendors-node_modules_aws-iot-device-sdk-v2_dist_browser_js.watchtogether-sdk.js.map +1 -0
- package/dist/watchtogether-sdk.js +30365 -76378
- package/dist/watchtogether-sdk.js.map +1 -1
- package/dist/watchtogether-sdk.min.js +2 -2
- package/example/index.html +5 -1
- package/package.json +1 -1
- package/src/index.js +1 -1
- package/src/modules/wt-iot-worker.worker.js +164 -0
- package/src/modules/wt-iot2.js +355 -0
- package/webpack.config.js +10 -3
- package/src/modules/iot-worker.worker.js +0 -84
package/example/index.html
CHANGED
|
@@ -189,7 +189,7 @@
|
|
|
189
189
|
return Instance.iot.iotLogout()
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
function
|
|
192
|
+
function iotLogin() {
|
|
193
193
|
return Instance.iot.iotLogin()
|
|
194
194
|
}
|
|
195
195
|
|
|
@@ -197,6 +197,10 @@
|
|
|
197
197
|
return Instance.iot.subscribe(topic)
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
+
function updateCredentials() {
|
|
201
|
+
return Instance.iot.__updateCredentials()
|
|
202
|
+
}
|
|
203
|
+
|
|
200
204
|
let Instance = WatchTogetherSDK({debug:true})({instanceType:'reactooDemo'});
|
|
201
205
|
|
|
202
206
|
Instance.auth.$on('login', (r) => {
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { mqtt, iot } from 'aws-iot-device-sdk-v2';
|
|
2
|
+
console.log('Worker: Starting up');
|
|
3
|
+
|
|
4
|
+
let connection = null;
|
|
5
|
+
|
|
6
|
+
self.onmessage = function(event) {
|
|
7
|
+
const { type, params, topic, message } = event.data;
|
|
8
|
+
console.log(`Worker: Received message of type: ${type}`);
|
|
9
|
+
|
|
10
|
+
switch (type) {
|
|
11
|
+
case 'connect':
|
|
12
|
+
connect(params);
|
|
13
|
+
break;
|
|
14
|
+
case 'disconnect':
|
|
15
|
+
disconnect();
|
|
16
|
+
break;
|
|
17
|
+
case 'is_connected':
|
|
18
|
+
isConnected();
|
|
19
|
+
break;
|
|
20
|
+
case 'clear_topics':
|
|
21
|
+
// No action needed in the worker
|
|
22
|
+
break;
|
|
23
|
+
case 'subscribe':
|
|
24
|
+
subscribe(topic);
|
|
25
|
+
break;
|
|
26
|
+
case 'unsubscribe':
|
|
27
|
+
unsubscribe(topic);
|
|
28
|
+
break;
|
|
29
|
+
case 'send':
|
|
30
|
+
send(topic, message);
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
function connect(params) {
|
|
36
|
+
console.log('Worker: Attempting to connect');
|
|
37
|
+
const { apiMqttUrl, apiMqttClientId, region, accessKeyId, secretAccessKey, sessionToken } = params;
|
|
38
|
+
|
|
39
|
+
const configBuilder = iot.AwsIotMqttConnectionConfigBuilder.new_with_websockets();
|
|
40
|
+
|
|
41
|
+
configBuilder.with_clean_session(true);
|
|
42
|
+
configBuilder.with_client_id(apiMqttClientId);
|
|
43
|
+
configBuilder.with_endpoint(apiMqttUrl);
|
|
44
|
+
configBuilder.with_credentials(region, accessKeyId, secretAccessKey, sessionToken);
|
|
45
|
+
configBuilder.with_keep_alive_seconds(30);
|
|
46
|
+
configBuilder.with_ping_timeout_ms(3000);
|
|
47
|
+
configBuilder.with_reconnect_max_sec(5);
|
|
48
|
+
configBuilder.with_reconnect_min_sec(1);
|
|
49
|
+
|
|
50
|
+
const config = configBuilder.build();
|
|
51
|
+
|
|
52
|
+
const client = new mqtt.MqttClient();
|
|
53
|
+
connection = client.new_connection(config);
|
|
54
|
+
|
|
55
|
+
setupConnectionListeners();
|
|
56
|
+
|
|
57
|
+
connection.connect()
|
|
58
|
+
.then(() => {
|
|
59
|
+
console.log('Worker: Connection successful');
|
|
60
|
+
self.postMessage({ type: 'connect_result', data: {success: true} });
|
|
61
|
+
})
|
|
62
|
+
.catch((error) => {
|
|
63
|
+
console.error('Worker: Connection failed', error);
|
|
64
|
+
self.postMessage({ type: 'connect_result', data: {success: false, error: error.message} });
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function disconnect() {
|
|
69
|
+
if (connection) {
|
|
70
|
+
connection.disconnect()
|
|
71
|
+
.then(() => {
|
|
72
|
+
self.postMessage({ type: 'disconnect_result', data: {success: true} });
|
|
73
|
+
})
|
|
74
|
+
.catch((error) => {
|
|
75
|
+
self.postMessage({ type: 'disconnect_result', data: { success: false, error: error.message} });
|
|
76
|
+
});
|
|
77
|
+
} else {
|
|
78
|
+
self.postMessage({ type: 'disconnect_result', data: {success: true} });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function isConnected() {
|
|
83
|
+
const connected = connection && connection.currentState === 0 && connection.desiredState === 0;
|
|
84
|
+
self.postMessage({ type: 'is_connected_result', data:{connected} });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function subscribe(topic) {
|
|
88
|
+
if (connection && connection.currentState === 0 && connection.desiredState === 0) {
|
|
89
|
+
connection.subscribe(topic, mqtt.QoS.AtLeastOnce)
|
|
90
|
+
.then(() => {
|
|
91
|
+
self.postMessage({ type: 'subscribe_result', data: {success: true} });
|
|
92
|
+
})
|
|
93
|
+
.catch((error) => {
|
|
94
|
+
self.postMessage({ type: 'subscribe_result', data: {success: false, error: error.message} });
|
|
95
|
+
});
|
|
96
|
+
} else {
|
|
97
|
+
self.postMessage({ type: 'subscribe_result', data: {success: false, error: 'Not connected'} });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function unsubscribe(topic) {
|
|
102
|
+
if (connection && connection.currentState === 0 && connection.desiredState === 0) {
|
|
103
|
+
connection.unsubscribe(topic)
|
|
104
|
+
.then(() => {
|
|
105
|
+
self.postMessage({ type: 'unsubscribe_result', data: {success: true} });
|
|
106
|
+
})
|
|
107
|
+
.catch((error) => {
|
|
108
|
+
self.postMessage({ type: 'unsubscribe_result', data: {success: false, error: error.message} });
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
self.postMessage({ type: 'unsubscribe_result', data: {success: false, error: 'Not connected'} });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function send(topic, message) {
|
|
116
|
+
if (connection && connection.currentState === 0 && connection.desiredState === 0) {
|
|
117
|
+
connection.publish(topic, message, mqtt.QoS.AtLeastOnce, false);
|
|
118
|
+
} else {
|
|
119
|
+
console.error('Cannot send message: Not connected');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function setupConnectionListeners() {
|
|
124
|
+
connection.on('connect', () => {
|
|
125
|
+
self.postMessage({ type: 'connect' });
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
connection.on('disconnect', () => {
|
|
129
|
+
self.postMessage({ type: 'disconnect' });
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
connection.on('error', (error) => {
|
|
133
|
+
self.postMessage({ type: 'error', data: error });
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
connection.on('interrupt', (error) => {
|
|
137
|
+
self.postMessage({ type: 'interrupt', data: error });
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
connection.on('resume', (error) => {
|
|
141
|
+
self.postMessage({ type: 'resume', data: error });
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
connection.on('message', (topic, payload) => {
|
|
145
|
+
self.postMessage({ type: 'message', data: { topic, payload } });
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
connection.on('connection_success', (error) => {
|
|
149
|
+
self.postMessage({ type: 'connection_success', data: error });
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
connection.on('connection_failure', (error) => {
|
|
153
|
+
self.postMessage({ type: 'connection_failure', data: error });
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Add a general error handler for uncaught exceptions
|
|
157
|
+
self.addEventListener('error', (error) => {
|
|
158
|
+
console.error('Worker: Uncaught error', error);
|
|
159
|
+
self.postMessage({ type: 'uncaught_error', error: error.message });
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Add this at the end of the file
|
|
164
|
+
console.log('Worker: Setup complete');
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import emitter from './wt-emitter';
|
|
2
|
+
import { decodeJanusDisplay } from "./wt-utils";
|
|
3
|
+
import Worker from './wt-iot-worker.worker.js';
|
|
4
|
+
|
|
5
|
+
class Iot {
|
|
6
|
+
constructor(enableDebugFlag) {
|
|
7
|
+
Object.assign(this, emitter());
|
|
8
|
+
this.decoder = new TextDecoder('utf-8');
|
|
9
|
+
this.log = Iot.noop;
|
|
10
|
+
this.credentialsExpirationCheckIntervalId = null;
|
|
11
|
+
this.currentCredentialsExpirationStamp = null;
|
|
12
|
+
this.lastConnectParams = null;
|
|
13
|
+
this.subscribedTopics = new Set();
|
|
14
|
+
this.initWorker();
|
|
15
|
+
|
|
16
|
+
if (enableDebugFlag) {
|
|
17
|
+
this.enableDebug();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static noop() {}
|
|
22
|
+
|
|
23
|
+
enableDebug() {
|
|
24
|
+
this.log = console.log.bind(console);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
initWorker() {
|
|
28
|
+
this.worker = new Worker();
|
|
29
|
+
this.worker.onmessage = this.handleWorkerMessage.bind(this);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
connect(apiMqttUrl, apiMqttClientId, region, accessKeyId, secretAccessKey, sessionToken, expiration) {
|
|
33
|
+
this.log('iot connect called, we disconnect first just to be sure');
|
|
34
|
+
return this.disconnect()
|
|
35
|
+
.catch(() => {
|
|
36
|
+
// we dont care if disconnect fails
|
|
37
|
+
return Promise.resolve();
|
|
38
|
+
})
|
|
39
|
+
.finally(() => {
|
|
40
|
+
this.log('iot connect');
|
|
41
|
+
this.startCredentialsExpirationCheck(expiration);
|
|
42
|
+
this.lastConnectParams = { apiMqttUrl, apiMqttClientId, region, accessKeyId, secretAccessKey, sessionToken, expiration };
|
|
43
|
+
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
const timeoutId = setTimeout(() => {
|
|
46
|
+
this.off('worker:connect_result');
|
|
47
|
+
reject(new Error('Connection timeout'));
|
|
48
|
+
}, 5000);
|
|
49
|
+
|
|
50
|
+
const handleConnectResult = (event) => {
|
|
51
|
+
clearTimeout(timeoutId);
|
|
52
|
+
this.off('worker:connect_result', handleConnectResult);
|
|
53
|
+
if (event.success) {
|
|
54
|
+
resolve();
|
|
55
|
+
} else {
|
|
56
|
+
reject(new Error(event.error));
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
this.on('worker:connect_result', handleConnectResult);
|
|
61
|
+
|
|
62
|
+
this.worker.postMessage({
|
|
63
|
+
type: 'connect',
|
|
64
|
+
params: this.lastConnectParams
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
disconnect() {
|
|
71
|
+
this.log('iot disconnect');
|
|
72
|
+
this.stopCredentialsExpirationCheck();
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
|
+
const timeoutId = setTimeout(() => {
|
|
75
|
+
this.off('worker:disconnect_result');
|
|
76
|
+
reject(new Error('Disconnect timeout'));
|
|
77
|
+
}, 5000);
|
|
78
|
+
|
|
79
|
+
const handleDisconnectResult = (event) => {
|
|
80
|
+
clearTimeout(timeoutId);
|
|
81
|
+
this.off('worker:disconnect_result', handleDisconnectResult);
|
|
82
|
+
if (event.success) {
|
|
83
|
+
resolve();
|
|
84
|
+
} else {
|
|
85
|
+
reject(new Error(event.error));
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
this.on('worker:disconnect_result', handleDisconnectResult);
|
|
89
|
+
this.worker.postMessage({ type: 'disconnect' });
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
isConnected() {
|
|
94
|
+
return new Promise((resolve) => {
|
|
95
|
+
const handleIsConnectedResult = (event) => {
|
|
96
|
+
this.off('worker:is_connected_result', handleIsConnectedResult);
|
|
97
|
+
resolve(event.connected);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
this.on('worker:is_connected_result', handleIsConnectedResult);
|
|
101
|
+
this.worker.postMessage({ type: 'is_connected' });
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
clearTopics() {
|
|
106
|
+
this.subscribedTopics.clear();
|
|
107
|
+
this.worker.postMessage({ type: 'clear_topics' });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
subscribe(topic) {
|
|
111
|
+
this.log('iot subscribe', topic);
|
|
112
|
+
if (typeof topic === 'string' && topic.trim() !== '') {
|
|
113
|
+
return new Promise((resolve, reject) => {
|
|
114
|
+
const handleSubscribeResult = (event) => {
|
|
115
|
+
this.off('worker:subscribe_result', handleSubscribeResult);
|
|
116
|
+
if (event.success) {
|
|
117
|
+
this.subscribedTopics.add(topic);
|
|
118
|
+
resolve();
|
|
119
|
+
} else {
|
|
120
|
+
reject(new Error(event.error));
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
this.on('worker:subscribe_result', handleSubscribeResult);
|
|
125
|
+
this.worker.postMessage({ type: 'subscribe', topic });
|
|
126
|
+
});
|
|
127
|
+
} else {
|
|
128
|
+
this.log('Invalid topic:', topic);
|
|
129
|
+
return Promise.reject(new Error('Invalid topic'));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
unsubscribe(topic) {
|
|
134
|
+
this.log('iot unsubscribe', topic);
|
|
135
|
+
if (typeof topic === 'string' && topic.trim() !== '') {
|
|
136
|
+
return new Promise((resolve, reject) => {
|
|
137
|
+
const handleUnsubscribeResult = (event) => {
|
|
138
|
+
this.off('worker:unsubscribe_result', handleUnsubscribeResult);
|
|
139
|
+
if (event.success) {
|
|
140
|
+
this.subscribedTopics.delete(topic);
|
|
141
|
+
resolve();
|
|
142
|
+
} else {
|
|
143
|
+
reject(new Error(event.error));
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
this.on('worker:unsubscribe_result', handleUnsubscribeResult);
|
|
148
|
+
this.worker.postMessage({ type: 'unsubscribe', topic });
|
|
149
|
+
});
|
|
150
|
+
} else {
|
|
151
|
+
this.log('Invalid topic:', topic);
|
|
152
|
+
return Promise.reject(new Error('Invalid topic'));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
send(topic, message) {
|
|
157
|
+
this.log('iot send', topic, message);
|
|
158
|
+
let msg = typeof message === 'object' ? JSON.stringify(message) : message;
|
|
159
|
+
this.worker.postMessage({ type: 'send', topic, message: msg });
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
handleWorkerMessage(event) {
|
|
163
|
+
const { type, data } = event.data;
|
|
164
|
+
switch (type) {
|
|
165
|
+
case 'message':
|
|
166
|
+
this.handleMessage(data.topic, new Uint8Array(data.payload));
|
|
167
|
+
break;
|
|
168
|
+
case 'connect':
|
|
169
|
+
case 'disconnect':
|
|
170
|
+
case 'error':
|
|
171
|
+
case 'interrupt':
|
|
172
|
+
case 'resume':
|
|
173
|
+
case 'connection_success':
|
|
174
|
+
case 'connection_failure':
|
|
175
|
+
this.emit(type, data);
|
|
176
|
+
break;
|
|
177
|
+
case 'connect_result':
|
|
178
|
+
case 'disconnect_result':
|
|
179
|
+
case 'is_connected_result':
|
|
180
|
+
case 'subscribe_result':
|
|
181
|
+
case 'unsubscribe_result':
|
|
182
|
+
this.emit(`worker:${type}`, data);
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
handleMessage(topic, payload) {
|
|
188
|
+
const topicParts = topic.split('/');
|
|
189
|
+
let message;
|
|
190
|
+
try {
|
|
191
|
+
message = JSON.parse(this.decoder.decode(payload));
|
|
192
|
+
} catch (error) {
|
|
193
|
+
this.log('Error parsing message:', error);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if(message.display) {
|
|
198
|
+
const decodedDisplay = decodeJanusDisplay(message.display);
|
|
199
|
+
if(decodedDisplay.userId) {
|
|
200
|
+
message = {...message, userId: decodedDisplay.userId, role: decodedDisplay.role, start: decodedDisplay.start};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if(topicParts[0] === 'user') { // user
|
|
205
|
+
const userId = topicParts[1].replace("_", ':');
|
|
206
|
+
this.emit('message', {userId, ...message, event: message.event ? `user:${message.event}` : 'user'});
|
|
207
|
+
} else if(topicParts[0] === 'wt') {
|
|
208
|
+
const event = message.event;
|
|
209
|
+
const roomId = topicParts[2];
|
|
210
|
+
if(topicParts[1] === 'room') { // room
|
|
211
|
+
if(
|
|
212
|
+
event === 'message' ||
|
|
213
|
+
event === 'template_updated' ||
|
|
214
|
+
event === 'record_start' ||
|
|
215
|
+
event === 'record_stop' ||
|
|
216
|
+
event === 'record_configured' ||
|
|
217
|
+
event === 'record_livestream_available' ||
|
|
218
|
+
event === 'record_livestream_kick' ||
|
|
219
|
+
event === 'user_update_displayname' ||
|
|
220
|
+
event === 'user_update_avatar' ||
|
|
221
|
+
event === 'user_update_bio' ||
|
|
222
|
+
event === 'user_update_customattributes' ||
|
|
223
|
+
event === 'user_update_privateattributes' ||
|
|
224
|
+
event === 'channel_changed' ||
|
|
225
|
+
event === "instance_homepage_changed" ||
|
|
226
|
+
event === "instance_settings_changed" ||
|
|
227
|
+
event === "externalmix_changed" ||
|
|
228
|
+
event === "video_uploaded" ||
|
|
229
|
+
event === "change_user_devices" ||
|
|
230
|
+
event === "queue" ||
|
|
231
|
+
event === "title_changed" ||
|
|
232
|
+
event === "videowall_changed" ||
|
|
233
|
+
event === 'left' || //user removed room a.k.a. left the room
|
|
234
|
+
event === 'kicked' ||
|
|
235
|
+
event === 'banned' ||
|
|
236
|
+
event === 'unbanned' ||
|
|
237
|
+
event === 'approved' ||
|
|
238
|
+
event === 'muted' ||
|
|
239
|
+
event === 'unmuted' ||
|
|
240
|
+
event === 'messageRemoved' ||
|
|
241
|
+
event === 'messageReported' ||
|
|
242
|
+
event === 'chatClear' ||
|
|
243
|
+
event === 'handRaised' ||
|
|
244
|
+
event === 'handLowered' ||
|
|
245
|
+
event === 'handsCleared' ||
|
|
246
|
+
event === 'volume_set' ||
|
|
247
|
+
event === 'asset_created'
|
|
248
|
+
) {
|
|
249
|
+
this.emit('message', {event, ...message, roomId})
|
|
250
|
+
}
|
|
251
|
+
else if(event === 'joined' || event === 'leaving') {
|
|
252
|
+
this.emit('message', {event, ...message, isObserver:!!message.isObserver, roomId});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else if(topicParts[1] === 'instanceroom') { // instance
|
|
256
|
+
if(event === 'add_room' || event === 'remove_room' || event === 'set_room' || event === "instance_homepage_changed" || event === 'instance_settings_changed') {
|
|
257
|
+
this.emit('message', {event, ...message});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else if(topicParts[1] === 'externalmix') {
|
|
261
|
+
const event = message.event;
|
|
262
|
+
this.emit('message', {event, ...message});
|
|
263
|
+
}
|
|
264
|
+
else if(topicParts[1] === 'asset') {
|
|
265
|
+
this.emit('message', {event: 'asset', assetId: topicParts[2], ...message});
|
|
266
|
+
}
|
|
267
|
+
} else if(topicParts[0] === 'wtr' || topicParts[0] === 'gwtr') {
|
|
268
|
+
const recorderId = topicParts[1];
|
|
269
|
+
const sessionId = topicParts[2];
|
|
270
|
+
if(topicParts[3] === 'control') {
|
|
271
|
+
this.emit('message', {event: 'recorder_control', ...message, recorderId, sessionId});
|
|
272
|
+
} // recorder control
|
|
273
|
+
else if(topicParts[3] === 'monitor') {
|
|
274
|
+
this.emit('message', {event: 'recorder_monitor', ...message, recorderId, sessionId});
|
|
275
|
+
} // recorder monitor
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
startCredentialsExpirationCheck(expiration) {
|
|
280
|
+
this.stopCredentialsExpirationCheck();
|
|
281
|
+
this.currentCredentialsExpirationStamp = new Date(expiration).getTime();
|
|
282
|
+
this.credentialsExpirationCheckIntervalId = setInterval(() => {
|
|
283
|
+
const currentTimeStamp = new Date().getTime();
|
|
284
|
+
// update 15 minutes before expiration
|
|
285
|
+
if(this.currentCredentialsExpirationStamp - currentTimeStamp <= 900000) {
|
|
286
|
+
this.log('iot credentials expired, updating');
|
|
287
|
+
this.emit('updateCredentials');
|
|
288
|
+
}
|
|
289
|
+
}, 5000);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
stopCredentialsExpirationCheck() {
|
|
293
|
+
clearInterval(this.credentialsExpirationCheckIntervalId);
|
|
294
|
+
this.credentialsExpirationCheckIntervalId = null;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
updateWebSocketCredentials(accessKeyId, secretAccessKey, sessionToken, expiration) {
|
|
298
|
+
this.log('iot updateWebSocketCredentials');
|
|
299
|
+
this.lastConnectParams = {...this.lastConnectParams, accessKeyId, secretAccessKey, sessionToken, expiration };
|
|
300
|
+
const currentTopics = new Set(this.subscribedTopics);
|
|
301
|
+
return this.connect(
|
|
302
|
+
this.lastConnectParams.apiMqttUrl,
|
|
303
|
+
this.lastConnectParams.apiMqttClientId,
|
|
304
|
+
this.lastConnectParams.region,
|
|
305
|
+
accessKeyId,
|
|
306
|
+
secretAccessKey,
|
|
307
|
+
sessionToken,
|
|
308
|
+
expiration
|
|
309
|
+
).then(() => {
|
|
310
|
+
// Resubscribe to topics
|
|
311
|
+
currentTopics.forEach(topic => this.subscribe(topic));
|
|
312
|
+
return true;
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
checkConnection() {
|
|
317
|
+
return new Promise((resolve, reject) => {
|
|
318
|
+
if (this.subscribedTopics.size === 0) {
|
|
319
|
+
reject(new Error('No subscribed topics available for connection check', {cause: -1}));
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
let suitableTopic = Array.from(this.subscribedTopics).find(topic => topic.indexOf('user') > -1);
|
|
324
|
+
|
|
325
|
+
if (!suitableTopic) {
|
|
326
|
+
reject(new Error('No suitable topic found for connection check', {cause: -1}));
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const testMessage = {
|
|
331
|
+
type: 'keep_alive',
|
|
332
|
+
timestamp: Date.now()
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const timeoutId = setTimeout(() => {
|
|
336
|
+
this.off('message', checkMessageHandler);
|
|
337
|
+
reject(new Error('Connection check timeout'));
|
|
338
|
+
}, 5000);
|
|
339
|
+
|
|
340
|
+
const checkMessageHandler = (message) => {
|
|
341
|
+
if (message.type === 'keep_alive' && message.timestamp === testMessage.timestamp) {
|
|
342
|
+
clearTimeout(timeoutId);
|
|
343
|
+
this.off('message', checkMessageHandler);
|
|
344
|
+
resolve();
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
this.on('message', checkMessageHandler);
|
|
349
|
+
|
|
350
|
+
this.send(suitableTopic, testMessage);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export default Iot;
|
package/webpack.config.js
CHANGED
|
@@ -22,9 +22,9 @@ module.exports = (env, argv) => {
|
|
|
22
22
|
libraryTarget: 'umd',
|
|
23
23
|
libraryExport: 'default',
|
|
24
24
|
umdNamedDefine: true,
|
|
25
|
-
globalObject: "typeof self !== 'undefined' ? self : this"
|
|
25
|
+
globalObject: "typeof self !== 'undefined' ? self : this",
|
|
26
|
+
publicPath: '',
|
|
26
27
|
},
|
|
27
|
-
// Remove the experiments section
|
|
28
28
|
module: {
|
|
29
29
|
rules: [
|
|
30
30
|
{
|
|
@@ -36,7 +36,9 @@ module.exports = (env, argv) => {
|
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
test: /\.worker\.js$/,
|
|
39
|
-
use:
|
|
39
|
+
use: [
|
|
40
|
+
{ loader: 'worker-loader', options: { inline: 'no-fallback' } },
|
|
41
|
+
]
|
|
40
42
|
}
|
|
41
43
|
]
|
|
42
44
|
},
|
|
@@ -44,6 +46,11 @@ module.exports = (env, argv) => {
|
|
|
44
46
|
new webpack.BannerPlugin(banner),
|
|
45
47
|
new webpack.ProvidePlugin({
|
|
46
48
|
process: 'process/browser',
|
|
49
|
+
Buffer: ['buffer', 'Buffer'],
|
|
50
|
+
}),
|
|
51
|
+
new webpack.DefinePlugin({
|
|
52
|
+
'typeof window': JSON.stringify('object'),
|
|
53
|
+
'window': 'self',
|
|
47
54
|
}),
|
|
48
55
|
],
|
|
49
56
|
optimization: {
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { mqtt, iot } from 'aws-iot-device-sdk-v2';
|
|
2
|
-
|
|
3
|
-
let connection = null;
|
|
4
|
-
|
|
5
|
-
self.onmessage = function(e) {
|
|
6
|
-
const { action, payload } = e.data;
|
|
7
|
-
|
|
8
|
-
switch (action) {
|
|
9
|
-
case 'connect':
|
|
10
|
-
connect(payload);
|
|
11
|
-
break;
|
|
12
|
-
case 'disconnect':
|
|
13
|
-
disconnect();
|
|
14
|
-
break;
|
|
15
|
-
case 'subscribe':
|
|
16
|
-
subscribe(payload.topic);
|
|
17
|
-
break;
|
|
18
|
-
case 'unsubscribe':
|
|
19
|
-
unsubscribe(payload.topic);
|
|
20
|
-
break;
|
|
21
|
-
case 'send':
|
|
22
|
-
send(payload.topic, payload.message);
|
|
23
|
-
break;
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
function connect({ apiMqttUrl, apiMqttClientId, region, accessKeyId, secretAccessKey, sessionToken }) {
|
|
28
|
-
const configBuilder = iot.AwsIotMqttConnectionConfigBuilder.new_with_websockets();
|
|
29
|
-
|
|
30
|
-
configBuilder.with_clean_session(true);
|
|
31
|
-
configBuilder.with_client_id(apiMqttClientId);
|
|
32
|
-
configBuilder.with_endpoint(apiMqttUrl);
|
|
33
|
-
configBuilder.with_credentials(region, accessKeyId, secretAccessKey, sessionToken);
|
|
34
|
-
configBuilder.with_keep_alive_seconds(30);
|
|
35
|
-
configBuilder.with_ping_timeout_ms(3000);
|
|
36
|
-
|
|
37
|
-
const config = configBuilder.build();
|
|
38
|
-
|
|
39
|
-
const client = new mqtt.MqttClient();
|
|
40
|
-
connection = client.new_connection(config);
|
|
41
|
-
|
|
42
|
-
connection.on('connect', () => {
|
|
43
|
-
self.postMessage({ event: 'connect' });
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
connection.on('disconnect', () => {
|
|
47
|
-
self.postMessage({ event: 'disconnect' });
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
connection.on('error', (error) => {
|
|
51
|
-
self.postMessage({ event: 'error', error: error.toString() });
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
connection.on('message', (topic, payload) => {
|
|
55
|
-
self.postMessage({ event: 'message', topic, payload: new Uint8Array(payload) });
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
connection.connect();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function disconnect() {
|
|
62
|
-
if (connection) {
|
|
63
|
-
connection.disconnect();
|
|
64
|
-
connection = null;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function subscribe(topic) {
|
|
69
|
-
if (connection) {
|
|
70
|
-
connection.subscribe(topic, mqtt.QoS.AtLeastOnce);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function unsubscribe(topic) {
|
|
75
|
-
if (connection) {
|
|
76
|
-
connection.unsubscribe(topic);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function send(topic, message) {
|
|
81
|
-
if (connection) {
|
|
82
|
-
connection.publish(topic, message, mqtt.QoS.AtLeastOnce);
|
|
83
|
-
}
|
|
84
|
-
}
|