65 lines
2.0 KiB
Python
65 lines
2.0 KiB
Python
import os
|
|
import subprocess
|
|
from flask import Blueprint, request, current_app, session
|
|
from flask_socketio import SocketIO, emit, join_room
|
|
from threading import Thread
|
|
import sys
|
|
from ..extensions import socketio
|
|
|
|
terminal_bp = Blueprint('terminal', __name__, url_prefix='/vsc-like')
|
|
|
|
# 存储终端进程
|
|
terminals = {}
|
|
|
|
def start_terminal_process(socket_id):
|
|
# 启动一个 bash 终端
|
|
process = subprocess.Popen(
|
|
['bash'],
|
|
stdin=subprocess.PIPE,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
text=True
|
|
)
|
|
|
|
# 监听进程的输出
|
|
while True:
|
|
output = process.stdout.readline()
|
|
if output:
|
|
emit('terminal_output', {'data': output}, room=socket_id)
|
|
if process.poll() is not None:
|
|
break
|
|
|
|
@socketio.on('connect', namespace='/vsc-like/terminal')
|
|
def connect_terminal():
|
|
socket_id = session.get('uuid')
|
|
path = session.get('path')
|
|
if not path:
|
|
emit('error', {'message': 'Authentication failed, no path found for this session'})
|
|
return False # 拒绝连接
|
|
terminals[socket_id] = subprocess.Popen(
|
|
['bash'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
|
|
)
|
|
emit('connected', {'message': 'Terminal connected'})
|
|
join_room(path, namespace='/vsc-like/terminal')
|
|
# 启动监听终端输出的线程
|
|
thread = Thread(target=start_terminal_process, args=(socket_id,))
|
|
thread.daemon = True
|
|
thread.start()
|
|
|
|
@socketio.on('send_input', namespace='/vsc-like/terminal')
|
|
def send_input(data):
|
|
socket_id = session.get('uuid')
|
|
path = session.get('path')
|
|
input_data = data.get('input')
|
|
if socket_id in terminals:
|
|
terminals[socket_id].stdin.write(input_data + '\n')
|
|
terminals[socket_id].stdin.flush()
|
|
|
|
@socketio.on('disconnect', namespace='/vsc-like/terminal')
|
|
def disconnect_terminal():
|
|
socket_id = session.get('uuid')
|
|
path = session.get('path')
|
|
if socket_id in terminals:
|
|
terminals[socket_id].terminate()
|
|
del terminals[socket_id]
|