From e58cd1c4adda17a08408dfbc3287b7ba87cb4370 Mon Sep 17 00:00:00 2001 From: sawka Date: Thu, 16 Jun 2022 21:14:26 -0700 Subject: [PATCH] checkpoint, getting websockets working --- package.json | 1 + src/main.tsx | 11 ++++------- src/session.ts | 32 +++++++++++++++++++++++++------- src/sh2.ts | 3 +++ src/term.ts | 36 ++++++++++++++++++++---------------- src/ws.ts | 10 +++++++++- 6 files changed, 62 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index 09fed0643..2ce1d206b 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "react-dom": "^18.1.0", "sprintf-js": "^1.1.2", "tsx-control-statements": "^4.1.1", + "uuid": "^8.3.2", "xterm": "^4.18.0" }, "devDependencies": { diff --git a/src/main.tsx b/src/main.tsx index b3d01c571..cc77b3767 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -55,7 +55,7 @@ class LineCmd extends React.Component<{line : LineType, session : Session}, {}> componentDidMount() { let {session, line} = this.props; let termElem = document.getElementById(this.getId()); - let termWrap = session.getTermWrap(line); + let termWrap = session.getTermWrapByLine(line); termWrap.connectToElem(termElem); if (line.isnew) { setTimeout(() => { @@ -65,9 +65,6 @@ class LineCmd extends React.Component<{line : LineType, session : Session}, {}> line.isnew = false; })(); }, 100); - setTimeout(() => { - termWrap.reloadTerminal(0); - }, 1000); } } @@ -79,8 +76,8 @@ class LineCmd extends React.Component<{line : LineType, session : Session}, {}> @boundMethod doRefresh() { let {session, line} = this.props; - let termWrap = session.getTermWrap(line); - termWrap.reloadTerminal(500); + let termWrap = session.getTermWrapByLine(line); + termWrap.reloadTerminal(line.sessionid, line.cmdid, 500); } @boundMethod @@ -105,7 +102,7 @@ class LineCmd extends React.Component<{line : LineType, session : Session}, {}> let running = false; let rows = 0; let cols = 0; - let termWrap = session.getTermWrap(line); + let termWrap = session.getTermWrapByLine(line); let renderVersion = termWrap.getRenderVersion(); termWrap.resizeToContent(); let termSize = termWrap.getSize(); diff --git a/src/session.ts b/src/session.ts index 3323b4291..df8d7cadb 100644 --- a/src/session.ts +++ b/src/session.ts @@ -2,8 +2,8 @@ import * as mobx from "mobx"; import {sprintf} from "sprintf-js"; import {boundMethod} from "autobind-decorator"; import {handleJsonFetchResponse} from "./util"; -import {GlobalWS} from "./ws"; -import {TermWrap, makeTermKey} from "./term"; +import {TermWrap} from "./term"; +import {v4 as uuidv4} from "uuid"; var GlobalUser = "sawka"; 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"}, ]); +function makeTermKey(sessionId : string, cmdId : string, windowId : string, lineid : number) : string { + return sprintf("%s/%s/%s/%s", sessionId, cmdId, windowId, lineid); +} + type LineType = { sessionid : string, windowid : string, @@ -35,15 +39,19 @@ type WindowType = { }; class Session { - sessionid : string; + sessionId : string; name : string; windows : WindowType[]; activeWindowId : string; termMap : Record = {}; + termMapById : Record = {}; + + constructor() { + } submitCommand(windowid : string, commandStr : string) { 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) => { mobx.action(() => { 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 termWrap = this.termMap[termKey]; if (termWrap != null) { return termWrap; } - termWrap = new TermWrap(line.sessionid, line.cmdid, line.windowid, line.lineid); + termWrap = new TermWrap(); this.termMap[termKey] = termWrap; + this.termMapById[termWrap.termId] = termWrap; termWrap.initialized = true; termWrap.reloadTerminal(0); + termWrap.startPtyTail(line.sessionid, line.cmdid); return termWrap; } + getTermById(termId : string) : TermWrap { + return this.termMapById[termId]; + } + + recvCmdData(termWrap : TermWrap, pk : any) { + console.log("cmddata", pk); + } + getActiveWindow() : WindowType { if (this.windows == null) { return null; @@ -84,7 +102,7 @@ class Session { function getDefaultSession() : Session { let windowLines = GlobalLines.get(); let session = new Session(); - session.sessionid = GSessionId; + session.sessionId = GSessionId; session.name = "default"; session.activeWindowId = GWindowId; session.windows = [ diff --git a/src/sh2.ts b/src/sh2.ts index 0d1d6012a..8704ac35a 100644 --- a/src/sh2.ts +++ b/src/sh2.ts @@ -4,9 +4,12 @@ import {sprintf} from "sprintf-js"; import {Terminal} from 'xterm'; import {Main} from "./main"; import {GlobalWS} from "./ws"; +import {v4 as uuidv4} from "uuid"; let VERSION = __SHVERSION__; +window.ScriptHausClientId = uuidv4(); + document.addEventListener("DOMContentLoaded", () => { GlobalWS.reconnect(); let reactElem = React.createElement(Main, null, null); diff --git a/src/term.ts b/src/term.ts index 31cff7057..beee437d3 100644 --- a/src/term.ts +++ b/src/term.ts @@ -3,10 +3,7 @@ import {Terminal} from 'xterm'; import {sprintf} from "sprintf-js"; import {boundMethod} from "autobind-decorator"; import {GlobalWS} from "./ws"; - -function makeTermKey(sessionId : string, cmdId : string, windowId : string, lineid : number) : string { - return sprintf("%s/%s/%s/%s", sessionId, cmdId, windowId, lineid); -} +import {v4 as uuidv4} from "uuid"; function loadPtyOut(term : Terminal, sessionId : string, cmdId : string, delayMs : number, callback?: (number) => void) { term.clear() @@ -23,10 +20,7 @@ function loadPtyOut(term : Terminal, sessionId : string, cmdId : string, delayMs class TermWrap { terminal : Terminal; - sessionId : string; - cmdId : string; - windowId : string; - lineid : number; + termId : string; ptyPos : number = 0; runPos : number = 0; runData : string = ""; @@ -38,11 +32,8 @@ class TermWrap { atRowMax : boolean = false; initialized : boolean = false; - constructor(sessionId : string, cmdId : string, windowId : string, lineid : number) { - this.sessionId = sessionId; - this.cmdId = cmdId; - this.windowId = windowId; - this.lineid = lineid; + constructor() { + this.termId = uuidv4(); 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 updatePtyData(pos : number, data : string, datalen : number) { if (pos != this.ptyPos) { @@ -116,8 +120,8 @@ class TermWrap { mobx.action(() => this.renderVersion.set(this.renderVersion.get() + 1))(); } - reloadTerminal(delayMs : number) { - loadPtyOut(this.terminal, this.sessionId, this.cmdId, delayMs, (ptyoutLen) => { + reloadTerminal(sessionId : string, cmdId : string, delayMs : number) { + loadPtyOut(this.terminal, sessionId, cmdId, delayMs, (ptyoutLen) => { mobx.action(() => { this.incRenderVersion(); this.ptyPos = ptyoutLen; @@ -136,4 +140,4 @@ class TermWrap { } } -export {TermWrap, makeTermKey}; +export {TermWrap}; diff --git a/src/ws.ts b/src/ws.ts index 5df699154..70d1f0be2 100644 --- a/src/ws.ts +++ b/src/ws.ts @@ -22,6 +22,10 @@ class WSControl { this.open.set(val); } + registerAndSendGetCmd(pk : any) { + this.pushMessage(pk) + } + reconnect() { if (this.open.get()) { this.wsConn.close(); @@ -72,8 +76,8 @@ class WSControl { console.log("websocket open"); this.setOpen(true); this.opening = false; - this.reconnectTimes = 0; this.runMsgQueue(); + // reconnectTimes is reset in onmessage:hello } runMsgQueue() { @@ -107,6 +111,10 @@ class WSControl { // nothing return; } + if (eventData.type == "hello") { + this.reconnectTimes = 0; + return; + } console.log("websocket message", event); }