media_player_client/src/common/ClientConnection.ts

363 lines
9.4 KiB
TypeScript
Raw Normal View History

2021-08-09 10:59:16 +08:00
import NormalWindowRequestEntity from "src/entities/NormalWindowRequestEntity";
import { SignalSourceEntity } from "src/entities/SignalSourceEntity";
2021-08-05 14:23:45 +08:00
import { Protocol } from "src/entities/WSProtocol";
import EventBus, { EventNamesDefine } from "./EventBus";
2021-08-05 14:23:45 +08:00
export default class ClientConnection {
ws: WebSocket | null = null;
url = "";
user_name = "";
password = "";
_is_login = false;
_rpc_id_counter = 0;
rpc_map = new Map<
number,
(is_fail: boolean, packet: Protocol.Commands, data: string) => void
>();
public login_callback:
| ((this: ClientConnection, logined: boolean) => void)
| null = null;
constructor(
url: string,
user_name?: string | null,
password?: string | null
) {
this.reconnectTo(url, user_name, password);
}
get is_connected() {
return this.ws && this.ws.readyState == WebSocket.OPEN;
}
get is_login() {
return this._is_login;
}
public reconnectTo(
url: string,
user_name?: string | null,
password?: string | null
) {
2021-08-07 11:04:39 +08:00
if (this._destoryed) {
2021-08-09 10:59:16 +08:00
this.ws?.close();
this.ws = null;
2021-08-07 11:04:39 +08:00
return;
}
2021-08-05 14:23:45 +08:00
this.url = url;
this.user_name = user_name ?? "";
this.password = password ?? "";
if (this.ws) {
this.ws.close();
}
this.ws = new WebSocket(url);
this.initializeWs();
}
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() {
2021-08-09 10:59:16 +08:00
if (this._destoryed) {
this.ws?.close();
this.ws = null;
return;
}
2021-08-05 14:23:45 +08:00
if (this.is_connected) {
const request = new Protocol.LoginRequest(this.user_name, this.password);
this.ws?.send(JSON.stringify(request));
}
}
onClose(ev: CloseEvent) {
this._is_login = false;
2021-08-07 11:04:39 +08:00
this._reconnect();
EventBus.getInstance().emit(EventNamesDefine.WebSocketClose, this);
2021-08-05 14:23:45 +08:00
}
onError(ev: Event) {
this._is_login = false;
2021-08-07 11:04:39 +08:00
this._reconnect();
EventBus.getInstance().emit(EventNamesDefine.WebSocketError, this);
}
private _reconnectTimer: ReturnType<typeof setTimeout> | null = null;
private _reconnect() {
if (this._destoryed) {
2021-08-09 10:59:16 +08:00
this.ws?.close();
this.ws = null;
2021-08-07 11:04:39 +08:00
return;
}
if (
!this.ws ||
(this.ws.readyState != WebSocket.CONNECTING &&
this.ws.readyState != WebSocket.OPEN)
) {
if (this._reconnectTimer) {
clearTimeout(this._reconnectTimer);
this._reconnectTimer = null;
}
this._reconnectTimer = setTimeout(() => {
this.reconnectTo(this.url, this.user_name, this.password);
}, 3000);
}
2021-08-05 14:23:45 +08:00
}
onOpen(ev: Event) {
2021-08-09 10:59:16 +08:00
if (this._destoryed) {
this.ws?.close();
this.ws = null;
return;
}
2021-08-05 14:23:45 +08:00
this._is_login = false;
this.login();
}
onMessage(ev: MessageEvent) {
2021-08-09 10:59:16 +08:00
if (this._destoryed) {
this.ws?.close();
this.ws = null;
return;
}
2021-08-05 14:23:45 +08:00
try {
const packet = JSON.parse(ev.data) as Protocol.PacketEntity;
2021-08-05 14:23:45 +08:00
if (packet) {
if (packet.has_exception) {
console.error(ev.data);
}
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;
2021-08-07 11:04:39 +08:00
if (this.is_login) {
EventBus.getInstance().emit(
EventNamesDefine.WebSocketConnected,
this
);
}
2021-08-05 14:23:45 +08:00
if (
this.login_callback &&
typeof this.login_callback == "function"
) {
this.login_callback(this._is_login);
}
}
2021-08-07 11:04:39 +08:00
} else if (this.rpc_map.has(packet.rpc_id)) {
2021-08-05 14:23:45 +08:00
const f = this.rpc_map.get(packet.rpc_id);
if (f && typeof f == "function") {
f(false, packet, ev.data);
this.rpc_map.delete(packet.rpc_id);
}
} else {
EventBus.getInstance().emit(EventNamesDefine.ResponseMessage, {
packet: packet,
data: ev.data,
});
2021-08-05 14:23:45 +08:00
}
}
} else {
console.error("unknow command: " + packet.command, packet);
2021-08-05 14:23:45 +08:00
}
}
} catch (e) {
console.error(e);
}
}
public async doRpc<_ResponseType>(
request: Protocol.PacketEntity
2021-08-05 17:26:27 +08:00
): Promise<_ResponseType | null> {
2021-08-05 14:23:45 +08:00
return new Promise((resolve, reject) => {
const rpc_id = ++this._rpc_id_counter;
if (this.rpc_map.has(rpc_id)) {
const f = this.rpc_map.get(rpc_id);
if (f && typeof f == "function") {
f(true, new Protocol.Commands(), "");
this.rpc_map.delete(rpc_id);
}
}
2021-08-05 17:26:27 +08:00
request.rpc_id = rpc_id;
this.ws?.send(JSON.stringify(request));
2021-08-05 14:23:45 +08:00
this.rpc_map.set(
rpc_id,
(is_fail: boolean, packet: Protocol.Commands, data: string) => {
if (is_fail) {
reject();
} else {
try {
2021-08-05 17:26:27 +08:00
const response = JSON.parse(data) as _ResponseType;
2021-08-05 14:23:45 +08:00
if (response) {
resolve(response);
} else {
reject();
}
} catch {
reject();
}
}
}
);
});
}
public async getSignalSources() {
2021-08-05 17:26:27 +08:00
try {
return await this.doRpc<Protocol.GetSignalSourcesResponse>(
new Protocol.GetSignalSourcesRequest()
);
2021-08-05 17:26:27 +08:00
} catch (e) {
console.error(e);
}
2021-08-05 14:23:45 +08:00
}
public async getApplicationSettins() {
try {
return await this.doRpc<Protocol.GetApplicationConfigResponseEntity>(
new Protocol.GetApplicationConfigRequestEntity()
);
2021-08-05 17:26:27 +08:00
} catch (e) {
console.error(e);
}
}
public async getWindows() {
try {
return await this.doRpc<Protocol.GetWindowsResponseEntity>(
new Protocol.GetWindowsRequestEntity()
);
2021-08-05 14:23:45 +08:00
} 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 closeWindow(window_id: number) {
this.ws?.send(
JSON.stringify(new Protocol.CloseWindowRequestEntity(window_id))
);
}
2021-08-07 11:04:39 +08:00
public openWindow(data: Protocol.OpenWindowRequestEntity) {
this.ws?.send(JSON.stringify(data));
}
2021-08-09 10:59:16 +08:00
public focusIn(window_id: number) {
this.ws?.send(
JSON.stringify(
new NormalWindowRequestEntity(
Protocol.Commands.kFocuseWindow,
window_id
)
)
);
}
public async addSignalSourceGroup(parent_uuid: string, name: string) {
try {
return await this.doRpc<Protocol.AddSignalSourcesGroupResponseEntity>(
new Protocol.AddSignalSourcesGroupRequestEntity(0, parent_uuid, name)
);
} catch (e) {
console.error(e);
}
}
2021-08-10 15:09:11 +08:00
public async editSignalSourceGroup(uuid: string, name: string) {
try {
return await this.doRpc<Protocol.EditSignalSourcesGroupResponseEntity>(
new Protocol.EditSignalSourcesGroupRequestEntity(0, uuid, name)
);
} catch (e) {
console.error(e);
}
}
public async deleteSignalSourceGroup(uuid: string) {
try {
return await this.doRpc<Protocol.DeleteSignalSourcesGroupResponseEntity>(
new Protocol.DeleteSignalSourcesGroupRequestEntity(0, uuid)
);
} catch (e) {
console.error(e);
}
}
public async addSignalSource(item: SignalSourceEntity) {
try {
return await this.doRpc<Protocol.AddSignalSourcesResponseEntity>(
new Protocol.AddSignalSourcesRequestEntity(0, item)
);
} catch (e) {
console.error(e);
}
}
public async editSignalSource(item: SignalSourceEntity) {
try {
return await this.doRpc<Protocol.EditSignalSourcesResponseEntity>(
new Protocol.EditSignalSourcesRequestEntity(0, item)
);
} catch (e) {
console.error(e);
}
}
2021-08-10 15:09:11 +08:00
public async deleteSignalSource(uuid: string) {
try {
return await this.doRpc<Protocol.DeleteSignalSourcesResponseEntity>(
new Protocol.DeleteSignalSourcesRequestEntity(0, uuid)
2021-08-10 15:09:11 +08:00
);
} catch (e) {
console.error(e);
}
}
2021-08-07 11:04:39 +08:00
private _destoryed = false;
public destory() {
this._destoryed = true;
this.ws?.close();
this.ws = null;
}
2021-08-05 14:23:45 +08:00
}