media_player_client/src/common/ClientConnection.ts

1007 lines
26 KiB
TypeScript

import { ConnectTableEntity } from "./../entities/ConnectTableEntity";
import { PollingEntity } from "./../entities/PollingEntity";
import ReconnectingWebSocket from "reconnecting-websocket";
import NormalWindowRequestEntity from "src/entities/NormalWindowRequestEntity";
import { PlanEntity } from "src/entities/PlanEntity";
import { SignalSourceEntity } from "src/entities/SignalSourceEntity";
import { StringKeyValueEntity } from "src/entities/StringKeyValueEntity";
import SubtitleEntity from "src/entities/SubtitleEntity";
import { Protocol } from "src/entities/WSProtocol";
import EventBus, { EventNamesDefine } from "./EventBus";
import { EdgeBlendingPoint } from "src/entities/EdgeBlendingEntities";
import { ExternalControlTableEntity } from "src/entities/ExternalControlTableEntity";
import { SerialPortConfigEntity } from "src/entities/SerialPortConfigEntity";
class _RpcInfo {
send_timestamp: number;
timeout_timestamp: number;
callback: (is_fail: boolean, packet: Protocol.Commands, data: string) => void;
constructor(
timeout_timestamp: number,
callback: (
is_fail: boolean,
packet: Protocol.Commands,
data: string
) => void
) {
this.timeout_timestamp = timeout_timestamp;
this.send_timestamp = new Date().getTime();
this.callback = callback;
}
public reject() {
this.callback(true, new Protocol.Commands(), "");
}
public reslove(is_fail: boolean, packet: Protocol.Commands, data: string) {
this.callback(is_fail, packet, data);
}
}
export default class ClientConnection {
ws: ReconnectingWebSocket | null = null;
url = "";
user_name = "";
password = "";
_is_login = false;
_rpc_id_counter = 0;
rpc_map = new Map<number, _RpcInfo>();
public login_callback:
| ((this: ClientConnection, logined: boolean) => void)
| null = null;
constructor(
url: string,
user_name?: string | null,
password?: string | null
) {
this.url = url;
this.user_name = user_name ?? "";
this.password = password ?? "";
if (this.ws) {
this.ws.close();
}
this.ws = new ReconnectingWebSocket(url);
this.initializeWs();
setInterval(() => {
this.checkRpcTimeout();
}, 1000);
}
get is_connected() {
return this.ws && this.ws.readyState == WebSocket.OPEN;
}
get is_login() {
return this._is_login;
}
checkRpcTimeout() {
const current_datetime = new Date().getTime();
this.rpc_map.forEach((v, k, m) => {
if (current_datetime - v.send_timestamp > v.timeout_timestamp) {
v.reject();
m.delete(k);
}
});
}
initializeWs() {
if (this.ws) {
this.ws.onclose = (ev) => {
this.onClose(ev);
};
this.ws.onerror = (ev) => {
this.onError(ev);
};
this.ws.onopen = (ev) => {
this.onOpen(ev);
};
this.ws.onmessage = (ev) => {
this.onMessage(ev);
};
}
}
login() {
if (this.is_connected) {
const request = new Protocol.LoginRequest(this.user_name, this.password);
this.ws?.send(JSON.stringify(request));
}
}
onClose(ev: any) {
this._is_login = false;
EventBus.getInstance().emit(EventNamesDefine.WebSocketClose, this);
}
onError(ev: any) {
this._is_login = false;
EventBus.getInstance().emit(EventNamesDefine.WebSocketError, this);
}
onOpen(ev: any) {
this._is_login = false;
this.login();
}
onMessage(ev: MessageEvent) {
try {
const packet = JSON.parse(ev.data) as Protocol.PacketEntity;
if (packet) {
if (packet.has_exception) {
console.error(ev.data);
this.rpc_map.get(packet.rpc_id)?.reject();
this.rpc_map.delete(packet.rpc_id);
}
if (Protocol.Commands.AllCommands.has(packet.command)) {
if (
packet.flag == Protocol.PacketEntity.FLAG_RESPONSE ||
packet.flag == Protocol.PacketEntity.FLAG_NOTIFY
) {
if (packet.command == Protocol.Commands.kLogin) {
const login_response = JSON.parse(
ev.data
) as Protocol.LoginResponse;
if (login_response) {
this._is_login =
!login_response.has_exception && login_response.success;
if (this.is_login) {
EventBus.getInstance().emit(
EventNamesDefine.WebSocketConnected,
this
);
}
if (
this.login_callback &&
typeof this.login_callback == "function"
) {
this.login_callback(this._is_login);
}
}
} else if (this.rpc_map.has(packet.rpc_id)) {
this.rpc_map.get(packet.rpc_id)?.reslove(false, packet, ev.data);
this.rpc_map.delete(packet.rpc_id);
} else {
EventBus.getInstance().emit(
packet.flag == Protocol.PacketEntity.FLAG_NOTIFY
? EventNamesDefine.NotifyMessage
: packet.flag == Protocol.PacketEntity.FLAG_RESPONSE
? EventNamesDefine.ResponseMessage
: EventNamesDefine.UnKnow,
{
packet: packet,
data: ev.data,
}
);
}
}
} else {
console.error("unknow command: " + packet.command, packet);
}
}
} catch (e) {
console.error(e);
}
}
public async doRpc<_ResponseType>(
request: Protocol.PacketEntity
): Promise<_ResponseType | null> {
return new Promise((resolve, reject) => {
const rpc_id = ++this._rpc_id_counter;
if (this.rpc_map.has(rpc_id)) {
this.rpc_map.get(rpc_id)?.reject();
this.rpc_map.delete(rpc_id);
}
request.rpc_id = rpc_id;
this.rpc_map.set(
rpc_id,
new _RpcInfo(
request.timeout,
(is_fail: boolean, packet: Protocol.Commands, data: string) => {
if (is_fail) {
reject();
} else {
try {
const response = JSON.parse(data) as _ResponseType;
if (response) {
resolve(response);
} else {
reject();
}
} catch {
reject();
}
}
}
)
);
if (request) {
request.timeout;
}
this.ws?.send(JSON.stringify(request));
});
}
public async getSignalSources() {
try {
return await this.doRpc<Protocol.GetSignalSourcesResponse>(
new Protocol.GetSignalSourcesRequest()
);
} catch (e) {
console.error(e);
}
}
public async addSignalSourceGroup(parent_uuid: string, name: string) {
try {
return await this.doRpc<Protocol.AddSignalSourceGroupResponseEntity>(
new Protocol.AddSignalSourceGroupRequestEntity(0, parent_uuid, name)
);
} catch (e) {
console.error(e);
}
}
public async editSignalSourceGroup(uuid: string, name: string) {
try {
return await this.doRpc<Protocol.EditSignalSourceGroupResponseEntity>(
new Protocol.EditSignalSourceGroupRequestEntity(0, uuid, name)
);
} catch (e) {
console.error(e);
}
}
public async deleteSignalSourceGroup(uuid: string) {
try {
return await this.doRpc<Protocol.DeleteSignalSourceGroupResponseEntity>(
new Protocol.DeleteSignalSourceGroupRequestEntity(0, uuid)
);
} catch (e) {
console.error(e);
}
}
public async addSignalSource(item: SignalSourceEntity) {
try {
return await this.doRpc<Protocol.AddSignalSourceResponseEntity>(
new Protocol.AddSignalSourceRequestEntity(0, item)
);
} catch (e) {
console.error(e);
}
}
public async editSignalSource(item: SignalSourceEntity) {
try {
return await this.doRpc<Protocol.EditSignalSourceResponseEntity>(
new Protocol.EditSignalSourceRequestEntity(0, item)
);
} catch (e) {
console.error(e);
}
}
public async deleteSignalSource(uuid: string) {
try {
return await this.doRpc<Protocol.DeleteSignalSourceResponseEntity>(
new Protocol.DeleteSignalSourceRequestEntity(0, uuid)
);
} catch (e) {
console.error(e);
}
}
public async getModes() {
try {
return await this.doRpc<Protocol.GetModesResponseEntity>(
new Protocol.GetModesRequestEntity()
);
} catch (e) {
console.error(e);
}
}
public async addPlanGroup(group_uuid: string, name: string) {
try {
return await this.doRpc<Protocol.AddPlanGroupResponseEntity>(
new Protocol.AddPlanGroupRequestEntity(0, group_uuid, name)
);
} catch (e) {
console.error(e);
}
}
public async editPlanGroup(uuid: string, name: string) {
try {
return await this.doRpc<Protocol.EditPlanGroupResponseEntity>(
new Protocol.EditPlanGroupRequestEntity(0, uuid, name)
);
} catch (e) {
console.error(e);
}
}
public async deletePlanGroup(uuid: string) {
try {
return await this.doRpc<Protocol.DeletePlanGroupResponseEntity>(
new Protocol.DeletePlanGroupRequestEntity(0, uuid)
);
} catch (e) {
console.error(e);
}
}
public async addPlan(entity?: PlanEntity) {
try {
return await this.doRpc<Protocol.AddPlanResponseEntity>(
new Protocol.AddPlanRequestEntity(0, entity)
);
} catch (e) {
console.error(e);
}
}
public async editPlan(entity?: PlanEntity) {
try {
return await this.doRpc<Protocol.EditPlanResponseEntity>(
new Protocol.EditPlanRequestEntity(0, entity)
);
} catch (e) {
console.error(e);
}
}
public async deletePlan(uuid: string) {
try {
return await this.doRpc<Protocol.DeletePlanResponseEntity>(
new Protocol.DeletePlanRequestEntity(0, uuid)
);
} catch (e) {
console.error(e);
}
}
public async deletePollingGroup(uuid: string) {
try {
return await this.doRpc<Protocol.DeletePollingGroupResponseEntity>(
new Protocol.DeletePollingGroupRequestEntity(0, uuid)
);
} catch (e) {
console.error(e);
}
}
public async addPolling(
group_uuid: string,
name: string,
datas: StringKeyValueEntity[]
) {
try {
return await this.doRpc<Protocol.AddPollingResponseEntity>(
new Protocol.AddPollingRequestEntity(0, group_uuid, name, datas, "")
);
} catch (e) {
console.error(e);
}
}
public async editPolling(entity: PollingEntity) {
try {
return await this.doRpc<Protocol.EditPollingResponseEntity>(
new Protocol.EditPollingRequestEntity(0, entity)
);
} catch (e) {
console.error(e);
}
}
public async deletePolling(uuid: string) {
try {
return await this.doRpc<Protocol.DeletePollingResponseEntity>(
new Protocol.DeletePollingRequestEntity(0, uuid)
);
} catch (e) {
console.error(e);
}
}
public async getCurrentRunningPlan() {
try {
return await this.doRpc<Protocol.GetCurrentRunningPlanResponseEntity>(
new Protocol.GetCurrentRunningPlanRequestEntity(0)
);
} catch (e) {
console.error(e);
}
}
public runPlan(uuid: string) {
this.ws?.send(JSON.stringify(new Protocol.RunPlanRequestEntity(uuid)));
}
public stopCurrentRunningPlan() {
this.ws?.send(
JSON.stringify(new Protocol.StopCurrentRunningPlanRequestEntity())
);
}
public async getPlans() {
try {
return await this.doRpc<Protocol.GetPlansResponseEntity>(
new Protocol.GetPlansRequestEntity()
);
} catch (e) {
console.error(e);
}
}
public async addModeGroup(group_uuid: string, name: string) {
try {
return await this.doRpc<Protocol.AddModeGroupResponseEntity>(
new Protocol.AddModeGroupRequestEntity(0, group_uuid, name)
);
} catch (e) {
console.error(e);
}
}
public async editModeGroup(uuid: string, name: string) {
try {
return await this.doRpc<Protocol.EditModeGroupResponseEntity>(
new Protocol.EditModeGroupRequestEntity(0, uuid, name)
);
} catch (e) {
console.error(e);
}
}
public async updateModeWindowList(uuid: string) {
try {
return await this.doRpc<Protocol.UpdateModeWindowListResponseEntity>(
new Protocol.UpdateModeWindowListRequestEntity(0, uuid)
);
} catch (e) {
console.error(e);
}
}
public async deleteModeGroup(uuid: string) {
try {
return await this.doRpc<Protocol.DeleteModeGroupResponseEntity>(
new Protocol.DeleteModeGroupRequestEntity(0, uuid)
);
} catch (e) {
console.error(e);
}
}
public async addMode(group_uuid?: string, name?: string, index?: number) {
try {
return await this.doRpc<Protocol.AddModeResponseEntity>(
new Protocol.AddModeRequestEntity(0, name, group_uuid, index)
);
} catch (e) {
console.error(e);
}
}
public async editMode(uuid?: string, name?: string, index?: number) {
try {
return await this.doRpc<Protocol.EditModeResponseEntity>(
new Protocol.EditModeRequestEntity(0, name, uuid, index)
);
} catch (e) {
console.error(e);
}
}
public async deleteMode(uuid: string) {
try {
return await this.doRpc<Protocol.DeleteModeResponseEntity>(
new Protocol.DeleteModeRequestEntity(0, uuid)
);
} catch (e) {
console.error(e);
}
}
public callMode(uuid: string) {
this.ws?.send(JSON.stringify(new Protocol.CallModeRequestEntity(uuid)));
}
public async getApplicationSettins() {
try {
return await this.doRpc<Protocol.GetApplicationConfigResponseEntity>(
new Protocol.GetApplicationConfigRequestEntity()
);
} catch (e) {
console.error(e);
}
}
public async getWindows() {
try {
return await this.doRpc<Protocol.GetWindowsResponseEntity>(
new Protocol.GetWindowsRequestEntity()
);
} catch (e) {
console.error(e);
}
}
public moveWindow(window_id: number, x: number, y: number) {
this.ws?.send(
JSON.stringify(new Protocol.MoveWindowRequestEntity(window_id, x, y))
);
}
public resizeWindow(window_id: number, width: number, height: number) {
this.ws?.send(
JSON.stringify(
new Protocol.ResizeWindowRequestEntity(window_id, width, height)
)
);
}
public setWindowGeometry(
window_id: number,
x: number,
y: number,
width: number,
height: number,
limit: boolean = true
) {
this.ws?.send(
JSON.stringify(
new Protocol.SetWindowGeometryRequestEntity(
window_id,
x,
y,
width,
height,
limit
)
)
);
}
public closeWindow(window_id: number) {
this.ws?.send(
JSON.stringify(new Protocol.CloseWindowRequestEntity(window_id))
);
}
public openWindow(data: Protocol.OpenWindowRequestEntity) {
this.ws?.send(JSON.stringify(data));
}
public openPolling(data: Protocol.OpenPollingRequestEntity) {
this.ws?.send(JSON.stringify(data));
}
public focusIn(window_id: number) {
this.ws?.send(
JSON.stringify(
new NormalWindowRequestEntity(Protocol.Commands.kTopWindow, window_id)
)
);
}
public lowerWindow(window_id: number) {
this.ws?.send(
JSON.stringify(
new NormalWindowRequestEntity(Protocol.Commands.kLowerWindow, window_id)
)
);
}
public setWallRowCol(wall_row: number, wall_col: number) {
this.ws?.send(
JSON.stringify(
new Protocol.SetApplicationConfigRequestEntity(
0,
"wall_row",
wall_row.toString()
)
)
);
this.ws?.send(
JSON.stringify(
new Protocol.SetApplicationConfigRequestEntity(
0,
"wall_col",
wall_col.toString()
)
)
);
}
public setPowerOnPlan(uuid: string) {
this.ws?.send(
JSON.stringify(
new Protocol.SetApplicationConfigRequestEntity(0, "power_on_plan", uuid)
)
);
}
public windowFitGrid(window_id: number) {
this.ws?.send(
JSON.stringify(
new NormalWindowRequestEntity(
Protocol.Commands.kWindowFitGrid,
window_id
)
)
);
}
public windowFullScreen(window_id: number, full_screen: boolean) {
this.ws?.send(
JSON.stringify(new Protocol.WindowFullScreen(window_id, full_screen))
);
}
public async getSubtitle() {
try {
return await this.doRpc<Protocol.GetSubtitleResponseEntity>(
new Protocol.GetSubtitleRequestEntity(0)
);
} catch (e) {
console.error(e);
}
}
public async getRegisterInfo() {
try {
return await this.doRpc<Protocol.GetRegisterInfoResponseEntity>(
new Protocol.GetRegisterInfoRequestEntity(0)
);
} catch (e) {
console.error(e);
}
}
public async registerDevice(
register_code: string,
active_code: string,
online: boolean,
active_forever: boolean,
secret_key?: string,
hour?: number
) {
try {
return await this.doRpc<Protocol.RegisterDeviceResponseEntity>(
new Protocol.RegisterDeviceRequestEntity(
register_code,
active_code,
online,
active_forever,
secret_key,
hour,
0
)
);
} catch (e) {
console.error(e);
}
}
public async setSubtitle(subtitle: SubtitleEntity) {
try {
return await this.doRpc<Protocol.SetSubtitleResponseEntity>(
new Protocol.SetSubtitleRequestEntity(0, subtitle)
);
} catch (e) {
console.error(e);
}
}
public async setSystemNetwork(
request: Protocol.SetSystemNetworkRequestEntity
) {
return await this.doRpc<Protocol.SetSystemNetworkResponseEntity>(request);
}
public async setSystemGraphics(
request: Protocol.SetSystemGraphicsRequestEntity
) {
return await this.doRpc<Protocol.SetSystemGraphicsResponseEntity>(request);
}
public async setSystemOther(request: Protocol.SetSystemOtherRequestEntity) {
return await this.doRpc<Protocol.SetSystemOtherResponseEntity>(request);
}
public async getSupportResolutions() {
try {
return await this.doRpc<Protocol.GetSupportResolutionsResponseEntity>(
new Protocol.GetSupportResolutionsRequestEntity(0)
);
} catch (e) {
console.error(e);
}
}
public async getOutputBoardSetting() {
try {
return await this.doRpc<Protocol.GetOutputBoardSettingResponseEntity>(
new Protocol.GetOutputBoardSettingRequestEntity(0)
);
} catch (e) {
console.error(e);
}
}
public async setOutputBoardSetting(
request: Protocol.SetOutputBoardSettingRequestEntity
) {
try {
return await this.doRpc<Protocol.SetOutputBoardSettingResponseEntity>(
request
);
} catch (e) {
console.error(e);
}
}
public async restoreOutputBoard() {
try {
return await this.doRpc<Protocol.RestoreOutputBoardResponseEntity>(
new Protocol.RestoreOutputBoardRequestEntity(0)
);
} catch (e) {
console.error(e);
}
}
public async setWindowVolume(window_id: number, volume: number) {
this.ws?.send(
JSON.stringify(
new Protocol.SetWindowVolumeRequestEntity(window_id, volume, 0)
)
);
}
public async unmuteWindow(window_id: number) {
this.ws?.send(
JSON.stringify(new Protocol.UnMuteWindowRequestEntity(window_id, 0))
);
}
public async muteWindow(window_id: number) {
this.ws?.send(
JSON.stringify(new Protocol.MuteWindowRequestEntity(window_id, 0))
);
}
public async playWindow(window_id: number) {
this.ws?.send(
JSON.stringify(new Protocol.PlayWindowRequestEntity(window_id, 0))
);
}
public async windowPlayNext(window_id: number) {
this.ws?.send(
JSON.stringify(new Protocol.WindowPlayNextRequestEntity(window_id, 0))
);
}
public async windowPlayPrev(window_id: number) {
this.ws?.send(
JSON.stringify(new Protocol.WindowPlayPrevRequestEntity(window_id, 0))
);
}
public async pauseWindow(window_id: number) {
this.ws?.send(
JSON.stringify(new Protocol.PauseWindowRequestEntity(window_id, 0))
);
}
public async startPolling(window_id: number) {
this.ws?.send(
JSON.stringify(new Protocol.StartPollingRequestEntity(window_id))
);
}
public async stopPolling(window_id: number) {
this.ws?.send(
JSON.stringify(new Protocol.StopPollingRequestEntity(window_id))
);
}
public async setWindowPollingData(
window_id: number,
name: string,
datas?: StringKeyValueEntity[]
) {
return await this.doRpc<Protocol.SetWindowPollingDataResponseEntity>(
new Protocol.SetWindowPollingDataRequestEntity(window_id, name, datas)
);
}
public async getBuildInfo() {
return await this.doRpc<Protocol.GetBuildInfoResponseEntity>(
new Protocol.GetBuildInfoRequestEntity(0)
);
}
public async getSystemTimes() {
return await this.doRpc<Protocol.GetSystemTimesResponseEntity>(
new Protocol.GetSystemTimesRequestEntity(0)
);
}
public restartDevice(delay_ms?: number) {
this.ws?.send(
JSON.stringify(new Protocol.RestartDeviceRequestEntity(delay_ms))
);
}
public async getUsbDevices() {
try {
return await this.doRpc<Protocol.GetUsbDevicesResponseEntity>(
new Protocol.GetUsbDevicesRequestEntity(0)
);
} catch (e) {
console.error(e);
}
}
public async getPollings() {
try {
return await this.doRpc<Protocol.GetPollingsResponseEntity>(
new Protocol.GetPollingsRequestEntity()
);
} catch (e) {
console.error(e);
}
}
public async fileOperator(
from_path: string,
to_path: string,
operator_type: string,
force_operator: boolean = true
) {
try {
return await this.doRpc<Protocol.FileOperatorResponseEntity>(
new Protocol.FileOperatorRequestEntity(
from_path,
to_path,
operator_type,
force_operator
)
);
} catch (e) {
console.error(e);
}
}
public async getEdgeBlendingInfo() {
return await this.doRpc<Protocol.GetEdgeBlendingInfoResponseEntity>(
new Protocol.GetEdgeBlendingInfoRequestEntity(0)
);
}
public async setEdgeBlendingInfo(
enable_blending: boolean,
enable_correct: boolean,
width: number,
height: number,
col: number,
row: number,
point_count: number
) {
return await this.doRpc<Protocol.SetEdgeBlendingInfoResponseEntity>(
new Protocol.SetEdgeBlendingInfoRequestEntity(
enable_blending,
enable_correct,
width,
height,
col,
row,
point_count,
0
)
);
}
public async wakeUpDevice() {
return await this.doRpc<Protocol.SetDevicePowerResponseEntity>(
new Protocol.SetDevicePowerRequestEntity(
Protocol.SetDevicePowerRequestEntity.kPowerStatePowerOn
)
);
}
public async deviceStandByMode() {
return await this.doRpc<Protocol.SetDevicePowerResponseEntity>(
new Protocol.SetDevicePowerRequestEntity(
Protocol.SetDevicePowerRequestEntity.kPowerStateStandBy
)
);
}
public async getExternalControlDatas() {
return await this.doRpc<Protocol.RpcGetExternalControlDatasResponseEntity>(
new Protocol.RpcGetExternalControlDatasRequestEntity()
);
}
public async deleteExternalControlData(uuid: string) {
return await this.doRpc<Protocol.RpcDeleteExternalControlDataResponseEntity>(
new Protocol.RpcDeleteExternalControlDataRequestEntity(uuid)
);
}
public async editExternalControlData(entity: ExternalControlTableEntity) {
return await this.doRpc<Protocol.RpcEditExternalControlDataResponseEntity>(
new Protocol.RpcEditExternalControlDataRequestEntity(entity)
);
}
public async addExternalControlData(entity: ExternalControlTableEntity) {
return await this.doRpc<Protocol.RpcAddExternalControlDataResponseEntity>(
new Protocol.RpcAddExternalControlDataRequestEntity(entity)
);
}
public async getExternalControlSerialPortConfig() {
return await this.doRpc<Protocol.RpcGetExternalControlSerialPortConfigResponseEntity>(
new Protocol.RpcGetExternalControlSerialPortConfigRequestEntity()
);
}
public async setExternalControlSerialPortConfig(
config: SerialPortConfigEntity
) {
return await this.doRpc<Protocol.RpcSetExternalControlSerialPortConfigResponseEntity>(
new Protocol.RpcSetExternalControlSerialPortConfigRequestEntity(config)
);
}
public callExternalControlData(uuid: string) {
this.ws?.send(
JSON.stringify(new Protocol.CallExternalControlDataRequestEntity(uuid))
);
}
public setEdgeBlendingPoint(point: EdgeBlendingPoint) {
this.ws?.send(
JSON.stringify(new Protocol.SetEdgeBlendingPointRequestEntity(point))
);
}
public async getConnectList() {
return await this.doRpc<Protocol.GetConnectionListResponseEntity>(
new Protocol.GetConnectionListRequestEntity()
);
}
public async setConnectItem(entity: ConnectTableEntity) {
return await this.doRpc<Protocol.SetConnectionItemResponseEntity>(
new Protocol.SetConnectionItemRequestEntity(entity)
);
}
public destory() {
if (this.ws) {
this.ws.onclose = null;
this.ws.onerror = null;
this.ws.onopen = null;
this.ws.onmessage = null;
}
this.ws?.close();
this.ws = null;
}
}
export interface NotifyMessage {
packet: Protocol.PacketEntity;
data: string;
}