在单独的线程中扭曲transport.write

时间:2015-01-26 08:04:31

标签: python multithreading twisted

我希望从客户端收到消息,并通过单独的独立流程向他们发送消息。我尝试过的代码使用了扭曲的线程方法。我试图在另一个线程上运行方法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()

1 个答案:

答案 0 :(得分:2)

你不应该在Twisted中使用raw_input。它阻止了主线程。您无法从其他线程调用transport.write,因为必须从Twisted线程调用所有使用Twisted执行I / O的方法。

看起来你在这里要做的就是编写一个命令行程序,该程序采用标准输入(带行编辑)并将其发送到所有当前连接的客户端,并从中获取所有输入那些客户端并将其发送到控制台。希望以下示例显示如何使用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)