Просмотр исходного кода

Implement correct state handling with Relayed Data Task

Danilo Bargen 7 лет назад
Родитель
Сommit
8e9faa886b
5 измененных файлов с 43 добавлено и 21 удалено
  1. 3 1
      src/controllers/status.ts
  2. 3 1
      src/partials/welcome.ts
  3. 27 13
      src/services/state.ts
  4. 2 2
      src/services/webclient.ts
  5. 8 4
      src/threema.d.ts

+ 3 - 1
src/controllers/status.ts

@@ -19,6 +19,8 @@ import {ControllerService} from '../services/controller';
 import {StateService} from '../services/state';
 import {WebClientService} from '../services/webclient';
 
+import GlobalConnectionState = threema.GlobalConnectionState;
+
 /**
  * This controller handles state changes globally.
  *
@@ -31,7 +33,7 @@ export class StatusController {
     private logTag: string = '[StatusController]';
 
     // State variable
-    private state: threema.GlobalConnectionState = 'error';
+    private state = GlobalConnectionState.Error;
 
     // Expanded status bar
     public expandStatusBar = false;

+ 3 - 1
src/partials/welcome.ts

@@ -27,6 +27,8 @@ import {StateService} from '../services/state';
 import {VersionService} from '../services/version';
 import {WebClientService} from '../services/webclient';
 
+import GlobalConnectionState = threema.GlobalConnectionState;
+
 class DialogController {
     // TODO: This is also used in partials/messenger.ts. We could somehow
     // extract it into a separate file.
@@ -328,7 +330,7 @@ class WelcomeController {
                         this.$log.error(this.logTag, 'Session already connected in another tab or window');
                         this.$timeout(() => {
                             this.stateService.updateConnectionBuildupState('already_connected');
-                            this.stateService.state = 'error';
+                            this.stateService.state = GlobalConnectionState.Error;
                         }, 500);
                     }
                     break;

+ 27 - 13
src/services/state.ts

@@ -17,6 +17,14 @@
 
 import {AsyncEvent} from 'ts-events';
 
+import GlobalConnectionState = threema.GlobalConnectionState;
+import ChosenTask = threema.ChosenTask;
+
+const enum Stage {
+    Signaling,
+    Task,
+}
+
 export class StateService {
 
     private logTag: string = '[StateService]';
@@ -39,7 +47,7 @@ export class StateService {
     public slowConnect = false;
 
     // Global connection state
-    public stage: 'signaling' | 'rtc';
+    private stage: Stage;
     public state: threema.GlobalConnectionState;
     public wasConnected: boolean;
 
@@ -53,25 +61,29 @@ export class StateService {
     /**
      * Signaling connection state.
      */
-    public updateSignalingConnectionState(state: saltyrtc.SignalingState): void {
+    public updateSignalingConnectionState(state: saltyrtc.SignalingState, chosenTask: ChosenTask): void {
         const prevState = this.signalingConnectionState;
         this.signalingConnectionState = state;
-        if (this.stage === 'signaling') {
+        if (this.stage === Stage.Signaling) {
             this.$log.debug(this.logTag, 'Signaling connection state:', prevState, '=>', state);
             switch (state) {
                 case 'new':
                 case 'ws-connecting':
                 case 'server-handshake':
                 case 'peer-handshake':
-                    this.state = 'warning';
+                    this.state = GlobalConnectionState.Warning;
                     break;
                 case 'task':
-                    this.state = 'warning';
-                    this.stage = 'rtc';
+                    if (chosenTask === ChosenTask.RelayedData) {
+                        this.state = GlobalConnectionState.Ok;
+                    } else {
+                        this.state = GlobalConnectionState.Warning;
+                    }
+                    this.stage = Stage.Task;
                     break;
                 case 'closing':
                 case 'closed':
-                    this.state = 'error';
+                    this.state = GlobalConnectionState.Error;
                     break;
                 default:
                     this.$log.warn(this.logTag, 'Ignored signaling connection state change to', state);
@@ -83,23 +95,25 @@ export class StateService {
 
     /**
      * RTC connection state.
+     *
+     * This is only called if the WebRTC task is active.
      */
     public updateRtcConnectionState(state: threema.RTCConnectionState): void {
         const prevState = this.rtcConnectionState;
         this.rtcConnectionState = state;
-        if (this.stage === 'rtc') {
+        if (this.stage === Stage.Task) {
             this.$log.debug(this.logTag, 'RTC connection state:', prevState, '=>', state);
             switch (state) {
                 case 'new':
                 case 'connecting':
-                    this.state = 'warning';
+                    this.state = GlobalConnectionState.Warning;
                     break;
                 case 'connected':
-                    this.state = 'ok';
+                    this.state = GlobalConnectionState.Ok;
                     this.wasConnected = true;
                     break;
                 case 'disconnected':
-                    this.state = 'error';
+                    this.state = GlobalConnectionState.Error;
                     break;
                 default:
                     this.$log.warn(this.logTag, 'Ignored RTC connection state change to', state);
@@ -202,8 +216,8 @@ export class StateService {
         // Reset state
         this.signalingConnectionState = 'new';
         this.rtcConnectionState = 'new';
-        this.stage = 'signaling';
-        this.state = 'error';
+        this.stage = Stage.Signaling;
+        this.state = GlobalConnectionState.Error;
         this.wasConnected = false;
         this.connectionBuildupState = 'connecting';
     }

+ 2 - 2
src/services/webclient.ts

@@ -381,7 +381,7 @@ export class WebClientService {
                             this.$log.warn(this.logTag, 'Unknown signaling state:', state);
                     }
                 }
-                this.stateService.updateSignalingConnectionState(state);
+                this.stateService.updateSignalingConnectionState(state, this.chosenTask);
             }, 0);
         });
 
@@ -1424,7 +1424,7 @@ export class WebClientService {
 
     private _requestInitialData(): void {
         // If all conversations are reloaded, clear the message cache
-        // to get in sync (we dont know if a message was removed, updated etc..)
+        // to get in sync (we don't know if a message was removed, updated etc..)
         this.messages.clear(this.$rootScope);
 
         // Request initial data

+ 8 - 4
src/threema.d.ts

@@ -325,7 +325,11 @@ declare namespace threema {
     /**
      * Connection state of the WebRTC peer connection.
      */
-    type GlobalConnectionState = 'ok' | 'warning' | 'error';
+    const enum GlobalConnectionState {
+        Ok = 'ok',
+        Warning = 'warning',
+        Error = 'error',
+    }
 
     /**
      * Type of message to be sent to a receiver.
@@ -591,9 +595,9 @@ declare namespace threema {
     }
 
     const enum ChosenTask {
-        None = 'none',
-        WebRTC = 'webrtc',
-        RelayedData = 'relayed-data',
+        None,
+        WebRTC,
+        RelayedData,
     }
 
     namespace Container {