增加对会话操作的优化提示
This commit is contained in:
@ -36,7 +36,7 @@ func SessionPagingEndpoint(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(items); i++ {
|
for i := 0; i < len(items); i++ {
|
||||||
if len(items[i].Recording) > 0 {
|
if status == model.Disconnected && len(items[i].Recording) > 0 {
|
||||||
recording := items[i].Recording + "/recording"
|
recording := items[i].Recording + "/recording"
|
||||||
|
|
||||||
if utils.FileExists(recording) {
|
if utils.FileExists(recording) {
|
||||||
@ -82,7 +82,9 @@ func SessionContentEndpoint(c echo.Context) error {
|
|||||||
session.Status = model.Connected
|
session.Status = model.Connected
|
||||||
session.ConnectedTime = utils.NowJsonTime()
|
session.ConnectedTime = utils.NowJsonTime()
|
||||||
|
|
||||||
model.UpdateSessionById(&session, sessionId)
|
if err := model.UpdateSessionById(&session, sessionId); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,16 +93,20 @@ func SessionDiscontentEndpoint(c echo.Context) error {
|
|||||||
|
|
||||||
split := strings.Split(sessionIds, ",")
|
split := strings.Split(sessionIds, ",")
|
||||||
for i := range split {
|
for i := range split {
|
||||||
CloseSessionById(split[i], ForcedDisconnect, "管理员强制关闭了此次接入。")
|
CloseSessionById(split[i], ForcedDisconnect, "强制断开")
|
||||||
}
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CloseSessionById(sessionId string, code int, reason string) {
|
func CloseSessionById(sessionId string, code int, reason string) {
|
||||||
tun, _ := global.Store.Get(sessionId)
|
observable, _ := global.Store.Get(sessionId)
|
||||||
if tun != nil {
|
if observable != nil {
|
||||||
_ = tun.Tun.Close()
|
_ = observable.Subject.Tunnel.Close()
|
||||||
CloseSessionByWebSocket(tun.WebSocket, code, reason)
|
for i := 0; i < len(observable.Observers); i++ {
|
||||||
|
_ = observable.Observers[i].Tunnel.Close()
|
||||||
|
CloseWebSocket(observable.Observers[i].WebSocket, code, reason)
|
||||||
|
}
|
||||||
|
CloseWebSocket(observable.Subject.WebSocket, code, reason)
|
||||||
}
|
}
|
||||||
global.Store.Del(sessionId)
|
global.Store.Del(sessionId)
|
||||||
|
|
||||||
@ -126,10 +132,10 @@ func CloseSessionById(sessionId string, code int, reason string) {
|
|||||||
session.Code = code
|
session.Code = code
|
||||||
session.Message = reason
|
session.Message = reason
|
||||||
|
|
||||||
model.UpdateSessionById(&session, sessionId)
|
_ = model.UpdateSessionById(&session, sessionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CloseSessionByWebSocket(ws *websocket.Conn, c int, t string) {
|
func CloseWebSocket(ws *websocket.Conn, c int, t string) {
|
||||||
if ws == nil {
|
if ws == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -157,13 +163,10 @@ func SessionResizeEndpoint(c echo.Context) error {
|
|||||||
|
|
||||||
intHeight, _ := strconv.Atoi(height)
|
intHeight, _ := strconv.Atoi(height)
|
||||||
|
|
||||||
session := model.Session{}
|
if err := model.UpdateSessionWindowSizeById(intWidth, intHeight, sessionId); err != nil {
|
||||||
session.ID = sessionId
|
return err
|
||||||
session.Width = intWidth
|
}
|
||||||
session.Height = intHeight
|
return Success(c, "")
|
||||||
|
|
||||||
model.UpdateSessionById(&session, sessionId)
|
|
||||||
return Success(c, session)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SessionCreateEndpoint(c echo.Context) error {
|
func SessionCreateEndpoint(c echo.Context) error {
|
||||||
@ -239,7 +242,7 @@ func SessionUploadEndpoint(c echo.Context) error {
|
|||||||
return errors.New("获取sftp客户端失败")
|
return errors.New("获取sftp客户端失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
dstFile, err := tun.SftpClient.Create(remoteFile)
|
dstFile, err := tun.Subject.SftpClient.Create(remoteFile)
|
||||||
defer dstFile.Close()
|
defer dstFile.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -292,7 +295,7 @@ func SessionDownloadEndpoint(c echo.Context) error {
|
|||||||
return errors.New("获取sftp客户端失败")
|
return errors.New("获取sftp客户端失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
dstFile, err := tun.SftpClient.Open(remoteFile)
|
dstFile, err := tun.Subject.SftpClient.Open(remoteFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -341,16 +344,16 @@ func SessionLsEndpoint(c echo.Context) error {
|
|||||||
return errors.New("获取sftp客户端失败")
|
return errors.New("获取sftp客户端失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
if tun.SftpClient == nil {
|
if tun.Subject.SftpClient == nil {
|
||||||
sftpClient, err := CreateSftpClient(session.AssetId)
|
sftpClient, err := CreateSftpClient(session.AssetId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("创建sftp客户端失败:%v", err.Error())
|
logrus.Errorf("创建sftp客户端失败:%v", err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tun.SftpClient = sftpClient
|
tun.Subject.SftpClient = sftpClient
|
||||||
}
|
}
|
||||||
|
|
||||||
fileInfos, err := tun.SftpClient.ReadDir(remoteDir)
|
fileInfos, err := tun.Subject.SftpClient.ReadDir(remoteDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -410,7 +413,7 @@ func SessionMkDirEndpoint(c echo.Context) error {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("获取sftp客户端失败")
|
return errors.New("获取sftp客户端失败")
|
||||||
}
|
}
|
||||||
if err := tun.SftpClient.Mkdir(remoteDir); err != nil {
|
if err := tun.Subject.SftpClient.Mkdir(remoteDir); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
@ -441,18 +444,18 @@ func SessionRmDirEndpoint(c echo.Context) error {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("获取sftp客户端失败")
|
return errors.New("获取sftp客户端失败")
|
||||||
}
|
}
|
||||||
fileInfos, err := tun.SftpClient.ReadDir(remoteDir)
|
fileInfos, err := tun.Subject.SftpClient.ReadDir(remoteDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range fileInfos {
|
for i := range fileInfos {
|
||||||
if err := tun.SftpClient.Remove(path.Join(remoteDir, fileInfos[i].Name())); err != nil {
|
if err := tun.Subject.SftpClient.Remove(path.Join(remoteDir, fileInfos[i].Name())); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tun.SftpClient.RemoveDirectory(remoteDir); err != nil {
|
if err := tun.Subject.SftpClient.RemoveDirectory(remoteDir); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
@ -483,7 +486,7 @@ func SessionRmEndpoint(c echo.Context) error {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("获取sftp客户端失败")
|
return errors.New("获取sftp客户端失败")
|
||||||
}
|
}
|
||||||
if err := tun.SftpClient.Remove(remoteFile); err != nil {
|
if err := tun.Subject.SftpClient.Remove(remoteFile); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -49,9 +51,13 @@ func TunEndpoint(c echo.Context) error {
|
|||||||
if len(connectionId) > 0 {
|
if len(connectionId) > 0 {
|
||||||
session, err = model.FindSessionByConnectionId(connectionId)
|
session, err = model.FindSessionByConnectionId(connectionId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
CloseSessionById(sessionId, NotFoundSession, "会话不存在")
|
CloseWebSocket(ws, NotFoundSession, "会话不存在")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if session.Status != model.Connected {
|
||||||
|
CloseWebSocket(ws, NotFoundSession, "会话未在线")
|
||||||
|
return errors.New("会话未在线")
|
||||||
|
}
|
||||||
configuration.ConnectionID = connectionId
|
configuration.ConnectionID = connectionId
|
||||||
} else {
|
} else {
|
||||||
session, err = model.FindSessionById(sessionId)
|
session, err = model.FindSessionById(sessionId)
|
||||||
@ -131,38 +137,62 @@ func TunEndpoint(c echo.Context) error {
|
|||||||
|
|
||||||
tunnel, err := guacd.NewTunnel(addr, configuration)
|
tunnel, err := guacd.NewTunnel(addr, configuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if connectionId == "" {
|
||||||
CloseSessionById(sessionId, NewTunnelError, err.Error())
|
CloseSessionById(sessionId, NewTunnelError, err.Error())
|
||||||
|
}
|
||||||
logrus.Printf("建立连接失败: %v", err.Error())
|
logrus.Printf("建立连接失败: %v", err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tun := global.Tun{
|
tun := global.Tun{
|
||||||
Tun: tunnel,
|
Tunnel: tunnel,
|
||||||
WebSocket: ws,
|
WebSocket: ws,
|
||||||
}
|
}
|
||||||
|
|
||||||
global.Store.Set(sessionId, &tun)
|
|
||||||
|
|
||||||
if len(session.ConnectionId) == 0 {
|
if len(session.ConnectionId) == 0 {
|
||||||
|
var observers []global.Tun
|
||||||
|
observable := global.Observable{
|
||||||
|
Subject: &tun,
|
||||||
|
Observers: observers,
|
||||||
|
}
|
||||||
|
|
||||||
|
global.Store.Set(sessionId, &observable)
|
||||||
|
// 创建新会话
|
||||||
session.ConnectionId = tunnel.UUID
|
session.ConnectionId = tunnel.UUID
|
||||||
session.Width = intWidth
|
session.Width = intWidth
|
||||||
session.Height = intHeight
|
session.Height = intHeight
|
||||||
session.Status = model.Connecting
|
session.Status = model.Connecting
|
||||||
session.Recording = configuration.GetParameter(guacd.RecordingPath)
|
session.Recording = configuration.GetParameter(guacd.RecordingPath)
|
||||||
|
|
||||||
model.UpdateSessionById(&session, sessionId)
|
if err := model.UpdateSessionById(&session, sessionId); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO 处理监控会话的退出
|
||||||
|
// 监控会话
|
||||||
|
observable, ok := global.Store.Get(sessionId)
|
||||||
|
if ok {
|
||||||
|
observers := append(observable.Observers, tun)
|
||||||
|
observable.Observers = observers
|
||||||
|
global.Store.Set(sessionId, observable)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for true {
|
for true {
|
||||||
instruction, err := tunnel.Read()
|
instruction, err := tunnel.Read()
|
||||||
|
fmt.Printf("<- %v \n", string(instruction))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
CloseSessionById(sessionId, TunnelClosed, "隧道已关闭")
|
if connectionId == "" {
|
||||||
|
CloseSessionById(sessionId, TunnelClosed, "远程连接关闭")
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = ws.WriteMessage(websocket.TextMessage, instruction)
|
err = ws.WriteMessage(websocket.TextMessage, instruction)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
CloseSessionById(sessionId, TunnelClosed, "隧道已关闭")
|
if connectionId == "" {
|
||||||
|
CloseSessionById(sessionId, Normal, "正常退出")
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,12 +201,16 @@ func TunEndpoint(c echo.Context) error {
|
|||||||
for true {
|
for true {
|
||||||
_, message, err := ws.ReadMessage()
|
_, message, err := ws.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
CloseSessionById(sessionId, Normal, "用户主动关闭了会话")
|
if connectionId == "" {
|
||||||
|
CloseSessionById(sessionId, Normal, "正常退出")
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
_, err = tunnel.WriteAndFlush(message)
|
_, err = tunnel.WriteAndFlush(message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
CloseSessionById(sessionId, Normal, "用户主动关闭了会话")
|
if connectionId == "" {
|
||||||
|
CloseSessionById(sessionId, TunnelClosed, "远程连接关闭")
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,16 +8,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Tun struct {
|
type Tun struct {
|
||||||
Tun *guacd.Tunnel
|
Tunnel *guacd.Tunnel
|
||||||
SftpClient *sftp.Client
|
SftpClient *sftp.Client
|
||||||
WebSocket *websocket.Conn
|
WebSocket *websocket.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Observable struct {
|
||||||
|
Subject *Tun
|
||||||
|
Observers []Tun
|
||||||
|
}
|
||||||
|
|
||||||
type TunStore struct {
|
type TunStore struct {
|
||||||
m sync.Map
|
m sync.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TunStore) Set(k string, v *Tun) {
|
func (s *TunStore) Set(k string, v *Observable) {
|
||||||
s.m.Store(k, v)
|
s.m.Store(k, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,10 +30,10 @@ func (s *TunStore) Del(k string) {
|
|||||||
s.m.Delete(k)
|
s.m.Delete(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TunStore) Get(k string) (item *Tun, ok bool) {
|
func (s *TunStore) Get(k string) (item *Observable, ok bool) {
|
||||||
value, ok := s.m.Load(k)
|
value, ok := s.m.Load(k)
|
||||||
if ok {
|
if ok {
|
||||||
return value.(*Tun), true
|
return value.(*Observable), true
|
||||||
}
|
}
|
||||||
return item, false
|
return item, false
|
||||||
}
|
}
|
||||||
|
@ -151,9 +151,9 @@ func NewTunnel(address string, config Configuration) (ret *Tunnel, err error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ret.WriteInstructionAndFlush(NewInstruction("timezone", "Asia/Shanghai")); err != nil {
|
//if err := ret.WriteInstructionAndFlush(NewInstruction("timezone", "Asia/Shanghai")); err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
//}
|
||||||
|
|
||||||
parameters := make([]string, len(args.Args))
|
parameters := make([]string, len(args.Args))
|
||||||
for i := range args.Args {
|
for i := range args.Args {
|
||||||
@ -198,7 +198,7 @@ func (opt *Tunnel) WriteInstruction(instruction Instruction) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (opt *Tunnel) WriteAndFlush(p []byte) (int, error) {
|
func (opt *Tunnel) WriteAndFlush(p []byte) (int, error) {
|
||||||
//fmt.Printf("-> %v \n", string(p))
|
fmt.Printf("-> %v \n", string(p))
|
||||||
nn, err := opt.rw.Write(p)
|
nn, err := opt.rw.Write(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nn, err
|
return nn, err
|
||||||
@ -211,7 +211,7 @@ func (opt *Tunnel) WriteAndFlush(p []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (opt *Tunnel) Write(p []byte) (int, error) {
|
func (opt *Tunnel) Write(p []byte) (int, error) {
|
||||||
//fmt.Printf("-> %v \n", string(p))
|
fmt.Printf("-> %v \n", string(p))
|
||||||
nn, err := opt.rw.Write(p)
|
nn, err := opt.rw.Write(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nn, err
|
return nn, err
|
||||||
@ -225,6 +225,7 @@ func (opt *Tunnel) Flush() error {
|
|||||||
|
|
||||||
func (opt *Tunnel) ReadInstruction() (instruction Instruction, err error) {
|
func (opt *Tunnel) ReadInstruction() (instruction Instruction, err error) {
|
||||||
msg, err := opt.rw.ReadString(Delimiter)
|
msg, err := opt.rw.ReadString(Delimiter)
|
||||||
|
fmt.Printf("<- %v \n", msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return instruction, err
|
return instruction, err
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,6 @@ package handle
|
|||||||
import (
|
import (
|
||||||
"github.com/robfig/cron/v3"
|
"github.com/robfig/cron/v3"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"next-terminal/pkg/api"
|
|
||||||
"next-terminal/pkg/global"
|
|
||||||
"next-terminal/pkg/guacd"
|
"next-terminal/pkg/guacd"
|
||||||
"next-terminal/pkg/model"
|
"next-terminal/pkg/model"
|
||||||
"next-terminal/pkg/utils"
|
"next-terminal/pkg/utils"
|
||||||
@ -42,21 +40,6 @@ func RunTicker() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 定时任务,每隔一分钟校验一次运行中的会话信息
|
|
||||||
_, _ = c.AddFunc("0 0/1 0/1 * * ?", func() {
|
|
||||||
sessions, _ := model.FindSessionByStatus(model.Connected)
|
|
||||||
if sessions != nil && len(sessions) > 0 {
|
|
||||||
for i := range sessions {
|
|
||||||
_, found := global.Store.Get(sessions[i].ID)
|
|
||||||
if !found {
|
|
||||||
api.CloseSessionById(sessions[i].ID, api.Normal, "")
|
|
||||||
s := sessions[i].Username + "@" + sessions[i].IP + ":" + strconv.Itoa(sessions[i].Port)
|
|
||||||
logrus.Infof("会话「%v」ID「%v」已离线,修改状态为「关闭」。", s, sessions[i].ID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
c.Start()
|
c.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +55,7 @@ func RunDataFix() {
|
|||||||
DisconnectedTime: utils.NowJsonTime(),
|
DisconnectedTime: utils.NowJsonTime(),
|
||||||
}
|
}
|
||||||
|
|
||||||
model.UpdateSessionById(&session, sessions[i].ID)
|
_ = model.UpdateSessionById(&session, sessions[i].ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,9 +132,17 @@ func FindSessionByConnectionId(connectionId string) (o Session, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateSessionById(o *Session, id string) {
|
func UpdateSessionById(o *Session, id string) error {
|
||||||
o.ID = id
|
o.ID = id
|
||||||
global.DB.Updates(o)
|
return global.DB.Updates(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateSessionWindowSizeById(width, height int, id string) error {
|
||||||
|
session := Session{}
|
||||||
|
session.Width = width
|
||||||
|
session.Height = height
|
||||||
|
|
||||||
|
return UpdateSessionById(&session, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteSessionById(id string) {
|
func DeleteSessionById(id string) {
|
||||||
|
@ -503,7 +503,7 @@ class Access extends Component {
|
|||||||
let stateChecker = setInterval(async () => {
|
let stateChecker = setInterval(async () => {
|
||||||
let result = await request.get(`/sessions/${sessionId}`);
|
let result = await request.get(`/sessions/${sessionId}`);
|
||||||
if (result['code'] !== 1) {
|
if (result['code'] !== 1) {
|
||||||
message.error(result['message']);
|
clearInterval(stateChecker);
|
||||||
} else {
|
} else {
|
||||||
let session = result['data'];
|
let session = result['data'];
|
||||||
if (session['status'] === 'connected') {
|
if (session['status'] === 'connected') {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import Guacamole from 'guacamole-common-js';
|
import Guacamole from 'guacamole-common-js';
|
||||||
import {message, Modal} from 'antd'
|
import {Modal, Result, Spin} from 'antd'
|
||||||
import qs from "qs";
|
import qs from "qs";
|
||||||
import {wsServer} from "../../common/constants";
|
import {wsServer} from "../../common/constants";
|
||||||
import {getToken} from "../../utils/utils";
|
import {getToken} from "../../utils/utils";
|
||||||
@ -20,9 +20,12 @@ class Access extends Component {
|
|||||||
state = {
|
state = {
|
||||||
client: {},
|
client: {},
|
||||||
containerOverflow: 'hidden',
|
containerOverflow: 'hidden',
|
||||||
containerWidth: 0,
|
width: 0,
|
||||||
containerHeight: 0,
|
height: 0,
|
||||||
rate: 1
|
rate: 1,
|
||||||
|
loading: false,
|
||||||
|
tip: '',
|
||||||
|
closed: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
@ -38,8 +41,8 @@ class Access extends Component {
|
|||||||
height = height * 2;
|
height = height * 2;
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
containerWidth: width * rate,
|
width: width * rate,
|
||||||
containerHeight: height * rate,
|
height: height * rate,
|
||||||
rate: rate,
|
rate: rate,
|
||||||
})
|
})
|
||||||
this.renderDisplay(connectionId);
|
this.renderDisplay(connectionId);
|
||||||
@ -53,40 +56,47 @@ class Access extends Component {
|
|||||||
|
|
||||||
onTunnelStateChange = (state) => {
|
onTunnelStateChange = (state) => {
|
||||||
console.log('onTunnelStateChange', state);
|
console.log('onTunnelStateChange', state);
|
||||||
|
if (state === Guacamole.Tunnel.State.CLOSED) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
closed: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onClientStateChange = (state) => {
|
onClientStateChange = (state) => {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
console.log('初始化');
|
this.setState({
|
||||||
message.destroy();
|
loading: true,
|
||||||
message.loading('正在初始化中...', 0);
|
tip: '正在初始化中...'
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case STATE_CONNECTING:
|
case STATE_CONNECTING:
|
||||||
console.log('正在连接...');
|
this.setState({
|
||||||
message.destroy();
|
loading: true,
|
||||||
message.loading('正在努力连接中...', 0);
|
tip: '正在努力连接中...'
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case STATE_WAITING:
|
case STATE_WAITING:
|
||||||
console.log('正在等待...');
|
this.setState({
|
||||||
message.destroy();
|
loading: true,
|
||||||
message.loading('正在等待服务器响应...', 0);
|
tip: '正在等待服务器响应...'
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case STATE_CONNECTED:
|
case STATE_CONNECTED:
|
||||||
console.log('连接成功。');
|
this.setState({
|
||||||
message.destroy();
|
loading: false
|
||||||
message.success('连接成功');
|
});
|
||||||
if (this.state.client) {
|
if (this.state.client) {
|
||||||
this.state.client.getDisplay().scale(this.state.rate);
|
this.state.client.getDisplay().scale(this.state.rate);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_DISCONNECTING:
|
case STATE_DISCONNECTING:
|
||||||
console.log('连接正在关闭中...');
|
|
||||||
message.destroy();
|
|
||||||
break;
|
break;
|
||||||
case STATE_DISCONNECTED:
|
case STATE_DISCONNECTED:
|
||||||
console.log('连接关闭。');
|
|
||||||
message.destroy();
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -211,16 +221,26 @@ class Access extends Component {
|
|||||||
render() {
|
render() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<Spin spinning={this.state.loading} tip={this.state.tip}>
|
||||||
<div>
|
<div>
|
||||||
|
{
|
||||||
|
this.state.closed ?
|
||||||
|
<Result
|
||||||
|
title="远程连接已关闭"
|
||||||
|
/> :
|
||||||
<div className="container" style={{
|
<div className="container" style={{
|
||||||
overflow: this.state.containerOverflow,
|
overflow: this.state.containerOverflow,
|
||||||
width: this.state.containerWidth,
|
width: this.state.width,
|
||||||
height: this.state.containerHeight
|
height: this.state.height
|
||||||
}}>
|
}}>
|
||||||
|
|
||||||
<div id="display"/>
|
<div id="display"/>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</Spin>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,6 +470,8 @@ class OnlineSession extends Component {
|
|||||||
loading={this.state.loading}
|
loading={this.state.loading}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{
|
||||||
|
this.state.accessVisible ?
|
||||||
<Modal
|
<Modal
|
||||||
className='monitor'
|
className='monitor'
|
||||||
title={this.state.sessionTitle}
|
title={this.state.sessionTitle}
|
||||||
@ -480,6 +482,7 @@ class OnlineSession extends Component {
|
|||||||
width={window.innerWidth * 0.8}
|
width={window.innerWidth * 0.8}
|
||||||
height={window.innerWidth * 0.8 / this.state.sessionWidth * this.state.sessionHeight}
|
height={window.innerWidth * 0.8 / this.state.sessionWidth * this.state.sessionHeight}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
|
message.destroy();
|
||||||
this.setState({accessVisible: false})
|
this.setState({accessVisible: false})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -490,7 +493,9 @@ class OnlineSession extends Component {
|
|||||||
rate={window.innerWidth * 0.8 / this.state.sessionWidth}>
|
rate={window.innerWidth * 0.8 / this.state.sessionWidth}>
|
||||||
|
|
||||||
</Monitor>
|
</Monitor>
|
||||||
</Modal>
|
</Modal> : undefined
|
||||||
|
}
|
||||||
|
|
||||||
</Content>
|
</Content>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user