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]