Repaired websockets.

This commit is contained in:
retoor 2025-03-23 18:46:10 +01:00
parent 1de2c55966
commit 529606955a
3 changed files with 33 additions and 67 deletions

View File

@ -180,8 +180,8 @@ class Application(BaseApplication):
executor = ThreadPoolExecutor(max_workers=100) executor = ThreadPoolExecutor(max_workers=100)
loop = asyncio.get_event_loop() #loop = asyncio.get_event_loop()
loop.set_default_executor(executor) #loop.set_default_executor(executor)
app = Application(db_path="sqlite:///snek.db") app = Application(db_path="sqlite:///snek.db")

View File

@ -13,80 +13,42 @@ commands = {
} }
class TerminalSession: class TerminalSession:
async def ensure_process(self):
if self.process:
return
self.process = await asyncio.create_subprocess_exec(
*self.command.split(" "),
stdin=self.slave,
stdout=self.slave,
stderr=self.slave,bufsize=0,
universal_newlines=True
)
def __init__(self,command): def __init__(self,command):
self.master, self.slave = pty.openpty() self.master, self.slave = pty.openpty()
self.sockets =[] self.sockets =[]
self.buffer = b'' self.history = b''
self.process = None self.history_size = 1024*20
self.process = subprocess.Popen(
#self.process = subprocess.Popen( command.split(" "),
# command.split(" "), stdin=self.slave,
# stdin=self.slave, stdout=self.slave,
# stdout=self.slave, stderr=self.slave,
# stderr=self.slave, bufsize=0,
# bufsize=0, universal_newlines=True
# universal_newlines=True )
#)
async def add_websocket(self, ws):
asyncio.create_task(self.read_output(ws))
async def read_output(self, ws): async def read_output(self, ws):
await self.ensure_process()
self.sockets.append(ws) self.sockets.append(ws)
if len(self.sockets) > 1: if len(self.sockets) > 1 and self.buffer:
start = self.buffer.index(b'\n') start = 0
await ws.send_bytes(self.buffer[start:])
return
while True:
try: try:
async for data in self.process.stdout: start = self.history.index(b'\n')
if not data: except ValueError:
break pass
self.buffer += data await ws.send_bytes(self.history[start:])
if len(self.buffer) > 10000:
self.buffer = self.buffer[:-10000]
try:
for ws in self.sockets: await ws.send_bytes(data) # Send raw bytes for ANSI support
except:
self.sockets.remove(ws)
except:
print("Terminating process")
self.process.terminate()
print("Terminated process")
for ws in self.sockets:
try:
await ws.close()
except Exception:
pass
break
async def read_outputa(self, ws):
loop = asyncio.get_event_loop()
self.sockets.append(ws)
if len(self.sockets) > 1:
start = self.buffer.index(b'\n')
await ws.send_bytes(self.buffer[start:])
return return
loop = asyncio.get_event_loop()
while True: while True:
try: try:
data = await loop.run_in_executor(None, os.read, self.master, 1024) data = await loop.run_in_executor(None, os.read, self.master, 1024)
if not data: if not data:
break break
self.buffer += data self.history += data
if len(self.buffer) > 10000: if len(self.history) > self.history_size:
self.buffer = self.buffer[:-10000] self.history = self.history[:0-self.history_size]
try: try:
for ws in self.sockets: await ws.send_bytes(data) # Send raw bytes for ANSI support for ws in self.sockets: await ws.send_bytes(data) # Send raw bytes for ANSI support
except: except:
@ -103,7 +65,10 @@ class TerminalSession:
break break
async def write_input(self, data): async def write_input(self, data):
await self.ensure_process() try:
os.write(self.master, data.encode()) data = data.encode()
except AttributeError:
pass
await asyncio.get_event_loop().run_in_executor(
None, os.write, self.master, data
)

View File

@ -37,7 +37,8 @@ class TerminalSocketView(BaseView):
if not session: if not session:
self.user_sessions[user["uid"]] = TerminalSession(command=command) self.user_sessions[user["uid"]] = TerminalSession(command=command)
session = self.user_sessions[user["uid"]] session = self.user_sessions[user["uid"]]
asyncio.create_task(session.read_output(ws)) await session.add_websocket(ws)
#asyncio.create_task(session.read_output(ws))
async for msg in ws: async for msg in ws:
if msg.type == aiohttp.WSMsgType.BINARY: if msg.type == aiohttp.WSMsgType.BINARY: