且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用 websocket 直播标准输出和标准输入

更新时间:2023-11-17 23:52:46

除非您在 100 毫秒内发送输入,否则您的 readline() 方法会超时,这会中断循环.您没有看到 read -p 提示的原因是缓冲(因为 readline 和管道缓冲).最后,您的示例 javascript 不会发送尾随换行符,因此 read 不会返回.

Your readline() method times out unless you send input within 100ms, which then breaks the loop. The reason you don't see the read -p prompt is buffering (because of readline and pipe buffering). Finally, your example javascript doesn't send a trailing newline, so read will not return.

如果您增加超时,请添加一个换行符,并且 找到解决缓冲问题的方法,您的示例应该基本上可以工作.

If you increase the timeout, include a newline, and find a way to work around buffering issues, your example should basically work.

我也会使用 tornado.process 和协程而不是子进程和线程:

I'd also use tornado.process and coroutines instead of subprocess and thread:

from tornado import gen
from tornado.process import Subprocess
from tornado.ioloop import IOLoop
from tornado.iostream import StreamClosedError
from tornado.websocket import WebSocketHandler


class WSHandler(WebSocketHandler):
    def open(self):
        self.app = Subprocess(['script', '-q', 'sh', 'app/shell.sh'], stdout=Subprocess.STREAM, stdin=Subprocess.STREAM)
        IOLoop.current().spawn_callback(self.stream_output)

    def on_message(self, incoming):
        self.app.stdin.write(incoming.encode('utf-8'))

    @gen.coroutine
    def stream_output(self):
        try:
            while True:
                line = yield self.app.stdout.read_bytes(1000, partial=True)
                self.write_message(line.decode('utf-8'))
        except StreamClosedError:
            pass