[英]What is the best way of handling received messages in Twisted for 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()
幾個問題:
handle_GOTDATA() function 是我接收收到的消息的地方,將其解析為告訴我如何處理數據的塊,然后根據需要對這些數據執行的操作調用不同的 function。 我是在同一個“MessageListener”class 中定義所有 20 個函數,還是編寫一個單獨的 class 來保留所有這些函數? 我可能會同時收到 10 條消息,它們可能需要調用相同的 function,所以我不確定這里的最佳架構方法。
我還想構建一個 GUI 來與服務器交互,以便偶爾進行一些故障排除和監控。 我熟悉 Tkinter ,這很好,我可以在單獨的文件中編寫 GUI 並讓它通過套接字連接到服務器。 但是我會使用上面實現的相同套接字偵聽器並傳遞類似的消息嗎? 或者我應該建立一個單獨的 class 和工廠來監聽 GUI 連接?
如果您要使用LineReceiver
,則不應覆蓋dataReceived
。 相反,覆蓋lineReceived
。 如果您的協議不是面向行的,您可能不想使用LineReceiver
。 此外,您可能需要考慮在任何一種情況下都使用Tubes接口。
我是在同一個“MessageListener”class 中定義所有 20 個函數,還是編寫一個單獨的 class 來保留所有這些函數?
您可能應該將它們放在不同的 class 上。 如果您將它們放在MessageListener
上,那么您將更難以測試、重構和維護代碼,因為您的協議邏輯與您的應用程序邏輯緊密耦合。
定義一個顯式接口, MessageListener
使用它來調度表示網絡操作的高級事件。 然后為您的特定應用程序適當地實現該接口。 稍后,您可以為另一個應用程序以不同的方式實現它。 或者您可以編寫測試替身。 或者您可以在不更改應用程序邏輯的情況下更改協議。 與將它們都粉碎成一個 class 相比,將這兩個部分解耦為您提供了更多的靈活性。
我可能會同時收到 10 條消息,它們可能需要調用相同的 function,所以我不確定這里的最佳架構方法。
我認為這是正交的,但如果它是您的協議或應用程序邏輯中足夠重要的部分,您可能需要考慮在我上面提到的顯式接口中構建某種矢量化。 而不是appObj.doOneThing(oneThing)
也許你有appObj.doSeveralThings([oneThing, anotherThing])
。
我還想構建一個 GUI 來與服務器交互,以便偶爾進行一些故障排除和監控。 我熟悉 Tkinter ,這很好,我可以在單獨的文件中編寫 GUI 並讓它通過套接字連接到服務器。 但是我會使用上面實現的相同套接字偵聽器並傳遞類似的消息嗎? 或者我應該建立一個單獨的 class 和工廠來監聽 GUI 連接?
我想這取決於你想要執行的交互。 如果這是一個與普通客戶端相比具有額外特權的 GUI,則您需要具有身份驗證和授權功能的協議和服務器,或者您不能使用相同的服務器和協議,因為您可能會給客戶端這些額外特權。
如果您只想使用一種調試友好的界面來模擬真實的客戶端,該界面使您可以輕松地以客戶端通常與服務器交互的方式與服務器交互,但使用使您更容易的界面,您可以(並且大概應該)連接到同一台服務器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.