From b4421b1b566518bb158214ab8af91ec7b350ad59 Mon Sep 17 00:00:00 2001 From: dushixiang Date: Sun, 7 Feb 2021 17:46:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=8C=87=E4=BB=A4=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=BD=95=E5=B1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 2 +- pkg/api/ssh.go | 57 +------------------------ pkg/term/next_terminal.go | 9 +++- pkg/term/recording.go | 4 +- web/package.json | 2 +- web/public/asciinema.html | 2 +- web/src/components/access/Console.js | 62 ++++++++++++++++++---------- web/src/components/access/Term.js | 1 - web/src/components/asset/Asset.js | 12 +++--- 9 files changed, 61 insertions(+), 90 deletions(-) diff --git a/main.go b/main.go index 994fe36..eb95f63 100644 --- a/main.go +++ b/main.go @@ -22,7 +22,7 @@ import ( "time" ) -const Version = "v0.2.0" +const Version = "v0.1.2" func main() { log.Fatal(Run()) diff --git a/pkg/api/ssh.go b/pkg/api/ssh.go index 0f74eca..6c6753b 100644 --- a/pkg/api/ssh.go +++ b/pkg/api/ssh.go @@ -2,7 +2,6 @@ package api import ( "encoding/json" - "fmt" "github.com/gorilla/websocket" "github.com/labstack/echo/v4" "github.com/pkg/sftp" @@ -155,12 +154,8 @@ func SSHEndpoint(c echo.Context) (err error) { _ = WriteMessage(ws, msg) quitChan := make(chan bool) - recordingChan := make(chan string, 1024) - go ReadMessage(nextTerminal, recordingChan, quitChan, ws) - - go Recoding(nextTerminal, recordingChan, quitChan) - go Monitor(sessionId, recordingChan, quitChan) + go ReadMessage(nextTerminal, quitChan, ws) for { _, message, err := ws.ReadMessage() @@ -207,7 +202,7 @@ func SSHEndpoint(c echo.Context) (err error) { return err } -func ReadMessage(nextTerminal *term.NextTerminal, stdoutChan chan string, quitChan chan bool, ws *websocket.Conn) { +func ReadMessage(nextTerminal *term.NextTerminal, quitChan chan bool, ws *websocket.Conn) { var quit bool for { @@ -227,8 +222,6 @@ func ReadMessage(nextTerminal *term.NextTerminal, stdoutChan chan string, quitCh } if n > 0 { s := string(p) - // 发送一份数据到队列中 - stdoutChan <- s msg := Message{ Type: Data, Content: s, @@ -240,52 +233,6 @@ func ReadMessage(nextTerminal *term.NextTerminal, stdoutChan chan string, quitCh } } -func Recoding(nextTerminal *term.NextTerminal, recordingChan chan string, quitChan chan bool) { - var quit bool - var s string - for { - select { - case quit = <-quitChan: - if quit { - fmt.Println("退出录屏") - return - } - case s = <-recordingChan: - _ = nextTerminal.Recorder.WriteData(s) - default: - - } - } -} - -func Monitor(sessionId string, recordingChan chan string, quitChan chan bool) { - var quit bool - var s string - for { - select { - case quit = <-quitChan: - if quit { - fmt.Println("退出监控") - return - } - case s = <-recordingChan: - msg := Message{ - Type: Data, - Content: s, - } - - observable, ok := global.Store.Get(sessionId) - if ok { - for i := 0; i < len(observable.Observers); i++ { - _ = WriteMessage(observable.Observers[i].WebSocket, msg) - } - } - default: - - } - } -} - func WriteMessage(ws *websocket.Conn, msg Message) error { message, err := json.Marshal(msg) if err != nil { diff --git a/pkg/term/next_terminal.go b/pkg/term/next_terminal.go index 55c5241..e7e1212 100644 --- a/pkg/term/next_terminal.go +++ b/pkg/term/next_terminal.go @@ -75,7 +75,14 @@ func (ret *NextTerminal) Write(p []byte) (int, error) { } func (ret *NextTerminal) Read() ([]byte, int, error) { - return ret.NextWriter.Read() + bytes, n, err := ret.NextWriter.Read() + if err != nil { + return nil, 0, err + } + if ret.Recorder != nil && n > 0 { + _ = ret.Recorder.WriteData(string(bytes)) + } + return bytes, n, nil } func (ret *NextTerminal) Close() error { diff --git a/pkg/term/recording.go b/pkg/term/recording.go index 4eda1b2..cd35efd 100644 --- a/pkg/term/recording.go +++ b/pkg/term/recording.go @@ -108,8 +108,8 @@ func CreateRecording(recordingPath string, h int, w int) (*Recorder, error) { header := &Header{ Title: "", Version: 2, - Height: h, - Width: w, + Height: 42, + Width: 150, Env: Env{Shell: "/bin/bash", Term: "xterm-256color"}, Timestamp: int(time.Now().Unix()), } diff --git a/web/package.json b/web/package.json index d771c9f..f58ee52 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "next-terminal", - "version": "0.2.0", + "version": "0.1.2", "private": true, "dependencies": { "@ant-design/icons": "^4.3.0", diff --git a/web/public/asciinema.html b/web/public/asciinema.html index 82c6f95..9adbf10 100644 --- a/web/public/asciinema.html +++ b/web/public/asciinema.html @@ -12,7 +12,7 @@ - + diff --git a/web/src/components/access/Console.js b/web/src/components/access/Console.js index 984e963..a9178ad 100644 --- a/web/src/components/access/Console.js +++ b/web/src/components/access/Console.js @@ -4,8 +4,10 @@ import {Terminal} from "xterm"; import qs from "qs"; import {wsServer} from "../../common/constants"; import "./Console.css" -import {getToken} from "../../utils/utils"; +import {getToken, isEmpty} from "../../utils/utils"; import {FitAddon} from 'xterm-addon-fit' +import request from "../../common/request"; +import {message} from "antd"; class Console extends Component { @@ -18,45 +20,33 @@ class Console extends Component { fitAddon: undefined }; - componentDidMount() { + componentDidMount = async () => { let command = this.props.command; let assetId = this.props.assetId; let width = this.props.width; let height = this.props.height; - - let params = { - 'width': width, - 'height': height, - 'assetId': assetId - }; - - let paramStr = qs.stringify(params); - - const ua = navigator.userAgent.toLowerCase(); - let lineHeight = 1; - if (ua.includes('windows')) { - lineHeight = 1.1; + let sessionId = await this.createSession(assetId); + if (isEmpty(sessionId)) { + return; } let term = new Terminal({ fontFamily: 'monaco, Consolas, "Lucida Console", monospace', fontSize: 14, - lineHeight: lineHeight, theme: { background: '#1b1b1b' }, rightClickSelectsWord: true, }); - let fitAddon = new FitAddon(); - term.loadAddon(fitAddon); term.open(this.refs.terminal); + const fitAddon = new FitAddon(); + term.loadAddon(fitAddon); + fitAddon.fit(); + term.focus(); term.writeln('Trying to connect to the server ...'); - term.onResize(e => { - - }); term.onData(data => { let webSocket = this.state.webSocket; @@ -66,8 +56,16 @@ class Console extends Component { }); let token = getToken(); + let params = { + 'cols': term.cols, + 'rows': term.rows, + 'sessionId': sessionId, + 'X-Auth-Token': token + }; - let webSocket = new WebSocket(wsServer + '/ssh?X-Auth-Token=' + token + '&' + paramStr); + let paramStr = qs.stringify(params); + + let webSocket = new WebSocket(wsServer + '/ssh?' + paramStr); this.props.appendWebsocket({'id': assetId, 'ws': webSocket}); @@ -86,6 +84,10 @@ class Console extends Component { webSocket.onmessage = (e) => { let msg = JSON.parse(e.data); switch (msg['type']) { + case 'connected': + term.clear(); + this.updateSessionStatus(sessionId); + break; case 'data': term.write(msg['content']); break; @@ -129,6 +131,22 @@ class Console extends Component { } } + async createSession(assetsId) { + let result = await request.post(`/sessions?assetId=${assetsId}&mode=naive`); + if (result['code'] !== 1) { + this.showMessage(result['message']); + return null; + } + return result['data']['id']; + } + + updateSessionStatus = async (sessionId) => { + let result = await request.post(`/sessions/${sessionId}/connect`); + if (result['code'] !== 1) { + message.error(result['message']); + } + } + onWindowResize = (e) => { let term = this.state.term; let fitAddon = this.state.fitAddon; diff --git a/web/src/components/access/Term.js b/web/src/components/access/Term.js index 20d9998..6ece5f6 100644 --- a/web/src/components/access/Term.js +++ b/web/src/components/access/Term.js @@ -105,7 +105,6 @@ class Term extends Component { let msg = JSON.parse(e.data); switch (msg['type']) { case 'connected': - // term.write(msg['content']) term.clear(); this.updateSessionStatus(sessionId); break; diff --git a/web/src/components/asset/Asset.js b/web/src/components/asset/Asset.js index cf6f16a..f90f1a3 100644 --- a/web/src/components/asset/Asset.js +++ b/web/src/components/asset/Asset.js @@ -323,12 +323,12 @@ class Asset extends Component { if (result.code === 1) { if (result.data === true) { message.success({content: '检测完成,您访问的资产在线,即将打开窗口进行访问。', key: id, duration: 3}); - // window.open(`#/access?assetId=${id}&assetName=${name}&protocol=${protocol}`); - if (protocol === 'ssh') { - window.open(`#/term?assetId=${id}&assetName=${name}`); - } else { - window.open(`#/access?assetId=${id}&assetName=${name}&protocol=${protocol}`); - } + window.open(`#/access?assetId=${id}&assetName=${name}&protocol=${protocol}`); + // if (protocol === 'ssh') { + // window.open(`#/term?assetId=${id}&assetName=${name}`); + // } else { + // window.open(`#/access?assetId=${id}&assetName=${name}&protocol=${protocol}`); + // } } else { message.warn('您访问的资产未在线,请确认网络状态。', 10); }