Twisted - 将数据从服务器发送到客户端

use*_*302 4 python twisted

我是Twisted的新手,并且阅读了许多与我遇到的问题类似的相关帖子.但是,我无法推断以前的答案来解决我的简单问题.我确实参考了Twisted的FAQ部分 - 我仍然无法弄清楚.

我的问题是我有一个服务器在一个端口监听,当我收到一个"START"命令时,我想和几个客户交谈.作为一个例子,我使用了一个客户端,它为我提供了一个幸运饼干.但是,我无法在服务器代码中与客户端通信.你能告诉我哪里出错吗?这是代码:

from twisted.internet import reactor, protocol
from twisted.internet.protocol import Protocol, Factory

class FakeTelnet(Protocol):
    def connectionMade(self):
        print 'local connection made'
        self.otherFact = protocol.ClientFactory()
        self.otherFact.protocol = EchoClient
        self.factory.clients.append(self.otherFact.protocol)
        reactor.connectTCP('psrfb6',10999, self.otherFact)

    def dataReceived(self, data):

        if 'START' in data:
            # send a command to cookie server.
            for client in self.factory.clients:
                client.transport.write('START\r\n')

    def connectionLost(self):
        print 'connection lost'

class EchoClient(Protocol):
    """Once connected, send a message, then print the result."""

    def connectionMade(self):
        print "Connection to cookie server"

    def dataReceived(self, data):
        "As soon as any data is received, write it back."
        print "Fortune Server said:", data

    def connectionLost(self):
        print "connection lost"

    def send_stuff(data):
        self.transport.write(data);

class MyFactory(Factory):
    protocol = FakeTelnet
    def __init__(self, EchoClient):
        self.clients = []
        self.otherCli = EchoClient

reactor.listenTCP(5823, MyFactory(EchoClient))
reactor.run()
Run Code Online (Sandbox Code Playgroud)

Jea*_*one 5

class FakeTelnet(Protocol):
    def connectionMade(self):
        print 'local connection made'
        self.otherFact = protocol.ClientFactory()
        self.otherFact.protocol = EchoClient
Run Code Online (Sandbox Code Playgroud)

在这里,你设置self.otherFact.protocol为EchoClient 类.

        self.factory.clients.append(self.otherFact.protocol)
Run Code Online (Sandbox Code Playgroud)

在这里,您可以将EchoClient 类添加到self.factory.clients列表中.这只会导致一遍又一遍地self.factory.clients成为一个完整的EchoClient 类列表.

def dataReceived(self, data):
    if 'START' in data:
        # send a command to cookie server.
        for client in self.factory.clients:
            client.transport.write('START\r\n')
Run Code Online (Sandbox Code Playgroud)

在这里,您尝试写入EchoClient.transport通常是None,因为它只是一个协议类的实例连接到传输,而不是类本身.

请尝试添加连接的实例self.factory.clients.我想你正在设法创建这样的实例,因为你还有这一行FakeTelnet.connectionMade:

    reactor.connectTCP('psrfb6',10999, self.otherFact)
Run Code Online (Sandbox Code Playgroud)

但是,您没有做任何可以让连接协议进入self.factory.clients列表的操作.也许你可以这样定义self.otherFact:

class OtherFactory(ClientFactory):
    protocol = EchoClient

    def __init__(self, originalFactory):
        self.originalFactory = originalFactory

    def buildProtocol(self, addr):
        proto = ClientFactory.buildProtocol(self, addr)
        self.originalFactory.clients.append(proto)
        return proto
Run Code Online (Sandbox Code Playgroud)

您还希望在某些时候从列表中删除内容clients.也许在connectionLost协议的回调中:

class EchoClient(Protocol):
    ...
    def connectionLost(self, reason):
        self.factory.originalFactory.clients.remove(self)
Run Code Online (Sandbox Code Playgroud)

最后,如果要处理面向行的数据,您可能希望将其twisted.protocols.basic.LineOnlyReceiver用作基类FakeTelnet并将其逻辑放入其lineReceived回调中.该dataReceived回调不会做出有关数据边界的保证,所以你可能永远不会看到包含一个字符串"START".例如,你可能会得到两个调用dataReceived,一个与"ST"另用"ART".