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);
}