From 7fbfe86634a0265b0761fdef4275b7c2b1fca961 Mon Sep 17 00:00:00 2001 From: Alex Mikhalev Date: Sun, 19 Aug 2018 19:25:26 -0600 Subject: [PATCH] Refactored out ws sprinklers client classes --- client/sprinklersRpc/WSSprinklersDevice.ts | 61 +++++++++++++++ client/sprinklersRpc/WebSocketRpcClient.ts | 91 ++++------------------ 2 files changed, 77 insertions(+), 75 deletions(-) create mode 100644 client/sprinklersRpc/WSSprinklersDevice.ts diff --git a/client/sprinklersRpc/WSSprinklersDevice.ts b/client/sprinklersRpc/WSSprinklersDevice.ts new file mode 100644 index 0000000..43c819c --- /dev/null +++ b/client/sprinklersRpc/WSSprinklersDevice.ts @@ -0,0 +1,61 @@ +import { autorun, runInAction, when } from "mobx"; + +import { ErrorCode } from "@common/ErrorCode"; +import * as deviceRequests from "@common/sprinklersRpc/deviceRequests"; +import * as s from "@common/sprinklersRpc/index"; +import * as ws from "@common/sprinklersRpc/websocketData"; +import { log, WebSocketRpcClient } from "./WebSocketRpcClient"; + +// tslint:disable:member-ordering +export class WSSprinklersDevice extends s.SprinklersDevice { + readonly api: WebSocketRpcClient; + private _id: string; + constructor(api: WebSocketRpcClient, id: string) { + super(); + this.api = api; + this._id = id; + autorun(this.updateConnectionState); + this.waitSubscribe(); + } + get id() { + return this._id; + } + private updateConnectionState = () => { + const { clientToServer, serverToBroker } = this.api.connectionState; + runInAction("updateConnectionState", () => { + Object.assign(this.connectionState, { clientToServer, serverToBroker }); + }); + } + + async subscribe() { + const subscribeRequest: ws.IDeviceSubscribeRequest = { + deviceId: this.id, + }; + try { + await this.api.makeRequest("deviceSubscribe", subscribeRequest); + runInAction("deviceSubscribeSuccess", () => { + this.connectionState.brokerToDevice = true; + }); + } catch (err) { + runInAction("deviceSubscribeError", () => { + this.connectionState.brokerToDevice = false; + if ((err as ws.IError).code === ErrorCode.NoPermission) { + this.connectionState.hasPermission = false; + } else { + log.error({ err }); + } + }); + } + } + + makeRequest(request: deviceRequests.Request): Promise { + return this.api.makeDeviceCall(this.id, request); + } + + waitSubscribe = () => { + when(() => this.api.authenticated, () => { + this.subscribe(); + when(() => !this.api.authenticated, this.waitSubscribe); + }); + } +} diff --git a/client/sprinklersRpc/WebSocketRpcClient.ts b/client/sprinklersRpc/WebSocketRpcClient.ts index 0f19ba5..ff0bb0f 100644 --- a/client/sprinklersRpc/WebSocketRpcClient.ts +++ b/client/sprinklersRpc/WebSocketRpcClient.ts @@ -1,4 +1,4 @@ -import { action, autorun, observable, runInAction, when } from "mobx"; +import { action, observable, runInAction, when } from "mobx"; import { update } from "serializr"; import { TokenStore } from "@client/state/TokenStore"; @@ -12,8 +12,9 @@ import * as schema from "@common/sprinklersRpc/schema/index"; import { seralizeRequest } from "@common/sprinklersRpc/schema/requests"; import * as ws from "@common/sprinklersRpc/websocketData"; import { DefaultEvents, TypedEventEmitter } from "@common/TypedEventEmitter"; +import { WSSprinklersDevice } from "./WSSprinklersDevice"; -const log = logger.child({ source: "websocket" }); +export const log = logger.child({ source: "websocket" }); const TIMEOUT_MS = 5000; const RECONNECT_TIMEOUT_MS = 5000; @@ -24,66 +25,6 @@ const websocketPort = isDev ? 8080 : location.port; const DEFAULT_URL = `${websocketProtocol}//${location.hostname}:${websocketPort}`; -// tslint:disable:member-ordering - -export class WSSprinklersDevice extends s.SprinklersDevice { - readonly api: WebSocketRpcClient; - - private _id: string; - - constructor(api: WebSocketRpcClient, id: string) { - super(); - this.api = api; - this._id = id; - - autorun(this.updateConnectionState); - this.waitSubscribe(); - } - - get id() { - return this._id; - } - - private updateConnectionState = () => { - const { clientToServer, serverToBroker } = this.api.connectionState; - runInAction("updateConnectionState", () => { - Object.assign(this.connectionState, { clientToServer, serverToBroker }); - }); - } - - async subscribe() { - const subscribeRequest: ws.IDeviceSubscribeRequest = { - deviceId: this.id, - }; - try { - await this.api.makeRequest("deviceSubscribe", subscribeRequest); - runInAction("deviceSubscribeSuccess", () => { - this.connectionState.brokerToDevice = true; - }); - } catch (err) { - runInAction("deviceSubscribeError", () => { - this.connectionState.brokerToDevice = false; - if ((err as ws.IError).code === ErrorCode.NoPermission) { - this.connectionState.hasPermission = false; - } else { - log.error({ err }); - } - }); - } - } - - makeRequest(request: deviceRequests.Request): Promise { - return this.api.makeDeviceCall(this.id, request); - } - - waitSubscribe = () => { - when(() => this.api.authenticated, () => { - this.subscribe(); - when(() => !this.api.authenticated, this.waitSubscribe); - }); - } -} - export interface WebSocketRpcClientEvents extends DefaultEvents { newUserData(userData: IUser): void; rpcError(error: ws.RpcError): void; @@ -91,6 +32,10 @@ export interface WebSocketRpcClientEvents extends DefaultEvents { } export class WebSocketRpcClient extends TypedEventEmitter implements s.SprinklersRPC { + + get connected(): boolean { + return this.connectionState.isServerConnected || false; + } readonly webSocketUrl: string; devices: Map = new Map(); @@ -106,9 +51,15 @@ export class WebSocketRpcClient extends TypedEventEmitter { + this.connectionState.serverToBroker = null; + this.connectionState.clientToServer = false; + this.authenticated = false; + }); + + private notificationHandlers = new WSClientNotificationHandlers(this); constructor(tokenStore: TokenStore, webSocketUrl: string = DEFAULT_URL) { super(); @@ -263,14 +214,6 @@ export class WebSocketRpcClient extends TypedEventEmitter { - this.connectionState.serverToBroker = null; - this.connectionState.clientToServer = false; - this.authenticated = false; - }); - private onClose(event: CloseEvent) { log.info({ event }, "disconnected from websocket"); @@ -321,8 +264,6 @@ export class WebSocketRpcClient extends TypedEventEmitter