import React, {Component} from 'react';
import Guacamole from 'guacamole-common-js';
import {Affix, Button, Col, Drawer, Dropdown, Form, Input, Menu, message, Modal, Row} from 'antd'
import qs from "qs";
import request from "../../common/request";
import {wsServer} from "../../common/constants";
import {
AppstoreTwoTone,
CopyTwoTone,
DesktopOutlined,
ExclamationCircleOutlined,
ExpandOutlined
} from '@ant-design/icons';
import {exitFull, getToken, isEmpty, requestFullScreen} from "../../utils/utils";
import './Access.css'
import Draggable from 'react-draggable';
import FileSystem from "./FileSystem";
const {TextArea} = Input;
const STATE_IDLE = 0;
const STATE_CONNECTING = 1;
const STATE_WAITING = 2;
const STATE_CONNECTED = 3;
const STATE_DISCONNECTING = 4;
const STATE_DISCONNECTED = 5;
class Access extends Component {
clipboardFormRef = React.createRef();
state = {
sessionId: '',
client: {},
clientState: STATE_IDLE,
clipboardVisible: false,
clipboardText: '',
containerOverflow: 'hidden',
containerWidth: 0,
containerHeight: 0,
uploadAction: '',
uploadHeaders: {},
keyboard: {},
protocol: '',
confirmLoading: false,
uploadVisible: false,
uploadLoading: false,
startTime: new Date(),
fullScreen: false,
fullScreenBtnText: '进入全屏'
};
async componentDidMount() {
let urlParams = new URLSearchParams(this.props.location.search);
let assetId = urlParams.get('assetId');
document.title = urlParams.get('assetName');
let protocol = urlParams.get('protocol');
let sessionId = await this.createSession(assetId);
if (isEmpty(sessionId)) {
return;
}
this.setState({
sessionId: sessionId,
protocol: protocol
});
this.renderDisplay(sessionId, protocol);
window.addEventListener('resize', this.onWindowResize);
window.onfocus = this.onWindowFocus;
}
componentWillUnmount() {
if (this.state.client) {
this.state.client.disconnect();
}
}
sendClipboard(data) {
let writer;
// Create stream with proper mimetype
const stream = this.state.client.createClipboardStream(data.type);
// Send data as a string if it is stored as a string
if (typeof data.data === 'string') {
writer = new Guacamole.StringWriter(stream);
writer.sendText(data.data);
writer.sendEnd();
} else {
// Write File/Blob asynchronously
writer = new Guacamole.BlobWriter(stream);
writer.oncomplete = function clipboardSent() {
writer.sendEnd();
};
// Begin sending data
writer.sendBlob(data.data);
}
this.setState({
clipboardText: data.data
})
if (this.state.protocol === 'ssh') {
if (data.data && data.data.length > 0) {
message.info('您输入的内容已复制到远程服务器上,使用右键将自动粘贴。');
}
} else {
if (data.data && data.data.length > 0) {
message.info('您输入的内容已复制到远程服务器上');
}
}
}
onTunnelStateChange = (state) => {
if (state === Guacamole.Tunnel.State.CLOSED) {
console.log('web socket 已关闭');
}
};
updateSessionStatus = async (sessionId) => {
let result = await request.post(`/sessions/${sessionId}/connect`);
if (result.code !== 1) {
message.error(result.message);
}
}
onClientStateChange = (state) => {
this.setState({
clientState: state
});
switch (state) {
case STATE_IDLE:
message.destroy();
message.loading('正在初始化中...', 0);
break;
case STATE_CONNECTING:
message.destroy();
message.loading('正在努力连接中...', 0);
break;
case STATE_WAITING:
message.destroy();
message.loading('正在等待服务器响应...', 0);
break;
case STATE_CONNECTED:
this.onWindowResize(null);
message.destroy();
message.success('连接成功');
// 向后台发送请求,更新会话的状态
this.updateSessionStatus(this.state.sessionId).then(_ => {
})
break;
case STATE_DISCONNECTING:
message.destroy();
message.loading('正在关闭连接...', 0);
break;
case STATE_DISCONNECTED:
message.destroy();
message.error('连接关闭');
break;
default:
break;
}
};
onError = (status) => {
console.log('通道异常。', status);
switch (status.code) {
case 256:
this.showMessage('未支持的访问');
break;
case 512:
this.showMessage('远程服务异常');
break;
case 513:
this.showMessage('服务器忙碌');
break;
case 514:
this.showMessage('服务器连接超时');
break;
case 515:
this.showMessage('远程服务异常');
break;
case 516:
this.showMessage('资源未找到');
break;
case 517:
this.showMessage('资源冲突');
break;
case 518:
this.showMessage('资源已关闭');
break;
case 519:
if (new Date().getTime() - this.state.startTime.getTime() <= 1000 * 30) {
this.showMessage('认证失败');
} else {
this.showMessage('远程服务未找到');
}
break;
case 520:
this.showMessage('远程服务不可用');
break;
case 521:
this.showMessage('会话冲突');
break;
case 522:
this.showMessage('会话连接超时');
break;
case 523:
this.showMessage('会话已关闭');
break;
case 768:
this.showMessage('网络不可达');
break;
case 769:
this.showMessage('服务器密码验证失败');
break;
case 771:
this.showMessage('客户端被禁止');
break;
case 776:
this.showMessage('客户端连接超时');
break;
case 781:
this.showMessage('客户端异常');
break;
case 783:
this.showMessage('错误的请求类型');
break;
case 800:
this.showMessage('会话不存在');
break;
case 801:
this.showMessage('创建隧道失败');
break;
case 802:
this.showMessage('管理员强制断开了此会话');
break;
default:
this.showMessage('未知错误。');
}
};
showMessage(msg) {
message.destroy();
Modal.confirm({
title: '提示',
icon: