mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
checkpoint, getting websockets working
This commit is contained in:
parent
bb37a829de
commit
e58cd1c4ad
@ -13,6 +13,7 @@
|
|||||||
"react-dom": "^18.1.0",
|
"react-dom": "^18.1.0",
|
||||||
"sprintf-js": "^1.1.2",
|
"sprintf-js": "^1.1.2",
|
||||||
"tsx-control-statements": "^4.1.1",
|
"tsx-control-statements": "^4.1.1",
|
||||||
|
"uuid": "^8.3.2",
|
||||||
"xterm": "^4.18.0"
|
"xterm": "^4.18.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
11
src/main.tsx
11
src/main.tsx
@ -55,7 +55,7 @@ class LineCmd extends React.Component<{line : LineType, session : Session}, {}>
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
let {session, line} = this.props;
|
let {session, line} = this.props;
|
||||||
let termElem = document.getElementById(this.getId());
|
let termElem = document.getElementById(this.getId());
|
||||||
let termWrap = session.getTermWrap(line);
|
let termWrap = session.getTermWrapByLine(line);
|
||||||
termWrap.connectToElem(termElem);
|
termWrap.connectToElem(termElem);
|
||||||
if (line.isnew) {
|
if (line.isnew) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -65,9 +65,6 @@ class LineCmd extends React.Component<{line : LineType, session : Session}, {}>
|
|||||||
line.isnew = false;
|
line.isnew = false;
|
||||||
})();
|
})();
|
||||||
}, 100);
|
}, 100);
|
||||||
setTimeout(() => {
|
|
||||||
termWrap.reloadTerminal(0);
|
|
||||||
}, 1000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,8 +76,8 @@ class LineCmd extends React.Component<{line : LineType, session : Session}, {}>
|
|||||||
@boundMethod
|
@boundMethod
|
||||||
doRefresh() {
|
doRefresh() {
|
||||||
let {session, line} = this.props;
|
let {session, line} = this.props;
|
||||||
let termWrap = session.getTermWrap(line);
|
let termWrap = session.getTermWrapByLine(line);
|
||||||
termWrap.reloadTerminal(500);
|
termWrap.reloadTerminal(line.sessionid, line.cmdid, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
@ -105,7 +102,7 @@ class LineCmd extends React.Component<{line : LineType, session : Session}, {}>
|
|||||||
let running = false;
|
let running = false;
|
||||||
let rows = 0;
|
let rows = 0;
|
||||||
let cols = 0;
|
let cols = 0;
|
||||||
let termWrap = session.getTermWrap(line);
|
let termWrap = session.getTermWrapByLine(line);
|
||||||
let renderVersion = termWrap.getRenderVersion();
|
let renderVersion = termWrap.getRenderVersion();
|
||||||
termWrap.resizeToContent();
|
termWrap.resizeToContent();
|
||||||
let termSize = termWrap.getSize();
|
let termSize = termWrap.getSize();
|
||||||
|
@ -2,8 +2,8 @@ import * as mobx from "mobx";
|
|||||||
import {sprintf} from "sprintf-js";
|
import {sprintf} from "sprintf-js";
|
||||||
import {boundMethod} from "autobind-decorator";
|
import {boundMethod} from "autobind-decorator";
|
||||||
import {handleJsonFetchResponse} from "./util";
|
import {handleJsonFetchResponse} from "./util";
|
||||||
import {GlobalWS} from "./ws";
|
import {TermWrap} from "./term";
|
||||||
import {TermWrap, makeTermKey} from "./term";
|
import {v4 as uuidv4} from "uuid";
|
||||||
|
|
||||||
var GlobalUser = "sawka";
|
var GlobalUser = "sawka";
|
||||||
var GSessionId = "47445c53-cfcf-4943-8339-2c04447f20a1";
|
var GSessionId = "47445c53-cfcf-4943-8339-2c04447f20a1";
|
||||||
@ -14,6 +14,10 @@ var GlobalLines = mobx.observable.box([
|
|||||||
{sessionid: GSessionId, windowid: GWindowId, lineid: 2, userid: "sawka", ts: 1654631125000, linetype: "text", text: "again"},
|
{sessionid: GSessionId, windowid: GWindowId, lineid: 2, userid: "sawka", ts: 1654631125000, linetype: "text", text: "again"},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
function makeTermKey(sessionId : string, cmdId : string, windowId : string, lineid : number) : string {
|
||||||
|
return sprintf("%s/%s/%s/%s", sessionId, cmdId, windowId, lineid);
|
||||||
|
}
|
||||||
|
|
||||||
type LineType = {
|
type LineType = {
|
||||||
sessionid : string,
|
sessionid : string,
|
||||||
windowid : string,
|
windowid : string,
|
||||||
@ -35,15 +39,19 @@ type WindowType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class Session {
|
class Session {
|
||||||
sessionid : string;
|
sessionId : string;
|
||||||
name : string;
|
name : string;
|
||||||
windows : WindowType[];
|
windows : WindowType[];
|
||||||
activeWindowId : string;
|
activeWindowId : string;
|
||||||
termMap : Record<string, TermWrap> = {};
|
termMap : Record<string, TermWrap> = {};
|
||||||
|
termMapById : Record<string, TermWrap> = {};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
submitCommand(windowid : string, commandStr : string) {
|
submitCommand(windowid : string, commandStr : string) {
|
||||||
let url = sprintf("http://localhost:8080/api/run-command");
|
let url = sprintf("http://localhost:8080/api/run-command");
|
||||||
let data = {sessionid: this.sessionid, windowid: windowid, command: commandStr, userid: GlobalUser};
|
let data = {sessionid: this.sessionId, windowid: windowid, command: commandStr, userid: GlobalUser};
|
||||||
fetch(url, {method: "post", body: JSON.stringify(data)}).then((resp) => handleJsonFetchResponse(url, resp)).then((data) => {
|
fetch(url, {method: "post", body: JSON.stringify(data)}).then((resp) => handleJsonFetchResponse(url, resp)).then((data) => {
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
let lines = GlobalLines.get();
|
let lines = GlobalLines.get();
|
||||||
@ -55,19 +63,29 @@ class Session {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getTermWrap(line : LineType) {
|
getTermWrapByLine(line : LineType) : TermWrap {
|
||||||
let termKey = makeTermKey(line.sessionid, line.cmdid, line.windowid, line.lineid);
|
let termKey = makeTermKey(line.sessionid, line.cmdid, line.windowid, line.lineid);
|
||||||
let termWrap = this.termMap[termKey];
|
let termWrap = this.termMap[termKey];
|
||||||
if (termWrap != null) {
|
if (termWrap != null) {
|
||||||
return termWrap;
|
return termWrap;
|
||||||
}
|
}
|
||||||
termWrap = new TermWrap(line.sessionid, line.cmdid, line.windowid, line.lineid);
|
termWrap = new TermWrap();
|
||||||
this.termMap[termKey] = termWrap;
|
this.termMap[termKey] = termWrap;
|
||||||
|
this.termMapById[termWrap.termId] = termWrap;
|
||||||
termWrap.initialized = true;
|
termWrap.initialized = true;
|
||||||
termWrap.reloadTerminal(0);
|
termWrap.reloadTerminal(0);
|
||||||
|
termWrap.startPtyTail(line.sessionid, line.cmdid);
|
||||||
return termWrap;
|
return termWrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTermById(termId : string) : TermWrap {
|
||||||
|
return this.termMapById[termId];
|
||||||
|
}
|
||||||
|
|
||||||
|
recvCmdData(termWrap : TermWrap, pk : any) {
|
||||||
|
console.log("cmddata", pk);
|
||||||
|
}
|
||||||
|
|
||||||
getActiveWindow() : WindowType {
|
getActiveWindow() : WindowType {
|
||||||
if (this.windows == null) {
|
if (this.windows == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -84,7 +102,7 @@ class Session {
|
|||||||
function getDefaultSession() : Session {
|
function getDefaultSession() : Session {
|
||||||
let windowLines = GlobalLines.get();
|
let windowLines = GlobalLines.get();
|
||||||
let session = new Session();
|
let session = new Session();
|
||||||
session.sessionid = GSessionId;
|
session.sessionId = GSessionId;
|
||||||
session.name = "default";
|
session.name = "default";
|
||||||
session.activeWindowId = GWindowId;
|
session.activeWindowId = GWindowId;
|
||||||
session.windows = [
|
session.windows = [
|
||||||
|
@ -4,9 +4,12 @@ import {sprintf} from "sprintf-js";
|
|||||||
import {Terminal} from 'xterm';
|
import {Terminal} from 'xterm';
|
||||||
import {Main} from "./main";
|
import {Main} from "./main";
|
||||||
import {GlobalWS} from "./ws";
|
import {GlobalWS} from "./ws";
|
||||||
|
import {v4 as uuidv4} from "uuid";
|
||||||
|
|
||||||
let VERSION = __SHVERSION__;
|
let VERSION = __SHVERSION__;
|
||||||
|
|
||||||
|
window.ScriptHausClientId = uuidv4();
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
GlobalWS.reconnect();
|
GlobalWS.reconnect();
|
||||||
let reactElem = React.createElement(Main, null, null);
|
let reactElem = React.createElement(Main, null, null);
|
||||||
|
36
src/term.ts
36
src/term.ts
@ -3,10 +3,7 @@ import {Terminal} from 'xterm';
|
|||||||
import {sprintf} from "sprintf-js";
|
import {sprintf} from "sprintf-js";
|
||||||
import {boundMethod} from "autobind-decorator";
|
import {boundMethod} from "autobind-decorator";
|
||||||
import {GlobalWS} from "./ws";
|
import {GlobalWS} from "./ws";
|
||||||
|
import {v4 as uuidv4} from "uuid";
|
||||||
function makeTermKey(sessionId : string, cmdId : string, windowId : string, lineid : number) : string {
|
|
||||||
return sprintf("%s/%s/%s/%s", sessionId, cmdId, windowId, lineid);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadPtyOut(term : Terminal, sessionId : string, cmdId : string, delayMs : number, callback?: (number) => void) {
|
function loadPtyOut(term : Terminal, sessionId : string, cmdId : string, delayMs : number, callback?: (number) => void) {
|
||||||
term.clear()
|
term.clear()
|
||||||
@ -23,10 +20,7 @@ function loadPtyOut(term : Terminal, sessionId : string, cmdId : string, delayMs
|
|||||||
|
|
||||||
class TermWrap {
|
class TermWrap {
|
||||||
terminal : Terminal;
|
terminal : Terminal;
|
||||||
sessionId : string;
|
termId : string;
|
||||||
cmdId : string;
|
|
||||||
windowId : string;
|
|
||||||
lineid : number;
|
|
||||||
ptyPos : number = 0;
|
ptyPos : number = 0;
|
||||||
runPos : number = 0;
|
runPos : number = 0;
|
||||||
runData : string = "";
|
runData : string = "";
|
||||||
@ -38,11 +32,8 @@ class TermWrap {
|
|||||||
atRowMax : boolean = false;
|
atRowMax : boolean = false;
|
||||||
initialized : boolean = false;
|
initialized : boolean = false;
|
||||||
|
|
||||||
constructor(sessionId : string, cmdId : string, windowId : string, lineid : number) {
|
constructor() {
|
||||||
this.sessionId = sessionId;
|
this.termId = uuidv4();
|
||||||
this.cmdId = cmdId;
|
|
||||||
this.windowId = windowId;
|
|
||||||
this.lineid = lineid;
|
|
||||||
this.terminal = new Terminal({rows: 2, cols: 80});
|
this.terminal = new Terminal({rows: 2, cols: 80});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,6 +41,19 @@ class TermWrap {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startPtyTail(sessionId : string, cmdId : string) {
|
||||||
|
let getCmdPacket = {
|
||||||
|
type: "getcmd",
|
||||||
|
reqid: this.termId,
|
||||||
|
sessionid: sessionId,
|
||||||
|
cmdid: cmdId,
|
||||||
|
ptypos: this.ptyPos,
|
||||||
|
};
|
||||||
|
GlobalWS.registerAndSendGetCmd(getCmdPacket, (dataPacket) => {
|
||||||
|
console.log("data-packet", dataPacket);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// datalen is passed because data could be utf-8 and data.length is not the actual *byte* length
|
// datalen is passed because data could be utf-8 and data.length is not the actual *byte* length
|
||||||
updatePtyData(pos : number, data : string, datalen : number) {
|
updatePtyData(pos : number, data : string, datalen : number) {
|
||||||
if (pos != this.ptyPos) {
|
if (pos != this.ptyPos) {
|
||||||
@ -116,8 +120,8 @@ class TermWrap {
|
|||||||
mobx.action(() => this.renderVersion.set(this.renderVersion.get() + 1))();
|
mobx.action(() => this.renderVersion.set(this.renderVersion.get() + 1))();
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadTerminal(delayMs : number) {
|
reloadTerminal(sessionId : string, cmdId : string, delayMs : number) {
|
||||||
loadPtyOut(this.terminal, this.sessionId, this.cmdId, delayMs, (ptyoutLen) => {
|
loadPtyOut(this.terminal, sessionId, cmdId, delayMs, (ptyoutLen) => {
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
this.incRenderVersion();
|
this.incRenderVersion();
|
||||||
this.ptyPos = ptyoutLen;
|
this.ptyPos = ptyoutLen;
|
||||||
@ -136,4 +140,4 @@ class TermWrap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {TermWrap, makeTermKey};
|
export {TermWrap};
|
||||||
|
10
src/ws.ts
10
src/ws.ts
@ -22,6 +22,10 @@ class WSControl {
|
|||||||
this.open.set(val);
|
this.open.set(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerAndSendGetCmd(pk : any) {
|
||||||
|
this.pushMessage(pk)
|
||||||
|
}
|
||||||
|
|
||||||
reconnect() {
|
reconnect() {
|
||||||
if (this.open.get()) {
|
if (this.open.get()) {
|
||||||
this.wsConn.close();
|
this.wsConn.close();
|
||||||
@ -72,8 +76,8 @@ class WSControl {
|
|||||||
console.log("websocket open");
|
console.log("websocket open");
|
||||||
this.setOpen(true);
|
this.setOpen(true);
|
||||||
this.opening = false;
|
this.opening = false;
|
||||||
this.reconnectTimes = 0;
|
|
||||||
this.runMsgQueue();
|
this.runMsgQueue();
|
||||||
|
// reconnectTimes is reset in onmessage:hello
|
||||||
}
|
}
|
||||||
|
|
||||||
runMsgQueue() {
|
runMsgQueue() {
|
||||||
@ -107,6 +111,10 @@ class WSControl {
|
|||||||
// nothing
|
// nothing
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (eventData.type == "hello") {
|
||||||
|
this.reconnectTimes = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
console.log("websocket message", event);
|
console.log("websocket message", event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user