online compiler這是我的網站,用戶可以在其中運行控制檯程序。實時流stdout和stdin與websocket
目前,用戶在運行程序之前必須輸入程序輸入。我正在嘗試爲程序構建實時用戶輸入(希望在他們的筆記本電腦上運行程序時提供相同的體驗)。
在研究實現這一目標,我碰到一個解決流標準輸出和標準輸入與的WebSocket。
我實現
# coding: utf-8
import subprocess
import thread
from tornado.websocket import WebSocketHandler
from nbstreamreader import NonBlockingStreamReader as NBSR
class WSHandler(WebSocketHandler):
def open(self):
self.write_message("connected")
self.app = subprocess.Popen(['sh', 'app/shell.sh'], stdout=subprocess.PIPE, stdin=subprocess.PIPE,
shell=False)
self.nbsr = NBSR(self.app.stdout)
thread.start_new_thread(self.soutput,())
def on_message(self, incoming):
self.app.stdin.write(incoming)
def on_close(self):
self.write_message("disconnected")
def soutput(self):
while True:
output = self.nbsr.readline(0.1)
# 0.1 secs to let the shell output the result
if not output:
print 'No more data'
break
self.write_message(output)
nbstreamreader.py
from threading import Thread
from Queue import Queue, Empty
class NonBlockingStreamReader:
def __init__(self, stream):
'''
stream: the stream to read from.
Usually a process' stdout or stderr.
'''
self._s = stream
self._q = Queue()
def _populateQueue(stream, queue):
'''
Collect lines from 'stream' and put them in 'quque'.
'''
while True:
line = stream.readline()
if line:
queue.put(line)
else:
raise UnexpectedEndOfStream
self._t = Thread(target=_populateQueue,
args=(self._s, self._q))
self._t.daemon = True
self._t.start() # start collecting lines from the stream
def readline(self, timeout=None):
try:
return self._q.get(block=timeout is not None,
timeout=timeout)
except Empty:
return None
class UnexpectedEndOfStream(Exception): pass
shell.sh
#!/usr/bin/env bash
echo "hello world"
echo "hello world"
read -p "Your first name: " fname
read -p "Your last name: " lname
echo "Hello $fname $lname ! I am learning how to create shell scripts"
此碼流標準輸出未直到shell.sh碼達到閱讀聲明。
請指導我我在做什麼錯。爲什麼它不會等待stdin並在完成程序執行之前打印出'沒有更多數據'?
的源代碼來測試它https://github.com/mryogesh/streamconsole.git
您是否嘗試調試您的代碼? :) – 2017-01-03 13:54:39
是的,。它進入on_message方法,在thread.start_new_thread(self.soutput,())之後,我添加了print語句,這意味着線程不被阻塞。 –
當你(在輸入之後)擊中「what name」語句時發生了什麼?它是不是流式傳輸?如果你經歷了整個'shell.sh',甚至最後一個'echo'沒有流式傳輸,會發生什麼?這個問題讓我想起了一些事情(我在一年前完成了這一切,通過websocket進行syso流式處理,但目前我無法訪問該代碼;但我記得過早終止了流)。 –