我正在尝试实现一个简单的命令行客户端,它接受来自服务器的消息并将它们打印到标准输出,同时用户输入转换为服务器请求的命令。现在它是用twisted和Cmd完成的:
from sys import stdout
from cmd import Cmd
from twisted.internet import reactor
from twisted.internet.protocol import Protocol
from twisted.internet.endpoints import TCP4ClientEndpoint, connectProtocol
class MyCmd(Cmd):
def __init__(self, client):
Cmd.__init__(self)
self.client = client
def default(self, line):
client.sendData(line)
def do_EOF(self, line):
if reactor.running:
reactor.stop()
stdout.write("\n")
return True
class MyClient(Protocol):
def dataReceived(self, data):
stdout.write(data)
def sendData(self, data):
self.transport.write(data)
self.transport.write("\n")
point = TCP4ClientEndpoint(reactor, "localhost", 6004)
client = MyClient()
connectProtocol(point, client)
reactor.callInThread(MyCmd(client).cmdloop)
reactor.run()
这需要异步完成,因为服务器有时只是向客户端发送未经请求的数据。
但是这样,MyClient.dataReceived
写入stdout的文本与Cmd的控制台处理冲突,使其几乎无法使用。
我正在考虑使用某种控制台UI库(如Urwid或ncurses)将MyCmd和MyClient的输出放入屏幕的不同部分。
2009年的这个帖子表明,Urwid可能无法实现: http://lists.excess.org/pipermail/urwid/2009-July/000715.html
用ncurses做这件事的要点对我来说效果不好:https://gist.github.com/interstar/3005137
还能以某种方式吗?