🚸 优化 Terminal 连接健壮性、输入缓存

This commit is contained in:
naiba 2021-08-19 10:21:54 +08:00
parent 1f0791fc0e
commit 77a89f62cd
2 changed files with 65 additions and 18 deletions

View File

@ -161,8 +161,6 @@ func (cp *commonPage) ws(c *gin.Context) {
} }
func (cp *commonPage) terminal(c *gin.Context) { func (cp *commonPage) terminal(c *gin.Context) {
log.Println("terminal connected", c.Request.URL)
defer log.Println("terminal disconnected", c.Request.URL)
terminalID := c.Param("id") terminalID := c.Param("id")
cp.terminalsLock.Lock() cp.terminalsLock.Lock()
if terminalID == "" || cp.terminals[terminalID] == nil { if terminalID == "" || cp.terminals[terminalID] == nil {
@ -181,6 +179,7 @@ func (cp *commonPage) terminal(c *gin.Context) {
cp.terminalsLock.Unlock() cp.terminalsLock.Unlock()
defer func() { defer func() {
// 清理 context
cp.terminalsLock.Lock() cp.terminalsLock.Lock()
defer cp.terminalsLock.Unlock() defer cp.terminalsLock.Unlock()
delete(cp.terminals, terminalID) delete(cp.terminals, terminalID)
@ -272,8 +271,17 @@ func (cp *commonPage) terminal(c *gin.Context) {
} }
defer conn.Close() defer conn.Close()
log.Println("terminal connected", isAgent, c.Request.URL)
defer log.Println("terminal disconnected", isAgent, c.Request.URL)
if isAgent { if isAgent {
terminal.agentConn = conn terminal.agentConn = conn
defer func() {
// Agent断开链接时断开用户连接
if terminal.userConn != nil {
terminal.userConn.Close()
}
}()
} else { } else {
terminal.userConn = conn terminal.userConn = conn
defer func() { defer func() {
@ -284,23 +292,57 @@ func (cp *commonPage) terminal(c *gin.Context) {
}() }()
} }
deadlineCh := make(chan interface{})
go func() {
connectDeadline := time.NewTimer(time.Second * 15)
<-connectDeadline.C
close(deadlineCh)
}()
dataCh := make(chan []byte)
go func() {
for {
msgType, data, err := conn.ReadMessage()
if err != nil {
return
}
// 将文本消息转换为命令输入
if msgType == websocket.TextMessage {
data = append([]byte{0}, data...)
}
dataCh <- data
}
}()
var dataBuffer [][]byte
var distConn *websocket.Conn
for { for {
msgType, data, err := conn.ReadMessage() select {
if err != nil { case <-deadlineCh:
return if distConn == nil {
} return
// 将文本消息转换为命令输入 }
if msgType == websocket.TextMessage { case data := <-dataCh:
data = append([]byte{0}, data...) dataBuffer = append(dataBuffer, data)
} if distConn == nil {
// 传递给对方 // 传递给对方
if isAgent { if isAgent {
err = terminal.userConn.WriteMessage(websocket.BinaryMessage, data) distConn = terminal.userConn
} else { } else {
err = terminal.agentConn.WriteMessage(websocket.BinaryMessage, data) distConn = terminal.agentConn
} }
if err != nil { }
return if distConn != nil {
for i := 0; i < len(dataBuffer); i++ {
err = distConn.WriteMessage(websocket.BinaryMessage, dataBuffer[i])
if err != nil {
return
}
}
dataBuffer = dataBuffer[:0]
}
} }
} }
} }

View File

@ -48,6 +48,11 @@
onResize() onResize()
} }
socket.onclose = () => {
alert('Terminal 连接超时或会话已结束')
window.close()
}
socket.onerror = () => { socket.onerror = () => {
alert('Terminal 连接失败,请检查 /terminal/* 的 WebSocket 反代情况') alert('Terminal 连接失败,请检查 /terminal/* 的 WebSocket 反代情况')
} }