siyuan/app/src/layout/Model.ts

105 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {Constants} from "../constants";
/// #if !MOBILE
import {Tab} from "./Tab";
/// #endif
import {processMessage} from "../util/processMessage";
import {kernelError, reloadSync} from "../dialog/processSystem";
import {App} from "../index";
export class Model {
public ws: WebSocket;
public reqId: number;
/// #if !MOBILE
public parent: Tab;
/// #else
// @ts-ignore
public parent: any;
/// #endif
public app: App;
constructor(options: {
app: App,
id: string,
type?: TWS,
callback?: () => void,
msgCallback?: (data: IWebSocketData) => void
}) {
this.app = options.app;
if (options.msgCallback) {
this.connect(options);
}
}
private connect(options: {
id: string,
type?: TWS,
callback?: () => void,
msgCallback?: (data: IWebSocketData) => void
}) {
const websocketURL = `${window.location.protocol === "https:" ? "wss" : "ws"}://${window.location.host}/ws`;
const ws = new WebSocket(`${websocketURL}?app=${Constants.SIYUAN_APPID}&id=${options.id}${options.type ? "&type=" + options.type : ""}`);
ws.onopen = () => {
if (options.callback) {
options.callback.call(this);
}
const logElement = document.getElementById("errorLog");
if (logElement) {
// 内核中断后无法 catch fetch 请求错误,重连会导致无法执行 transactionsTimeout
reloadSync(this.app, {upsertRootIDs: [], removeRootIDs: []});
window.siyuan.dialogs.find(item => {
if (item.element.id === "errorLog") {
item.destroy();
return true;
}
});
}
};
ws.onmessage = (event) => {
if (options.msgCallback) {
const data = processMessage(JSON.parse(event.data));
options.msgCallback.call(this, data);
}
};
ws.onclose = (ev) => {
if (0 <= ev.reason.indexOf("unauthenticated")) {
return;
}
if (0 > ev.reason.indexOf("close websocket")) {
console.warn("WebSocket is closed. Reconnect will be attempted in 3 second.", ev);
setTimeout(() => {
this.connect({
id: options.id,
type: options.type,
msgCallback: options.msgCallback
});
}, 3000);
}
};
ws.onerror = (err: Event & { target: { url: string, readyState: number } }) => {
if (err.target.url.endsWith("&type=main") && err.target.readyState === 3) {
kernelError();
}
};
this.ws = ws;
}
public send(cmd: string, param: Record<string, unknown>, process = false) {
if (!this.ws) { // Inbox 无 ws
return;
}
this.reqId = process ? 0 : new Date().getTime();
this.ws.send(JSON.stringify({
cmd,
reqId: this.reqId,
param,
// pushMode
// 0: 所有应用所有会话广播
// 1自我应用会话单播
// 2非自我会话广播
// 4非自我应用所有会话广播
// 5单个应用内所有会话广播
// 6非自我应用主会话广播
}));
}
}