在单独的线程中扭曲 transport.write
Twisted transport.write in separate thread
我想从客户端接收消息并通过单独的独立进程向他们发送消息。我尝试使用的代码使用了扭曲的线程方法。我尝试 运行 方法 sendMessage 在不同的线程上继续接收来自客户端的消息,但它等待用户键入文本。 运行 如何在不同的线程中使用 sendMessage 方法,以便即使服务器端未提供消息,程序也能继续接收客户端的数据?
我的代码:
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
import time
class MultiEcho(Protocol):
def __init__(self, factory):
self.factory = factory
def connectionMade(self):
self.factory.echoers.append(self)
def dataReceived(self, data):
print 'Client Said: ' + data
reactor.callFromThread(self.sendMessage)
def connectionLost(self, reason):
self.factory.echoers.remove(self)
def sendMessage(self):
app = raw_input('Send Message to client :')
for echoer in self.factory.echoers:
echoer.transport.write(app)
class MultiEchoFactory(Factory):
def __init__(self):
self.echoers = []
def buildProtocol(self, addr):
return MultiEcho(self)
reactor.listenTCP(8000, MultiEchoFactory())
reactor.run()
你不应该在 Twisted 中使用 raw_input
。它阻塞了主线程。您不能从不同的线程调用 transport.write
,因为所有使用 Twisted 来做 I/O 的方法都必须从 Twisted 线程调用。
看起来你在这里试图做的是编写一个命令行程序,它接受标准输入(通过行编辑)并将其发送到所有当前连接的客户端,并从中获取所有输入这些客户端并将其发送到控制台。希望下面的示例展示了如何使用 Twisted 自己的 API 完成类似的事情。
from twisted.python.failure import Failure
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, Factory
from twisted.conch.recvline import HistoricRecvLine
from twisted.conch.stdio import runWithProtocol
class ConsolePrompter(HistoricRecvLine, object):
ps = ["Message: "]
def __init__(self, multiEcho):
self.multiEcho = multiEcho
def lineReceived(self, line):
try:
if not line:
reactor.stop()
self.drawInputLine()
self.multiEcho.tellAllClients(line)
except:
f = Failure()
data = f.getTraceback()
self.terminal.write(data)
def clientSaid(self, data):
self.terminal.write("\r")
self.terminal.eraseLine()
self.terminal.write("Client Said:" + repr(data))
self.terminal.write("\n")
self.drawInputLine()
class MultiEcho(Protocol):
def __init__(self, factory):
self.factory = factory
def connectionMade(self):
self.factory.echoers.append(self)
def dataReceived(self, data):
self.factory.prompter.clientSaid(data)
def connectionLost(self, reason):
self.factory.echoers.remove(self)
class MultiEchoFactory(Factory):
def __init__(self):
self.echoers = []
self.prompter = ConsolePrompter(self)
def buildProtocol(self, addr):
return MultiEcho(self)
def tellAllClients(self, message):
for echoer in self.echoers:
echoer.transport.write(message + "\r\n")
mef = MultiEchoFactory()
reactor.listenTCP(8000, mef)
runWithProtocol(lambda: mef.prompter)
我想从客户端接收消息并通过单独的独立进程向他们发送消息。我尝试使用的代码使用了扭曲的线程方法。我尝试 运行 方法 sendMessage 在不同的线程上继续接收来自客户端的消息,但它等待用户键入文本。 运行 如何在不同的线程中使用 sendMessage 方法,以便即使服务器端未提供消息,程序也能继续接收客户端的数据? 我的代码:
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
import time
class MultiEcho(Protocol):
def __init__(self, factory):
self.factory = factory
def connectionMade(self):
self.factory.echoers.append(self)
def dataReceived(self, data):
print 'Client Said: ' + data
reactor.callFromThread(self.sendMessage)
def connectionLost(self, reason):
self.factory.echoers.remove(self)
def sendMessage(self):
app = raw_input('Send Message to client :')
for echoer in self.factory.echoers:
echoer.transport.write(app)
class MultiEchoFactory(Factory):
def __init__(self):
self.echoers = []
def buildProtocol(self, addr):
return MultiEcho(self)
reactor.listenTCP(8000, MultiEchoFactory())
reactor.run()
你不应该在 Twisted 中使用 raw_input
。它阻塞了主线程。您不能从不同的线程调用 transport.write
,因为所有使用 Twisted 来做 I/O 的方法都必须从 Twisted 线程调用。
看起来你在这里试图做的是编写一个命令行程序,它接受标准输入(通过行编辑)并将其发送到所有当前连接的客户端,并从中获取所有输入这些客户端并将其发送到控制台。希望下面的示例展示了如何使用 Twisted 自己的 API 完成类似的事情。
from twisted.python.failure import Failure
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, Factory
from twisted.conch.recvline import HistoricRecvLine
from twisted.conch.stdio import runWithProtocol
class ConsolePrompter(HistoricRecvLine, object):
ps = ["Message: "]
def __init__(self, multiEcho):
self.multiEcho = multiEcho
def lineReceived(self, line):
try:
if not line:
reactor.stop()
self.drawInputLine()
self.multiEcho.tellAllClients(line)
except:
f = Failure()
data = f.getTraceback()
self.terminal.write(data)
def clientSaid(self, data):
self.terminal.write("\r")
self.terminal.eraseLine()
self.terminal.write("Client Said:" + repr(data))
self.terminal.write("\n")
self.drawInputLine()
class MultiEcho(Protocol):
def __init__(self, factory):
self.factory = factory
def connectionMade(self):
self.factory.echoers.append(self)
def dataReceived(self, data):
self.factory.prompter.clientSaid(data)
def connectionLost(self, reason):
self.factory.echoers.remove(self)
class MultiEchoFactory(Factory):
def __init__(self):
self.echoers = []
self.prompter = ConsolePrompter(self)
def buildProtocol(self, addr):
return MultiEcho(self)
def tellAllClients(self, message):
for echoer in self.echoers:
echoer.transport.write(message + "\r\n")
mef = MultiEchoFactory()
reactor.listenTCP(8000, mef)
runWithProtocol(lambda: mef.prompter)