🚸 优化 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) {
log.Println("terminal connected", c.Request.URL)
defer log.Println("terminal disconnected", c.Request.URL)
terminalID := c.Param("id")
cp.terminalsLock.Lock()
if terminalID == "" || cp.terminals[terminalID] == nil {
@ -181,6 +179,7 @@ func (cp *commonPage) terminal(c *gin.Context) {
cp.terminalsLock.Unlock()
defer func() {
// 清理 context
cp.terminalsLock.Lock()
defer cp.terminalsLock.Unlock()
delete(cp.terminals, terminalID)
@ -272,8 +271,17 @@ func (cp *commonPage) terminal(c *gin.Context) {
}
defer conn.Close()
log.Println("terminal connected", isAgent, c.Request.URL)
defer log.Println("terminal disconnected", isAgent, c.Request.URL)
if isAgent {
terminal.agentConn = conn
defer func() {
// Agent断开链接时断开用户连接
if terminal.userConn != nil {
terminal.userConn.Close()
}
}()
} else {
terminal.userConn = conn
defer func() {
@ -284,6 +292,15 @@ 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 {
@ -293,16 +310,41 @@ func (cp *commonPage) terminal(c *gin.Context) {
if msgType == websocket.TextMessage {
data = append([]byte{0}, data...)
}
dataCh <- data
}
}()
var dataBuffer [][]byte
var distConn *websocket.Conn
for {
select {
case <-deadlineCh:
if distConn == nil {
return
}
case data := <-dataCh:
dataBuffer = append(dataBuffer, data)
if distConn == nil {
// 传递给对方
if isAgent {
err = terminal.userConn.WriteMessage(websocket.BinaryMessage, data)
distConn = terminal.userConn
} else {
err = terminal.agentConn.WriteMessage(websocket.BinaryMessage, data)
distConn = terminal.agentConn
}
}
if distConn != nil {
for i := 0; i < len(dataBuffer); i++ {
err = distConn.WriteMessage(websocket.BinaryMessage, dataBuffer[i])
if err != nil {
return
}
}
dataBuffer = dataBuffer[:0]
}
}
}
}
type createTerminalRequest struct {

View File

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