diff --git a/src/common/ClientConnection.ts b/src/common/ClientConnection.ts index 641c90b..cfd4fad 100644 --- a/src/common/ClientConnection.ts +++ b/src/common/ClientConnection.ts @@ -1,3 +1,4 @@ +import { ConnectTableEntity } from "./../entities/ConnectTableEntity"; import { PollingEntity } from "./../entities/PollingEntity"; import ReconnectingWebSocket from "reconnecting-websocket"; import NormalWindowRequestEntity from "src/entities/NormalWindowRequestEntity"; @@ -970,6 +971,17 @@ export default class ClientConnection { ); } + public async getConnectList() { + return await this.doRpc( + new Protocol.GetConnectionListRequestEntity() + ); + } + public async setConnectItem(entity: ConnectTableEntity) { + return await this.doRpc( + new Protocol.SetConnectionItemRequestEntity(entity) + ); + } + public destory() { if (this.ws) { this.ws.onclose = null; diff --git a/src/common/EventBus.ts b/src/common/EventBus.ts index 31f1806..ffa7ebe 100644 --- a/src/common/EventBus.ts +++ b/src/common/EventBus.ts @@ -31,4 +31,5 @@ export namespace EventNamesDefine { export const WebSocketConnected = "onWebSocketConnected"; export const CurrentConnectDisconnect = "onCurrentConnectDisconnect"; export const CurrentConnectConnected = "onCurrentConnectConnected"; + export const CurrentClientChanged = "onCurrentClientChanged"; } diff --git a/src/common/GlobalData.ts b/src/common/GlobalData.ts index 5008731..ca49bb2 100644 --- a/src/common/GlobalData.ts +++ b/src/common/GlobalData.ts @@ -182,7 +182,9 @@ export default class GlobalData { removeClient(name: string | null) { if (name) { + const connection = this.clients.get(name); this.clients.delete(name); + connection?.destory(); } } } diff --git a/src/entities/ConnectTableEntity.ts b/src/entities/ConnectTableEntity.ts new file mode 100644 index 0000000..39d2ef9 --- /dev/null +++ b/src/entities/ConnectTableEntity.ts @@ -0,0 +1,11 @@ +import BaseEntity from "./BaseEntity"; + +export class ConnectTableEntity extends BaseEntity { + static WSType = "websocket"; + + type = ""; + host = ""; + name = ""; + user = ""; + password = ""; +} diff --git a/src/entities/WSProtocol.ts b/src/entities/WSProtocol.ts index 052e6a9..ad36544 100644 --- a/src/entities/WSProtocol.ts +++ b/src/entities/WSProtocol.ts @@ -8,6 +8,7 @@ import { PollingEntity, PollingGroupEntity } from "./PollingEntity"; import { EdgeBlendingPoint } from "./EdgeBlendingEntities"; import { ExternalControlTableEntity } from "./ExternalControlTableEntity"; import { SerialPortConfigEntity } from "./SerialPortConfigEntity"; +import { ConnectTableEntity } from "./ConnectTableEntity"; export namespace Protocol { export class Commands { @@ -378,6 +379,12 @@ export namespace Protocol { public static get kRpcSetExternalControlSerialPortConfig() { return Commands.PROTOCOL_PREFIX + "RpcSetExternalControlSerialPortConfig"; } + public static get kRpcGetConnectionList() { + return Commands.PROTOCOL_PREFIX + "RpcGetConnectionList"; + } + public static get kRpcSetConnectionItem() { + return Commands.PROTOCOL_PREFIX + "RpcSetConnectionItem"; + } static _all_commands = new Set([ Commands.kUnKnowCommand, @@ -473,6 +480,8 @@ export namespace Protocol { Commands.kCallExternalControlData, Commands.kRpcGetExternalControlSerialPortConfig, Commands.kRpcSetExternalControlSerialPortConfig, + Commands.kRpcGetConnectionList, + Commands.kRpcSetConnectionItem, ]); public static get AllCommands() { @@ -2264,7 +2273,6 @@ export namespace Protocol { super(); super.flag = PacketEntity.FLAG_RESPONSE; } - RpcDeleteExternalControlDataResponseEntity() {} success = false; } @@ -2297,7 +2305,6 @@ export namespace Protocol { super(); super.flag = PacketEntity.FLAG_RESPONSE; } - RpcEditExternalControlDataResponseEntity() {} success = false; } @@ -2330,7 +2337,6 @@ export namespace Protocol { super(); super.flag = PacketEntity.FLAG_RESPONSE; } - RpcAddExternalControlDataResponseEntity() {} success = false; } @@ -2347,15 +2353,15 @@ export namespace Protocol { } export class CallExternalControlDataRequestEntity extends PacketEntity { - constructor(uuid:string) { + constructor(uuid: string) { super(); super.command = Commands.kCallExternalControlData; super.flag = PacketEntity.FLAG_REQUEST; super.rpc_id = 0; - this.uuid = uuid + this.uuid = uuid; } - uuid:string; + uuid: string; } export class RpcGetExternalControlSerialPortConfigRequestEntity extends PacketEntity { @@ -2374,7 +2380,6 @@ export namespace Protocol { super(); super.flag = PacketEntity.FLAG_RESPONSE; } - RpcGetExternalControlSerialPortConfigResponseEntity() {} config = new SerialPortConfigEntity(); } @@ -2396,7 +2401,47 @@ export namespace Protocol { super(); super.flag = PacketEntity.FLAG_RESPONSE; } - RpcSetExternalControlSerialPortConfigResponseEntity() {} + + success = false; + } + + export class GetConnectionListRequestEntity extends PacketEntity { + constructor(rpc_id = 0) { + super(); + super.command = Commands.kRpcGetConnectionList; + super.flag = PacketEntity.FLAG_REQUEST; + super.rpc_id = rpc_id; + } + + timestamp = 0; + } + + export class GetConnectionListResponseEntity extends PacketEntity { + constructor() { + super(); + super.flag = PacketEntity.FLAG_RESPONSE; + } + + connects: ConnectTableEntity[] = []; + } + + export class SetConnectionItemRequestEntity extends PacketEntity { + constructor(entity: ConnectTableEntity, rpc_id = 0) { + super(); + super.command = Commands.kRpcSetConnectionItem; + super.flag = PacketEntity.FLAG_REQUEST; + super.rpc_id = rpc_id; + this.entity = entity; + } + + entity: ConnectTableEntity; + } + + export class SetConnectionItemResponseEntity extends PacketEntity { + constructor() { + super(); + super.flag = PacketEntity.FLAG_RESPONSE; + } success = false; } diff --git a/src/i18n/zh-CN/index.ts b/src/i18n/zh-CN/index.ts index 95ae568..f57be36 100644 --- a/src/i18n/zh-CN/index.ts +++ b/src/i18n/zh-CN/index.ts @@ -460,4 +460,8 @@ export default { button: "按钮", "send power on command": "发送开机指令", "send power off command": "发送关机指令", + client: "客户端", + connection: "连接中", + "please check ipaddress or username or password": + "请检查用户名或用户名或密码", }; diff --git a/src/pages/Index.vue b/src/pages/Index.vue index e2268f1..aa92be4 100644 --- a/src/pages/Index.vue +++ b/src/pages/Index.vue @@ -66,6 +66,10 @@ export default defineComponent({ GlobalData.getInstance().getCurrentClientName() ); + EventBus.getInstance().on(EventNamesDefine.CurrentClientChanged, () => { + new Initializer(options).initialize(); + }); + return {}; }, }); diff --git a/src/pages/Login.vue b/src/pages/Login.vue index a548e7d..16f79f8 100644 --- a/src/pages/Login.vue +++ b/src/pages/Login.vue @@ -351,6 +351,7 @@ export default defineComponent({ if (is_login && web_socket) { global_data.addClient(data.ip_address, web_socket); global_data.setCurrentClientName(data.ip_address); + SessionStorage.set("auth", PermissionLevel.Root); SessionStorage.set("url", url); SessionStorage.set("name", data.ip_address); @@ -362,6 +363,8 @@ export default defineComponent({ : Md5.hashStr(data.password ?? "admin") ); + // TODO add self to setConnects + if (remember_password.value) { Cookies.set("remember_password", JSON.stringify(true)); Cookies.set("auto_login", JSON.stringify(auto_login.value)); diff --git a/src/pages/TopToolBar.vue b/src/pages/TopToolBar.vue index 42dea72..154931e 100644 --- a/src/pages/TopToolBar.vue +++ b/src/pages/TopToolBar.vue @@ -35,6 +35,31 @@ class="q-mr-sm" > +
+
+ + + + + + + {{ item.name ? item.name : $t("client") + index }} + + + {{ item.host }} + + + +
+
@@ -356,6 +381,8 @@ import { date as $date, } from "quasar"; import { useI18n } from "vue-i18n"; +import { ConnectTableEntity } from "src/entities/ConnectTableEntity"; +import ClientConnection from "src/common/ClientConnection"; export default defineComponent({ name: "PageTopToolBar", @@ -463,6 +490,20 @@ export default defineComponent({ }; setInterval(checkRegistered, 5000); + EventBus.getInstance().on( + EventNamesDefine.CurrentConnectConnected, + async () => { + try { + const client = GlobalData.getInstance().getCurrentClient(); + if (client) { + const response = await client.getConnectList(); + if (response) { + $store.commit("setConnects", response.connects); + } + } + } catch {} + } + ); return { show_advanced_menu, plan_running, @@ -645,6 +686,71 @@ export default defineComponent({ timeout: 1500, }); }, + async changeHost(item: ConnectTableEntity) { + if (item) { + const url = + "ws://" + + item.host + + ":" + + GlobalData.kDefaultWebsocektPort.toString() + + GlobalData.kWebsocketResource; + const web_socket = new ClientConnection( + url, + item.user, + item.password + ); + $q.loading.hide(); + $q.loading.show({ + message: $t.t("connection") + "...", + }); + + const wait_for = (ms: number) => { + return new Promise((resolve, reject) => { + setTimeout(() => { + resolve(true); + }, ms); + }); + }; + + let login_success = false; + for (let i = 0; i < 20; ++i) { + await wait_for(500); + if (web_socket._is_login) { + login_success = true; + break; + } + } + + $q.loading.hide(); + + { + $q.notify({ + color: login_success ? "positive" : "negative", + icon: login_success ? "done" : "warning", + message: + $t.t("login") + + (login_success + ? $t.t("success") + : $t.t("fail") + + $t.t("please check ipaddress or username or password")) + + "!", + position: "top", + timeout: 1500, + }); + if (login_success) { + GlobalData.getInstance().addClient(item.host, web_socket); + GlobalData.getInstance().setCurrentClientName(item.host); + $store.commit("setDeviceIpAddress", item.host); + EventBus.getInstance().emit( + EventNamesDefine.CurrentClientChanged + ); + } else { + web_socket.destory(); + GlobalData.getInstance().removeClient(item.host); + } + } + } + }, }; }, }); diff --git a/src/store/index.ts b/src/store/index.ts index 36dcb6d..aeb4d61 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,3 +1,4 @@ +import { ConnectTableEntity } from "./../entities/ConnectTableEntity"; import { PollingEntity, PollingTreeItemEntity, @@ -52,6 +53,7 @@ export interface StateInterface { selected_window: string; selected_signal_source: string; current_running_plan: string; + connect_list: ConnectTableEntity[]; } // provide typings for `this.$store` @@ -291,6 +293,7 @@ export default store(function (/* { ssrContext } */) { selected_signal_source: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", current_running_plan: "", + connect_list: [], }, mutations: { @@ -831,6 +834,20 @@ export default store(function (/* { ssrContext } */) { setCurrentRunningPlan(state: StateInterface, playload?: any) { state.current_running_plan = playload; }, + setConnects(state: StateInterface, playload?: any) { + state.connect_list = playload; + }, + addConnectItem(state: StateInterface, playload?: any) { + state.connect_list.push(playload); + }, + cleanConnectItem(state: StateInterface, playload?: any) { + const index = state.connect_list.findIndex( + (element) => element && element.uuid == playload + ); + if (index != -1) { + state.connect_list.slice(index, 1); + } + }, }, // enable strict mode (adds overhead!)