import React, { Component } from 'react'; import './index.scss' import { Terminal } from "xterm" import 'xterm/css/xterm.css' import { FitAddon } from "xterm-addon-fit"; import { http } from "@/utils" import { Toast } from "antd-mobile"; import axios from 'axios' class TerminalInterface extends Component { terminal = null termElem = null quit = '\u0003' socket = null state = { terminalWidth: '', } componentDidMount() { const content = document.querySelector('.container .content') const contentStyles = window.getComputedStyle(content) const contentWidth = content.clientWidth const contentPaddingLeft = parseFloat(contentStyles.getPropertyValue('padding-left')) this.setState({ terminalWidth: `${contentWidth - contentPaddingLeft}px`, }) this.terminal = new Terminal() const fitAddon = new FitAddon() this.terminal.loadAddon(fitAddon) this.terminal.open(this.termElem) const {result, executing} = this.props setTimeout(() => { fitAddon.fit() if (result) { this.terminal && this.terminal.write(this.props.result) } else if (executing) { this.getAuthenticationData() } }) } getAuthenticationData = () => { axios.post(`http://47.93.119.175:8888/auth`, { username: '3guh394h3fhj0f4', password: 'okqdw029j038hrv3890cv', }, { withCredentials: false, }).then(res => { const {code, msg, data} = res.data if (code === 0) { this.getLinkId(data) } else { Toast.fail(msg, 2) } }) } getLinkId = token => { axios.post(`http://47.93.119.175:8888`, {}, { headers: { Token: token, }, withCredentials: false, }).then(res => { const {id} = res.data this.connectServer(id) }) } connectServer = (id) => { this.socket = new WebSocket(`${API.ws}?id=${id}`) this.socket.addEventListener('open', () => { this.socket.send(JSON.stringify({ data: this.props.filename, })) }) this.socket.onmessage = event => { const reader = new FileReader() reader.onload = () => { this.terminal.write(this.ab2str(reader.result)) } reader.readAsArrayBuffer(event.data) } this.socket.onerror = (event) => { console.log(event) // this.connectServer(id) } this.socket.onclose = (event) => { console.log('closed') } } ab2str = buf => { return String.fromCharCode.apply(null, new Uint8Array(buf)); } render() { const {terminalWidth} = this.state return ( <div className={'terminal-container'}> <div className={'terminal'} ref={el => this.termElem = el} style={{width: `${terminalWidth}`}}></div> </div> ); } } export default TerminalInterface;