diff --git a/backend/app/api/v1/terminal.go b/backend/app/api/v1/terminal.go index 7f6e74aec..52d5b933c 100644 --- a/backend/app/api/v1/terminal.go +++ b/backend/app/api/v1/terminal.go @@ -1,6 +1,8 @@ package v1 import ( + "encoding/base64" + "encoding/json" "fmt" "net/http" "strconv" @@ -196,7 +198,15 @@ func wshandleError(ws *websocket.Conn, err error) bool { global.LOG.Errorf("handler ws faled:, err: %v", err) dt := time.Now().Add(time.Second) if ctlerr := ws.WriteControl(websocket.CloseMessage, []byte(err.Error()), dt); ctlerr != nil { - _ = ws.WriteMessage(websocket.TextMessage, []byte(err.Error())) + wsData, err := json.Marshal(terminal.WsMsg{ + Type: terminal.WsMsgCmd, + Data: base64.StdEncoding.EncodeToString([]byte(err.Error())), + }) + if err != nil { + _ = ws.WriteMessage(websocket.TextMessage, []byte("{\"type\":\"cmd\",\"data\":\"failed to encoding to json\"}")) + } else { + _ = ws.WriteMessage(websocket.TextMessage, wsData) + } } return true } diff --git a/backend/utils/terminal/ws_local_session.go b/backend/utils/terminal/ws_local_session.go index 04350bc3a..d9221b6cc 100644 --- a/backend/utils/terminal/ws_local_session.go +++ b/backend/utils/terminal/ws_local_session.go @@ -52,11 +52,17 @@ func (sws *LocalWsSession) handleSlaveEvent(exitCh chan bool) { func (sws *LocalWsSession) masterWrite(data []byte) error { sws.writeMutex.Lock() defer sws.writeMutex.Unlock() - err := sws.wsConn.WriteMessage(websocket.TextMessage, data) + wsData, err := json.Marshal(WsMsg{ + Type: WsMsgCmd, + Data: base64.StdEncoding.EncodeToString(data), + }) + if err != nil { + return errors.Wrapf(err, "failed to encoding to json") + } + err = sws.wsConn.WriteMessage(websocket.TextMessage, wsData) if err != nil { return errors.Wrapf(err, "failed to write to master") } - return nil } @@ -74,21 +80,27 @@ func (sws *LocalWsSession) receiveWsMsg(exitCh chan bool) { global.LOG.Errorf("reading webSocket message failed, err: %v", err) return } - msgObj := wsMsg{} + msgObj := WsMsg{} _ = json.Unmarshal(wsData, &msgObj) switch msgObj.Type { - case wsMsgResize: + case WsMsgResize: if msgObj.Cols > 0 && msgObj.Rows > 0 { if err := sws.slave.ResizeTerminal(msgObj.Cols, msgObj.Rows); err != nil { global.LOG.Errorf("ssh pty change windows size failed, err: %v", err) } } - case wsMsgCmd: + case WsMsgCmd: decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Data) if err != nil { global.LOG.Errorf("websock cmd string base64 decoding failed, err: %v", err) } sws.sendWebsocketInputCommandToSshSessionStdinPipe(decodeBytes) + case WsMsgHeartbeat: + // 接收到心跳包后将心跳包原样返回,可以用于网络延迟检测等情况 + err = wsConn.WriteMessage(websocket.TextMessage, wsData) + if err != nil { + global.LOG.Errorf("ssh sending heartbeat to webSocket failed, err: %v", err) + } } } } diff --git a/backend/utils/terminal/ws_session.go b/backend/utils/terminal/ws_session.go index 11078517b..7c30c65ab 100644 --- a/backend/utils/terminal/ws_session.go +++ b/backend/utils/terminal/ws_session.go @@ -35,17 +35,17 @@ func (w *safeBuffer) Reset() { } const ( - wsMsgCmd = "cmd" - wsMsgResize = "resize" - wsMsgHeartbeat = "heartbeat" + WsMsgCmd = "cmd" + WsMsgResize = "resize" + WsMsgHeartbeat = "heartbeat" ) -type wsMsg struct { +type WsMsg struct { Type string `json:"type"` - Data string `json:"data,omitempty"` // wsMsgCmd - Cols int `json:"cols,omitempty"` // wsMsgResize - Rows int `json:"rows,omitempty"` // wsMsgResize - Timestamp int `json:"timestamp,omitempty"` // wsMsgHeartbeat + Data string `json:"data,omitempty"` // WsMsgCmd + Cols int `json:"cols,omitempty"` // WsMsgResize + Rows int `json:"rows,omitempty"` // WsMsgResize + Timestamp int `json:"timestamp,omitempty"` // WsMsgHeartbeat } type LogicSshWsSession struct { @@ -127,22 +127,22 @@ func (sws *LogicSshWsSession) receiveWsMsg(exitCh chan bool) { if err != nil { return } - msgObj := wsMsg{} + msgObj := WsMsg{} _ = json.Unmarshal(wsData, &msgObj) switch msgObj.Type { - case wsMsgResize: + case WsMsgResize: if msgObj.Cols > 0 && msgObj.Rows > 0 { if err := sws.session.WindowChange(msgObj.Rows, msgObj.Cols); err != nil { global.LOG.Errorf("ssh pty change windows size failed, err: %v", err) } } - case wsMsgCmd: + case WsMsgCmd: decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Data) if err != nil { global.LOG.Errorf("websock cmd string base64 decoding failed, err: %v", err) } sws.sendWebsocketInputCommandToSshSessionStdinPipe(decodeBytes) - case wsMsgHeartbeat: + case WsMsgHeartbeat: // 接收到心跳包后将心跳包原样返回,可以用于网络延迟检测等情况 err = wsConn.WriteMessage(websocket.TextMessage, wsData) if err != nil { @@ -173,8 +173,8 @@ func (sws *LogicSshWsSession) sendComboOutput(exitCh chan bool) { } bs := sws.comboOutput.Bytes() if len(bs) > 0 { - wsData, err := json.Marshal(wsMsg{ - Type: wsMsgCmd, + wsData, err := json.Marshal(WsMsg{ + Type: WsMsgCmd, Data: base64.StdEncoding.EncodeToString(bs), }) if err != nil { diff --git a/frontend/src/components/terminal/index.vue b/frontend/src/components/terminal/index.vue index e13cffdb5..dd6c6e19f 100644 --- a/frontend/src/components/terminal/index.vue +++ b/frontend/src/components/terminal/index.vue @@ -68,14 +68,16 @@ const initError = (errorInfo: string) => { } }; -function onClose() { +function onClose(isKeepShow: boolean = false) { window.removeEventListener('resize', changeTerminalSize); try { terminalSocket.value?.close(); } catch {} - try { - term.value.dispose(); - } catch {} + if (!isKeepShow) { + try { + term.value.dispose(); + } catch {} + } } // terminal 相关代码 start @@ -162,7 +164,7 @@ const onWSReceive = (message: MessageEvent) => { switch (wsMsg.type) { case 'cmd': { term.value.element && term.value.focus(); - term.value.write(Base64.decode(wsMsg.data)); + wsMsg.data && term.value.write(Base64.decode(wsMsg.data)); // 这里理论上不用判断,但是Redis和Ctr还没实现Alive处理,所以exit后会一直发数据,todo break; } case 'heartbeat': { diff --git a/frontend/src/views/container/container/terminal/index.vue b/frontend/src/views/container/container/terminal/index.vue index daca454d8..070818750 100644 --- a/frontend/src/views/container/container/terminal/index.vue +++ b/frontend/src/views/container/container/terminal/index.vue @@ -44,7 +44,7 @@ {{ $t('commons.button.conn') }} {{ $t('commons.button.disconn') }} -
+ @@ -52,24 +52,12 @@ -