add terminal input stdio

This commit is contained in:
beanjs 2024-09-27 11:28:48 +08:00
parent 418695c4aa
commit 659078f9d6
7 changed files with 45 additions and 6 deletions

View File

@ -1,5 +1,6 @@
import { Service, Inject } from 'typedi';
import winston from 'winston';
import { Connection } from 'sockjs';
import nodeSchedule from 'node-schedule';
import { ChildProcessWithoutNullStreams } from 'child_process';
import {
@ -33,6 +34,7 @@ export interface TaskCallbacks {
) => Promise<void>;
onLog?: (message: string) => Promise<void>;
onError?: (message: string) => Promise<void>;
onMessage?:(cb:(msg:string,conn:Connection)=>void)=>void;
}
@Service()
@ -120,6 +122,10 @@ export default class ScheduleService {
);
resolve({ ...others, pid: cp.pid, code });
});
callbacks.onMessage?.((msg:string,conn:Connection)=>{
cp.stdin.write(JSON.parse(msg).message)
})
} catch (error) {
this.logger.error(
'[panel][执行任务失败] 命令: %s, 错误信息: %j',

View File

@ -1,4 +1,5 @@
import { Service, Inject } from 'typedi';
import { Connection } from 'sockjs';
import winston from 'winston';
import path, { join } from 'path';
import SockService from './sock';
@ -22,6 +23,7 @@ export default class ScriptService {
return {
onEnd: async (cp, endTime, diff) => {
await rmPath(filePath);
this.sockService.removeAllListeners('message')
},
onError: async (message: string) => {
this.sockService.sendMessage({
@ -35,6 +37,10 @@ export default class ScriptService {
message,
});
},
onMessage:(cb:(msg:string,conn:Connection)=>void)=>{
this.sockService.off('message',cb)
this.sockService.on('message',cb)
},
};
}

View File

@ -2,12 +2,15 @@ import { Service, Inject } from 'typedi';
import winston from 'winston';
import { Connection } from 'sockjs';
import { SockMessage } from '../data/sock';
import EventEmitter from 'events';
@Service()
export default class SockService {
export default class SockService extends EventEmitter{
private clients: Connection[] = [];
constructor(@Inject('logger') private logger: winston.Logger) { }
constructor(@Inject('logger') private logger: winston.Logger) {
super()
}
public getClients() {
return this.clients;
@ -16,11 +19,17 @@ export default class SockService {
public addClient(conn: Connection) {
if (this.clients.indexOf(conn) === -1) {
this.clients.push(conn);
conn.on('data',(msg:string)=>{
this.emit('message',msg,conn)
});
}
}
public removeClient(conn: Connection) {
const index = this.clients.indexOf(conn);
conn.removeAllListeners('data')
if (index !== -1) {
this.clients.splice(index, 1);
}

View File

@ -486,5 +486,7 @@
"NPM 镜像源": "NPM Mirror Source",
"PyPI 镜像源": "PyPI Mirror Source",
"alpine linux 镜像源": "Alpine Linux Mirror Source",
"如果恢复失败,可进入容器执行": "If recovery fails, you can enter the container and execute"
"如果恢复失败,可进入容器执行": "If recovery fails, you can enter the container and execute",
"终端输入": "terminal input",
"发送": "send"
}

View File

@ -486,5 +486,7 @@
"NPM 镜像源": "NPM 镜像源",
"PyPI 镜像源": "PyPI 镜像源",
"alpine linux 镜像源": "alpine linux 镜像源",
"如果恢复失败,可进入容器执行": "如果恢复失败,可进入容器执行"
"如果恢复失败,可进入容器执行": "如果恢复失败,可进入容器执行",
"终端输入": "终端输入",
"发送": "发送"
}

View File

@ -6,7 +6,7 @@ import React, {
useCallback,
useReducer,
} from 'react';
import { Drawer, Button, Tabs, Badge, Select, TreeSelect } from 'antd';
import { Drawer, Button, Tabs, Badge, Select, TreeSelect, Input } from 'antd';
import { request } from '@/utils/http';
import config from '@/utils/config';
import SplitPane from 'react-split-pane';
@ -41,6 +41,7 @@ const EditModal = ({
const [settingModalVisible, setSettingModalVisible] =
useState<boolean>(false);
const [log, setLog] = useState('');
const [raw, setRaw] = useState('')
const { theme } = useTheme();
const editorRef = useRef<any>(null);
const [isRunning, setIsRunning] = useState(false);
@ -124,6 +125,12 @@ const EditModal = ({
setLog((p) => `${p}${_message}`);
}, []);
const send=()=>{
const ws = WebSocketManager.getInstance();
ws.send({ type:'terminalInput', message:raw })
setRaw('')
}
useEffect(() => {
const ws = WebSocketManager.getInstance();
ws.subscribe('manuallyRunScript', handleMessage);
@ -253,6 +260,12 @@ const EditModal = ({
padding: '0 15px',
}}
>
<div style={{ minWidth: 0, display: 'flex', alignItems: 'center', gap:'8px' }}>
<Input placeholder={intl.get('终端输入')} value={raw} onChange={(e)=>{
setRaw(e.target.value)
}}></Input>
<Button type="primary" onClick={send}>{intl.get('发送')}</Button>
</div>
<Ansi>{log}</Ansi>
</pre>
</SplitPane>

View File

@ -7,4 +7,5 @@ export type SockMessageType =
| 'runSubscriptionEnd'
| 'reloadSystem'
| 'updateNodeMirror'
| 'updateLinuxMirror';
| 'updateLinuxMirror'
| 'terminalInput';