remoterigs-raspberrypi 0.1.9 → 0.1.11

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "remoterigs-raspberrypi",
3
3
  "type": "module",
4
- "version": "0.1.9",
4
+ "version": "0.1.11",
5
5
  "main": "./index.js",
6
6
  "files": [
7
7
  "index.js",
@@ -9,12 +9,15 @@ export default class SignalR {
9
9
  static { this.reconnectTimer = null; }
10
10
  static { this.lastUniqueCode = null; }
11
11
  static { this.intentionalStop = false; }
12
+ static { this.signInRetryTimer = null; }
13
+ static { this.signInAttempts = 0; }
12
14
  static GetName() {
13
15
  return "SignalR";
14
16
  }
15
17
  static StartConnection(uniquecode) {
16
18
  SignalR.lastUniqueCode = uniquecode;
17
19
  SignalR.intentionalStop = false;
20
+ SignalR.CancelSignInRetry();
18
21
  Debug.LogAlways(SignalR.GetName(), "initiating hub connection... url: '" + Server.signalr + "'", false);
19
22
  SignalR.hubConnection = new signalR.HubConnectionBuilder()
20
23
  .withUrl(Server.signalr)
@@ -33,7 +36,7 @@ export default class SignalR {
33
36
  if (Server.rig.rig.id !== webRTCMessage.rigId) {
34
37
  Debug.Error(SignalR.GetName(), "incoming web-rtc-message error Server.rig.rig.id (" + Server.rig.rig.id + ") !== message.rigId (" + webRTCMessage.rigId + ")");
35
38
  }
36
- Debug.Log(LogSettingType.SignalR, undefined, SignalR.GetName(), "incoming web-rtc-message rigId:" + webRTCMessage.rigId + " componentId:" + webRTCMessage.componentId + " userName: " + webRTCMessage.userName + " rigOwnerUsername: " + webRTCMessage.rigOwnerUsername);
39
+ Debug.Log(LogSettingType.SignalR, undefined, SignalR.GetName(), "incoming web-rtc-message rigId:" + webRTCMessage.rigId + " componentId:" + webRTCMessage.componentId + " userId: " + webRTCMessage.userId + " rigOwnerUserId: " + webRTCMessage.rigOwnerUserId);
37
40
  Server.rig.PutWebRTCMessage(webRTCMessage);
38
41
  }
39
42
  else {
@@ -61,6 +64,8 @@ export default class SignalR {
61
64
  });
62
65
  SignalR.hubConnection.onclose((error) => {
63
66
  Debug.LogAlways(SignalR.GetName(), "hub connection closed" + (error ? (": " + error) : ""), true);
67
+ // a new connection signs in itself (StartConnection)
68
+ SignalR.CancelSignInRetry();
64
69
  SignalR.ScheduleReconnect();
65
70
  });
66
71
  SignalR.hubConnection
@@ -76,7 +81,6 @@ export default class SignalR {
76
81
  }
77
82
  static ScheduleReconnect() {
78
83
  if (SignalR.intentionalStop) {
79
- 1;
80
84
  return;
81
85
  }
82
86
  if (SignalR.reconnectTimer != null) {
@@ -91,9 +95,35 @@ export default class SignalR {
91
95
  }
92
96
  }, 30000);
93
97
  }
98
+ /// The server refuses a sign in while another connection is still signed in as this rig. After a network drop
99
+ /// that is our own old connection: the server only drops it after the SignalR timeout (30s). The server also
100
+ /// refuses (with the same empty answer) when there are too many sign in attempts from this IP address.
101
+ /// So keep trying: after 5s, 10s, 20s and then every 30s.
102
+ static ScheduleSignInRetry(uniquecode) {
103
+ if (SignalR.intentionalStop || SignalR.signInRetryTimer != null) {
104
+ return;
105
+ }
106
+ SignalR.signInAttempts++;
107
+ const delay = Math.min(5000 * Math.pow(2, SignalR.signInAttempts - 1), 30000);
108
+ Debug.LogAlways(SignalR.GetName(), "retrying sign in in " + (delay / 1000) + "s (attempt " + SignalR.signInAttempts + ")...", true);
109
+ SignalR.signInRetryTimer = setTimeout(() => {
110
+ SignalR.signInRetryTimer = null;
111
+ if (!SignalR.intentionalStop) {
112
+ SignalR.SignIn(uniquecode);
113
+ }
114
+ }, delay);
115
+ }
116
+ static CancelSignInRetry() {
117
+ if (SignalR.signInRetryTimer != null) {
118
+ clearTimeout(SignalR.signInRetryTimer);
119
+ SignalR.signInRetryTimer = null;
120
+ }
121
+ SignalR.signInAttempts = 0;
122
+ }
94
123
  static StopConnection() {
95
124
  Debug.Log(LogSettingType.SignalR, undefined, SignalR.GetName(), "stopping hub connection...");
96
125
  SignalR.intentionalStop = true;
126
+ SignalR.CancelSignInRetry();
97
127
  if (SignalR.reconnectTimer != null) {
98
128
  clearTimeout(SignalR.reconnectTimer);
99
129
  SignalR.reconnectTimer = null;
@@ -116,9 +146,12 @@ export default class SignalR {
116
146
  SignalR.hubConnection.invoke('SignIn', uniquecode)
117
147
  .then((rigClientViewModel) => {
118
148
  if (rigClientViewModel.rigModelViewModel == undefined) {
149
+ // unknown code, the rig is still signed in on another (old) connection, or too many attempts
119
150
  Debug.LogAlways(SignalR.GetName(), "sign in to server failed! GUID: " + uniquecode, true);
151
+ SignalR.ScheduleSignInRetry(uniquecode);
120
152
  }
121
153
  else {
154
+ SignalR.CancelSignInRetry();
122
155
  Debug.LogAlways(SignalR.GetName(), "sign in to server successful", true);
123
156
  Debug.LogAlways(SignalR.GetName(), "rig #" + rigClientViewModel.id + " '" + rigClientViewModel.name + "'", true);
124
157
  Debug.LogAlways(SignalR.GetName(), "rig model #" + rigClientViewModel.rigModelViewModel.id + " '" + rigClientViewModel.rigModelViewModel.name + "'", true);
@@ -157,10 +190,10 @@ export default class SignalR {
157
190
  }
158
191
  static SendWebRTCMessage(message) {
159
192
  if (SignalR.hubConnection != null && SignalR.IsConnected()) {
160
- Debug.Log(LogSettingType.SignalR, undefined, SignalR.GetName(), "outgoing SendWebRTCMessage rigId: " + message.rigId + " componentId:" + message.componentId + " userName: " + message.userName + " rigOwnerUsername: " + message.rigOwnerUsername);
193
+ Debug.Log(LogSettingType.SignalR, undefined, SignalR.GetName(), "outgoing SendWebRTCMessage rigId: " + message.rigId + " componentId:" + message.componentId + " userId: " + message.userId + " rigOwnerUserId: " + message.rigOwnerUserId);
161
194
  SignalR.hubConnection.invoke("SendWebRTCMessage", message)
162
195
  .then(() => {
163
- Debug.Log(LogSettingType.SignalR, undefined, SignalR.GetName(), "outgoing SendWebRTCMessage success rigId: " + message.rigId + " componentId:" + message.componentId + " userName: " + message.userName + " rigOwnerUsername: " + message.rigOwnerUsername);
196
+ Debug.Log(LogSettingType.SignalR, undefined, SignalR.GetName(), "outgoing SendWebRTCMessage success rigId: " + message.rigId + " componentId:" + message.componentId + " userId: " + message.userId + " rigOwnerUserId: " + message.rigOwnerUserId);
164
197
  })
165
198
  .catch((err) => {
166
199
  Debug.Error(SignalR.GetName(), "outgoing SendWebRTCMessage error: " + err);
@@ -47,7 +47,7 @@ export default class WebRTCStreamerWrapper {
47
47
  }
48
48
  async PutWebRTCMessage(message) {
49
49
  if (this.streamerStarted) {
50
- this.Log("PutWebRTCMessage userName: " + message.userName + " messageType: " + message.messageType);
50
+ this.Log("PutWebRTCMessage userId: " + message.userId + " messageType: " + message.messageType);
51
51
  if (message.messageType == "getIceServers") {
52
52
  await this.GetIceServers(message);
53
53
  }
@@ -88,7 +88,7 @@ export default class WebRTCStreamerWrapper {
88
88
  }
89
89
  }
90
90
  else {
91
- this.Log("IGNORED! PutWebRTCMessage userName: " + message.userName + " messageType: " + message.messageType);
91
+ this.Log("IGNORED! PutWebRTCMessage userId: " + message.userId + " messageType: " + message.messageType);
92
92
  }
93
93
  }
94
94
  async StartWebRTCStreamer() {
@@ -189,8 +189,8 @@ export default class WebRTCStreamerWrapper {
189
189
  webrtcMessage.rigId = message.rigId;
190
190
  webrtcMessage.webRTCConnectionType = message.webRTCConnectionType;
191
191
  webrtcMessage.sessionId = message.sessionId;
192
- webrtcMessage.userName = message.userName;
193
- webrtcMessage.rigOwnerUsername = message.rigOwnerUsername;
192
+ webrtcMessage.userId = message.userId;
193
+ webrtcMessage.rigOwnerUserId = message.rigOwnerUserId;
194
194
  webrtcMessage.messageType = 'getIceServersResponse';
195
195
  webrtcMessage.message = JSON.stringify(response.data);
196
196
  SignalR.SendWebRTCMessage(webrtcMessage);
@@ -249,13 +249,13 @@ export default class WebRTCStreamerWrapper {
249
249
  webrtcMessage.rigId = message.rigId;
250
250
  webrtcMessage.sessionId = message.sessionId;
251
251
  webrtcMessage.webRTCConnectionType = message.webRTCConnectionType;
252
- webrtcMessage.userName = message.userName;
253
- webrtcMessage.rigOwnerUsername = message.rigOwnerUsername;
252
+ webrtcMessage.userId = message.userId;
253
+ webrtcMessage.rigOwnerUserId = message.rigOwnerUserId;
254
254
  webrtcMessage.messageType = 'onReceiveCall';
255
255
  webrtcMessage.message = JSON.stringify(response.data);
256
256
  SignalR.SendWebRTCMessage(webrtcMessage);
257
257
  // Start polling voor ICE candidates van de server
258
- this.StartIceCandidatePolling(message.sessionId, message.rigId, message.userName, message.rigOwnerUsername, message.webRTCConnectionType);
258
+ this.StartIceCandidatePolling(message.sessionId, message.rigId, message.userId, message.rigOwnerUserId, message.webRTCConnectionType);
259
259
  }
260
260
  else {
261
261
  this.Error("devicePath is empty");
@@ -324,8 +324,8 @@ export default class WebRTCStreamerWrapper {
324
324
  webrtcMessage.rigId = message.rigId;
325
325
  webrtcMessage.webRTCConnectionType = message.webRTCConnectionType;
326
326
  webrtcMessage.sessionId = message.sessionId;
327
- webrtcMessage.userName = message.userName;
328
- webrtcMessage.rigOwnerUsername = message.rigOwnerUsername;
327
+ webrtcMessage.userId = message.userId;
328
+ webrtcMessage.rigOwnerUserId = message.rigOwnerUserId;
329
329
  webrtcMessage.messageType = 'receiveOffer';
330
330
  //webrtcMessage.message = JSON.stringify(response.data);
331
331
  webrtcMessage.message = JSON.stringify({ ...response.data, sdp });
@@ -355,7 +355,7 @@ export default class WebRTCStreamerWrapper {
355
355
  const response = await this.streamerClient.post(setAnswerUrl, tJSON);
356
356
  this.Log("SetAnswer Response status: " + response.status);
357
357
  this.Log("SetAnswer Response data:\\r\\n" + JSON.stringify(response.data?.sdp));
358
- this.StartIceCandidatePolling(message.sessionId, message.rigId, message.userName, message.rigOwnerUsername, message.webRTCConnectionType);
358
+ this.StartIceCandidatePolling(message.sessionId, message.rigId, message.userId, message.rigOwnerUserId, message.webRTCConnectionType);
359
359
  }
360
360
  catch (err) {
361
361
  if (err.response) {
@@ -365,7 +365,7 @@ export default class WebRTCStreamerWrapper {
365
365
  this.Error("SetAnswer Call error: " + err.message);
366
366
  }
367
367
  }
368
- StartIceCandidatePolling(peerId, rigId, userName, rigOwnerUsername, webRTCConnectionType) {
368
+ StartIceCandidatePolling(peerId, rigId, userId, rigOwnerUserId, webRTCConnectionType) {
369
369
  // Stop eventuele bestaande polling voor deze peer
370
370
  this.StopIceCandidatePolling(peerId);
371
371
  // Initialiseer candidate tracking voor deze peer
@@ -401,8 +401,8 @@ export default class WebRTCStreamerWrapper {
401
401
  webrtcMessage.rigId = rigId;
402
402
  webrtcMessage.sessionId = peerId;
403
403
  webrtcMessage.webRTCConnectionType = webRTCConnectionType;
404
- webrtcMessage.userName = userName;
405
- webrtcMessage.rigOwnerUsername = rigOwnerUsername;
404
+ webrtcMessage.userId = userId;
405
+ webrtcMessage.rigOwnerUserId = rigOwnerUserId;
406
406
  webrtcMessage.messageType = 'onReceiveCandidate';
407
407
  webrtcMessage.message = JSON.stringify(candidate);
408
408
  SignalR.SendWebRTCMessage(webrtcMessage);
@@ -61,6 +61,7 @@ export default class Component {
61
61
  }
62
62
  this.Log("status: '" + this.component.status[i].name.toLowerCase() + "'");
63
63
  }
64
+ this.LoadStoredStatuses();
64
65
  for (var i = 0; i < this.component.codeBlocks.length; i++) {
65
66
  if (this.component.codeBlocks[i].type == CodeBlockType.Function) {
66
67
  try {
@@ -193,7 +194,7 @@ export default class Component {
193
194
  }
194
195
  PutWebRTCMessage(message) {
195
196
  if (this.component.id == message.componentId) {
196
- this.Log("PutWebRTCMessage userName: " + message.userName + " rigOwnerUsername: " + message.rigOwnerUsername);
197
+ this.Log("PutWebRTCMessage userId: " + message.userId + " rigOwnerUserId: " + message.rigOwnerUserId);
197
198
  if (this.streamer != null) {
198
199
  this.streamer.PutWebRTCMessage(message);
199
200
  }
@@ -232,6 +233,29 @@ export default class Component {
232
233
  }
233
234
  }
234
235
  }
236
+ LoadStoredStatuses() {
237
+ var componentStatuses = this.rig.rig.componentStatuses;
238
+ if (componentStatuses == undefined) {
239
+ return;
240
+ }
241
+ for (const key in this.status) {
242
+ var status = this.status[key];
243
+ if (!status.IsStored()) {
244
+ continue;
245
+ }
246
+ for (var i = 0; i < componentStatuses.length; i++) {
247
+ var stored = componentStatuses[i].value;
248
+ if (stored != undefined &&
249
+ stored.componentId == this.component.id &&
250
+ stored.statusId == status.GetStatusId() &&
251
+ stored.value != undefined && stored.value != null) {
252
+ status.LoadStoredValue(stored.value);
253
+ this.Log("stored status loaded: '" + key + "' = " + stored.value + (stored.valueStr ? " (" + stored.valueStr + ")" : ""));
254
+ break;
255
+ }
256
+ }
257
+ }
258
+ }
235
259
  SetCallback(callback) {
236
260
  this.callback = callback;
237
261
  }
@@ -262,7 +286,7 @@ export default class Component {
262
286
  }
263
287
  GetStatusState(status) {
264
288
  if (this.status.hasOwnProperty(status.toLowerCase())) {
265
- this.status[status.toLowerCase()].GetValueStr();
289
+ return this.status[status.toLowerCase()].GetValueStr();
266
290
  }
267
291
  return "";
268
292
  }
@@ -13,6 +13,19 @@ export default class Status {
13
13
  this.SendUpdateStatus(value);
14
14
  }
15
15
  }
16
+ /**
17
+ * Restore the last value stored on the server (only for statuses with 'store' enabled).
18
+ * Does not send an update; SendCurrent() will report it to the server.
19
+ */
20
+ LoadStoredValue(value) {
21
+ this.last_value = value;
22
+ }
23
+ IsStored() {
24
+ return this.status.store == true;
25
+ }
26
+ GetStatusId() {
27
+ return this.status.id;
28
+ }
16
29
  SendCurrent() {
17
30
  if (this.last_value != null) {
18
31
  this.SendUpdateStatus(this.last_value);
@@ -29,6 +29,7 @@ export class ComponentStatusViewModel {
29
29
  this.componentId = _data["componentId"];
30
30
  this.name = _data["name"];
31
31
  this.type = _data["type"];
32
+ this.store = _data["store"];
32
33
  if (Array.isArray(_data["states"])) {
33
34
  this.states = [];
34
35
  for (let item of _data["states"])
@@ -48,6 +49,7 @@ export class ComponentStatusViewModel {
48
49
  data["componentId"] = this.componentId;
49
50
  data["name"] = this.name;
50
51
  data["type"] = this.type;
52
+ data["store"] = this.store;
51
53
  if (Array.isArray(this.states)) {
52
54
  data["states"] = [];
53
55
  for (let item of this.states)
@@ -219,12 +221,12 @@ export class WebRTCMessage {
219
221
  }
220
222
  init(_data) {
221
223
  if (_data) {
222
- this.rigOwnerUsername = _data["rigOwnerUsername"];
224
+ this.rigOwnerUserId = _data["rigOwnerUserId"];
223
225
  this.rigId = _data["rigId"];
224
226
  this.componentId = _data["componentId"];
225
227
  this.webRTCConnectionType = _data["webRTCConnectionType"];
226
228
  this.sessionId = _data["sessionId"];
227
- this.userName = _data["userName"];
229
+ this.userId = _data["userId"];
228
230
  this.messageType = _data["messageType"];
229
231
  this.message = _data["message"];
230
232
  }
@@ -237,12 +239,12 @@ export class WebRTCMessage {
237
239
  }
238
240
  toJSON(data) {
239
241
  data = typeof data === 'object' ? data : {};
240
- data["rigOwnerUsername"] = this.rigOwnerUsername;
242
+ data["rigOwnerUserId"] = this.rigOwnerUserId;
241
243
  data["rigId"] = this.rigId;
242
244
  data["componentId"] = this.componentId;
243
245
  data["webRTCConnectionType"] = this.webRTCConnectionType;
244
246
  data["sessionId"] = this.sessionId;
245
- data["userName"] = this.userName;
247
+ data["userId"] = this.userId;
246
248
  data["messageType"] = this.messageType;
247
249
  data["message"] = this.message;
248
250
  return data;
@@ -308,6 +310,7 @@ export class RigClientViewModel {
308
310
  if (!data) {
309
311
  this.rigModelViewModel = new RigModelViewModel();
310
312
  this.logSettings = [];
313
+ this.componentStatuses = [];
311
314
  }
312
315
  }
313
316
  init(_data) {
@@ -323,6 +326,11 @@ export class RigClientViewModel {
323
326
  for (let item of _data["logSettings"])
324
327
  this.logSettings.push(LogSettingViewModel.fromJS(item));
325
328
  }
329
+ if (Array.isArray(_data["componentStatuses"])) {
330
+ this.componentStatuses = [];
331
+ for (let item of _data["componentStatuses"])
332
+ this.componentStatuses.push(StatusModel.fromJS(item));
333
+ }
326
334
  }
327
335
  }
328
336
  static fromJS(data) {
@@ -344,6 +352,11 @@ export class RigClientViewModel {
344
352
  for (let item of this.logSettings)
345
353
  data["logSettings"].push(item ? item.toJSON() : undefined);
346
354
  }
355
+ if (Array.isArray(this.componentStatuses)) {
356
+ data["componentStatuses"] = [];
357
+ for (let item of this.componentStatuses)
358
+ data["componentStatuses"].push(item ? item.toJSON() : undefined);
359
+ }
347
360
  return data;
348
361
  }
349
362
  }