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

发布于 2024-11-26 05:34:52 字数 1578 浏览 0 评论 0原文

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

我的问题是,我有一台服务器在一个端口侦听,当我收到“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()

I am new to Twisted, and have read many related posts similar to the problem that I have. However, I am unable to extrapolate the previous answers to solve my simple problem. I did refer to the FAQ section of Twisted - I still can't figure out.

My problem is that I have a server listening at one port, and when I receive a "START" command, I would like to talk to several clients. As an example, I used a single client, that serves me a fortune cookie. However, I am unable to talk to client from with in the server code. Can you please tell where I am going wrong? Here is the code:

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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜宝宝 2024-12-03 05:34:52
class FakeTelnet(Protocol):
    def connectionMade(self):
        print 'local connection made'
        self.otherFact = protocol.ClientFactory()
        self.otherFact.protocol = EchoClient

在这里,您将 self.otherFact.protocol 设置为 EchoClient

        self.factory.clients.append(self.otherFact.protocol)

在这里,您将 EchoClient 添加到 self.factory.clients 列表中。这只会导致 self.factory.clients 一遍又一遍地成为一个充满 EchoClient class 的列表。

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')

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

尝试将连接的实例添加到 self.factory.clients 中。我认为您正在设法创建这样的实例,因为您在 FakeTelnet.connectionMade 中也有这一行:

    reactor.connectTCP('psrfb6',10999, self.otherFact)

但是,您没有做任何事情来让您将连接的协议放入 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

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

class EchoClient(Protocol):
    ...
    def connectionLost(self, reason):
        self.factory.originalFactory.clients.remove(self)

最后,您可能希望使用 twisted.protocols.basic.LineOnlyReceiver 作为 FakeTelnet 的基类如果您正在处理面向行的数据,请将您的逻辑放入其 lineReceived 回调中。 dataReceived 回调不保证数据边界,因此您可能永远不会看到包含 "START" 的单个字符串。例如,您可能会收到两次对 dataReceived 的调用,一次调用 "ST",另一次调用 "ART"

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

Here, you set self.otherFact.protocol to be the EchoClient class.

        self.factory.clients.append(self.otherFact.protocol)

Here you add the EchoClient class to the self.factory.clients list. This can only cause self.factory.clients to be a list full of the EchoClient class over and over again.

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')

Here you try to write to EchoClient.transport which will generally be None, since it is only ever instances of a protocol class which get connected to a transport, not the classes themselves.

Try adding connected instances to self.factory.clients instead. You are managing to create such instances, I think, since you also have this line in FakeTelnet.connectionMade:

    reactor.connectTCP('psrfb6',10999, self.otherFact)

However, you aren't doing anything that would let you get the connected protocol into the self.factory.clients list. Perhaps you could define self.otherFact like this instead:

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

You will also want to remove things from the clients list at some point. Perhaps in the connectionLost callback of the protocol:

class EchoClient(Protocol):
    ...
    def connectionLost(self, reason):
        self.factory.originalFactory.clients.remove(self)

Finally, you may want to use twisted.protocols.basic.LineOnlyReceiver as the base class for FakeTelnet and put your logic in its lineReceived callback, if you are dealing with line-oriented data. The dataReceived callback does not make guarantees about data boundaries, so you may never see a single string containing "START". For example, you might get two calls to dataReceived, one with "ST" and the other with "ART".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文