实现可运行的xterm.js方案
This commit is contained in:
@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"next-terminal/pkg/utils"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -26,22 +27,29 @@ type Recorder struct {
|
||||
timestamp int
|
||||
}
|
||||
|
||||
func NewRecorder(filename string) (recorder *Recorder, err error) {
|
||||
func NewRecorder(dir string) (recorder *Recorder, filename string, err error) {
|
||||
recorder = &Recorder{}
|
||||
|
||||
if utils.FileExists(filename) {
|
||||
if err := os.RemoveAll(filename); err != nil {
|
||||
return nil, err
|
||||
if utils.FileExists(dir) {
|
||||
if err := os.RemoveAll(dir); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
|
||||
if err = os.MkdirAll(dir, 0777); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
filename = path.Join(dir, "recording.cast")
|
||||
|
||||
var file *os.File
|
||||
file, err = os.Create(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
recorder.file = file
|
||||
return recorder, nil
|
||||
return recorder, filename, nil
|
||||
}
|
||||
|
||||
func (recorder *Recorder) Close() {
|
||||
|
@ -38,7 +38,13 @@ func SessionPagingEndpoint(c echo.Context) error {
|
||||
|
||||
for i := 0; i < len(items); i++ {
|
||||
if status == model.Disconnected && len(items[i].Recording) > 0 {
|
||||
recording := items[i].Recording + "/recording"
|
||||
|
||||
var recording string
|
||||
if items[i].Protocol == "rdp" || items[i].Protocol == "vnc" {
|
||||
recording = items[i].Recording + "/recording"
|
||||
} else {
|
||||
recording = items[i].Recording
|
||||
}
|
||||
|
||||
if utils.FileExists(recording) {
|
||||
logrus.Debugf("检测到录屏文件[%v]存在", recording)
|
||||
@ -107,12 +113,14 @@ func CloseSessionById(sessionId string, code int, reason string) {
|
||||
observable, _ := global.Store.Get(sessionId)
|
||||
if observable != nil {
|
||||
logrus.Debugf("会话%v创建者退出", observable.Subject.Tunnel.UUID)
|
||||
_ = observable.Subject.Tunnel.Close()
|
||||
observable.Subject.Close()
|
||||
|
||||
for i := 0; i < len(observable.Observers); i++ {
|
||||
_ = observable.Observers[i].Tunnel.Close()
|
||||
observable.Observers[i].Close()
|
||||
CloseWebSocket(observable.Observers[i].WebSocket, code, reason)
|
||||
logrus.Debugf("强制踢出会话%v的观察者", observable.Observers[i].Tunnel.UUID)
|
||||
}
|
||||
|
||||
CloseWebSocket(observable.Subject.WebSocket, code, reason)
|
||||
}
|
||||
global.Store.Del(sessionId)
|
||||
@ -529,8 +537,15 @@ func SessionRecordingEndpoint(c echo.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
recording := path.Join(session.Recording, "recording")
|
||||
logrus.Debugf("读取录屏文件:%s", recording)
|
||||
|
||||
var recording string
|
||||
if session.Protocol == "rdp" || session.Protocol == "vnc" {
|
||||
recording = session.Recording + "/recording"
|
||||
} else {
|
||||
recording = session.Recording
|
||||
}
|
||||
|
||||
logrus.Debugf("读取录屏文件:%v,是否存在: %v, 是否为文件: %v", recording, utils.FileExists(recording), utils.IsFile(recording))
|
||||
return c.File(recording)
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,10 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"net/http"
|
||||
"next-terminal/pkg/guacd"
|
||||
"next-terminal/pkg/model"
|
||||
"next-terminal/pkg/utils"
|
||||
"path"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
@ -65,7 +67,7 @@ type WindowSize struct {
|
||||
Rows int `json:"rows"`
|
||||
}
|
||||
|
||||
func SSHEndpoint(c echo.Context) error {
|
||||
func SSHEndpoint(c echo.Context) (err error) {
|
||||
ws, err := UpGrader.Upgrade(c.Response().Writer, c.Request(), nil)
|
||||
if err != nil {
|
||||
logrus.Errorf("升级为WebSocket协议失败:%v", err.Error())
|
||||
@ -149,30 +151,44 @@ func SSHEndpoint(c echo.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
var recorder *Recorder
|
||||
var recording string
|
||||
property, _ := model.FindPropertyByName(guacd.RecordingPath)
|
||||
if property.Value != "" {
|
||||
dir := path.Join(property.Value, sessionId)
|
||||
recorder, recording, err = NewRecorder(dir)
|
||||
if err != nil {
|
||||
msg := Message{
|
||||
Type: Closed,
|
||||
Content: "创建录屏文件失败 :( " + err.Error(),
|
||||
}
|
||||
return WriteMessage(ws, msg)
|
||||
}
|
||||
|
||||
header := &Header{
|
||||
Title: "test",
|
||||
Version: 2,
|
||||
Height: height,
|
||||
Width: width,
|
||||
Env: Env{Shell: "/bin/bash", Term: "xterm-256color"},
|
||||
Timestamp: int(time.Now().Unix()),
|
||||
}
|
||||
|
||||
if err := recorder.WriteHeader(header); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := model.UpdateSessionById(&model.Session{Recording: recording}, sessionId); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
msg := Message{
|
||||
Type: Connected,
|
||||
Content: "Connect to server successfully.\r\n",
|
||||
}
|
||||
_ = WriteMessage(ws, msg)
|
||||
|
||||
recorder, err := NewRecorder("./" + sessionId + ".cast")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
header := &Header{
|
||||
Title: "test",
|
||||
Version: 2,
|
||||
Height: height,
|
||||
Width: width,
|
||||
Env: Env{Shell: "/bin/bash", Term: "xterm-256color"},
|
||||
Timestamp: int(time.Now().Unix()),
|
||||
}
|
||||
|
||||
if err := recorder.WriteHeader(header); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var mut sync.Mutex
|
||||
var active = true
|
||||
|
||||
@ -181,7 +197,10 @@ func SSHEndpoint(c echo.Context) error {
|
||||
mut.Lock()
|
||||
if !active {
|
||||
logrus.Debugf("会话: %v -> %v 关闭", sshClient.LocalAddr().String(), sshClient.RemoteAddr().String())
|
||||
recorder.Close()
|
||||
if recorder != nil {
|
||||
recorder.Close()
|
||||
}
|
||||
CloseSessionById(sessionId, Normal, "正常退出")
|
||||
break
|
||||
}
|
||||
mut.Unlock()
|
||||
@ -192,8 +211,10 @@ func SSHEndpoint(c echo.Context) error {
|
||||
}
|
||||
if n > 0 {
|
||||
s := string(p)
|
||||
// 录屏
|
||||
_ = recorder.WriteData(s)
|
||||
if recorder != nil {
|
||||
// 录屏
|
||||
_ = recorder.WriteData(s)
|
||||
}
|
||||
msg := Message{
|
||||
Type: Data,
|
||||
Content: s,
|
||||
|
@ -145,6 +145,7 @@ func TunEndpoint(c echo.Context) error {
|
||||
}
|
||||
|
||||
tun := global.Tun{
|
||||
Protocol: configuration.Protocol,
|
||||
Tunnel: tunnel,
|
||||
WebSocket: ws,
|
||||
}
|
||||
|
Reference in New Issue
Block a user