Twisted for Python中处理接收到的消息的最佳方式是什么?

问题描述 投票:0回答:1

我是一个Python新手,希望得到一些架构方面的帮助。 这是我的设置。 我有一个用LiveCode写的传统客户端应用,它在多个地方运行,根据服务器的需求显示同步信息。 把它想象成一个信息亭。 客户端这一块是不会去的。

服务器应用程序是我用Python重写的。 我的目标是让服务器应用程序不断地运行,监听客户端的socket连接,并向这些客户端发送接收数据。 我已经成功地在这个LiveCode客户端应用程序和一个使用Twisted处理套接字的python脚本之间传递消息,所以现在我需要开始处理这些消息。 代码看起来像这样。

from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor

class MessageListener(LineReceiver):

    def __init__(self, users):
        self.users = users
        self.name = None

    def connectionMade(self):
        d = self.transport.getHost()
        print("Connection established with {}:{}".format(d.host, d.port))

    def connectionLost(self, reason):
        print("Connection lost: {}".format(reason))
        if self.name in self.users:
            del self.users[self.name]

    def dataReceived(self, line):
        d = self.transport.getHost()
        print("Received message from {}:{}...{}".format(d.host, d.port, line))
        self.handle_GOTDATA(line)

    def handle_GOTDATA(self, msg):
        #convert "msg" to string and parse it into the necessary chunks

        #*****Go do something based on the requestor and the command*****
        #Use if-elif or dictionary to determine which function to run
        #based on what the string tells us.
        #Should these functions be defined here or in a separate class?

class MessageListenerFactory(Factory):

    def __init__(self):
        self.users = {} # maps user names to Chat instances

    def buildProtocol(self, addr):
        return MessageListener(self.users)

reactor.listenTCP(50010, MessageListenerFactory())

reactor.run()

有几个问题

  1. handle_GOTDATA()函数是我接收到消息的地方,将其解析成块,告诉我如何处理数据,然后根据需要对数据进行处理,调用不同的函数。 我可能会在差不多的时间收到10条消息,它们可能需要调用同一个函数,所以我不确定这里的最佳架构方法。

  2. 我还想建立一个GUI来与服务器交互,以便偶尔进行一些故障诊断和监控。 我对Tkinter很熟悉,用它来做这件事就可以了,我可以把GUI写在一个单独的文件中,让它也通过socket连接到服务器上。 但是,我是用上面实现的那个socket监听器,给它传递类似的消息就可以了吗? 还是我应该建立一个单独的类和工厂来监听GUI的连接?

python twisted twisted.internet
1个回答
0
投票

如果你打算使用 LineReceiver,你不应该覆盖 dataReceived. 相反,覆盖 lineReceived. 如果你的协议不是面向行的,你可能不想使用 LineReceiver. 此外,您可能会考虑使用 管子 接口中的任何一种情况。

我是在同一个 "MessageListener "类中定义这20个函数,还是写一个单独的类来保存所有这些函数?

你可能应该把它们放在一个不同的类上。 如果你把它们放在 MessageListener 那么你将会有更多的困难来测试、重构和维护代码,因为你的协议逻辑与你的应用逻辑是紧密耦合的。

定义一个显式接口,它可以 MessageListener 用来调度代表网络操作的高级事件。 然后为您的特定应用程序适当地实现该接口。 之后,你可以为另一个应用程序实现不同的接口。 或者你可以写测试双工。 或者你可以改变你的协议而不改变你的应用逻辑。 与将这两部分分解成一个类相比,解耦这两部分给了你很多额外的灵活性。

我可能会在差不多的时间收到10条消息,它们可能需要调用同一个函数,所以我不确定这里的最佳架构方法。

我认为这是正交的,但如果它是你的协议或应用逻辑中足够重要的一部分,你可能要考虑在我上面提到的显式接口中构建某种矢量化。 取而代之的是 appObj.doOneThing(oneThing) 也许你有 appObj.doSeveralThings([oneThing, anotherThing]).

我还想建立一个GUI来与服务器交互,以便偶尔进行一些故障诊断和监控。我对Tkinter很熟悉,用它来做就可以了,而且我可以把GUI写在一个单独的文件里,让它也通过socket连接到服务器上。但是,我是用上面实现的那个socket监听器,给它传递类似的消息就可以了吗?还是我应该建立一个单独的类和工厂来监听GUI的连接?

我想,这取决于你想要执行的交互。 如果这是一个与普通客户端相比具有额外权限的GUI,你需要一个具有认证和授权功能的协议和服务器,否则你一定不能使用相同的服务器和协议,因为你有可能给客户端这些额外的权限。

如果你只是想用一种调试友好的界面来模拟一个真实的客户端,让你轻松地以客户端通常会与服务器交互的方式与服务器进行交互,但用一个界面让你更容易做到这一点,你可以(大概也应该)连接到同一个服务器。

© www.soinside.com 2019 - 2024. All rights reserved.