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

2024-10-17 06:26:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python的新手,正在寻求架构方面的帮助。这是我的设置:我有一个用LiveCode编写的遗留客户端应用程序,它在多个位置运行,根据服务器的要求显示同步信息。把它想象成一个信息亭。这篇客户文章哪儿也去不了

服务器应用程序就是我用Python重写的。我的目标是让服务器应用程序持续运行,监听客户端套接字连接,并向这些客户端发送/接收数据。我已经成功地在这个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()函数用于接收接收到的消息,将其解析为块,这些块告诉我如何处理数据,然后根据需要对该数据执行的操作调用不同的函数。 我是在同一个“MessageListener”类中定义所有20个函数,还是编写一个单独的类来保留所有这些函数?我可能会同时收到10条消息,它们可能需要调用相同的函数,所以我不确定这里的最佳架构方法

  2. 我还想构建一个GUI来与服务器交互,以便偶尔进行一些故障排除和监视。我对Tkinter很熟悉,这很好,我可以在一个单独的文件中编写GUI,并让它通过套接字连接到服务器。但是,我会使用上面实现的同一个套接字侦听器并向其传递类似的消息吗?或者我应该构建一个单独的类和工厂来监听GUI连接吗


Tags: theto函数fromimportself服务器消息
1条回答
网友
1楼 · 发布于 2024-10-17 06:26:21

如果要使用LineReceiver,则不应重写dataReceived。相反,重写lineReceived。如果您的协议不是面向行的,那么您可能不想使用LineReceiver。此外,您可能需要考虑在任一种情况下使用Tubes接口。

Do I just define all 20 of these functions in this same “MessageListener” class, or do I write a separate class to keep all of these functions?

你可能应该把他们放在另一个班上。如果将它们放在MessageListener上,那么测试、重构和维护代码将更加困难,因为协议逻辑与应用程序逻辑紧密耦合

定义一个显式接口MessageListener用于调度表示网络操作的高级事件。然后针对您的特定应用程序适当地实现该接口。稍后,您可以为另一个应用程序以不同的方式实现它。或者您可以编写测试双精度。或者,您可以在不更改应用程序逻辑的情况下更改协议。与将这两个部分拆分为一个类相比,将这两个部分解耦可以为您提供更多的灵活性

I might get 10 messages at about the same time, and they may need to call the same function, so I wasn’t sure the best architecture approach here.

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

I also want to build a GUI to interact with the server for some troubleshooting and monitoring on occasion. I’m familiar with Tkinter and it would be fine for this, and I can write the GUI in a separate file and have it connect to the server over a socket as well. But would I use the same socket listener implemented above and just pass it similar messages? Or should I build a separate class and factory to listen for the GUI connections?

我想,这取决于您想要执行的交互。如果这是一个与普通客户端相比具有额外权限的GUI,则需要一个具有身份验证和授权功能的协议和服务器,或者您不能使用相同的服务器和协议,因为您可能会向客户端授予这些额外权限

如果您只是想用一种调试友好的界面来模拟一个真正的客户机,该界面允许您以客户机通常与服务器交互的方式轻松地与服务器交互,但是使用一种让您更轻松的界面,那么您可以(并且应该)连接到同一台服务器

相关问题 更多 >