在单独的线程中扭曲 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)