我正在开发一个 Flask/gevent WSGIserver 网络服务器,它需要使用 XML 通过两个套接字与硬件设备进行通信(在后台)。
一个套接字由客户端(我的应用程序)启动,我可以向设备发送 XML 命令。设备在不同的端口上应答并发回我的应用程序必须确认的信息。所以我的应用程序必须监听第二个端口。
到目前为止,我已经发出命令,打开第二个端口作为服务器,等待设备的响应并关闭第二个端口。
问题是设备可能会发送多个我必须确认的响应。所以我的解决方案是保持端口打开并继续响应传入的请求。但是,最终设备完成发送请求,而我的应用程序仍在侦听(我不知道设备何时完成),从而阻塞了其他所有内容。
这似乎是一个完美的线程用例,因此我的应用程序在单独的线程中启动了一个监听服务器。因为我已经在使用 gevent 作为 Flask 的 WSGI 服务器,所以我可以使用 greenlets。
问题是,我已经寻找了一个很好的例子,但我能找到的只是单个套接字服务器的多线程处理程序的例子。我不需要处理套接字服务器上的大量连接,但我需要在单独的线程中启动它,以便它可以侦听和处理传入消息,而我的主程序可以继续发送消息。我遇到的第二个问题是在服务器中,我需要使用“主”类中的一些方法。作为 Python 的新手,我不确定如何以某种方式构建它以使其成为可能。
class Device(object):
def __init__(self, ...):
self.clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def _connect_to_device(self):
print "OPEN CONNECTION TO DEVICE"
try:
self.clientsocket.connect((self.ip, 5100))
except socket.error as e:
pass
def _disconnect_from_device(self):
print "CLOSE CONNECTION TO DEVICE"
self.clientsocket.close()
def deviceaction1(self, ...):
# the data that is sent is an XML document that depends on the parameters of this method.
self._connect_to_device()
self._send_data(XMLdoc)
self._wait_for_response()
return True
def _send_data(self, data):
print "SEND:"
print(data)
self.clientsocket.send(data)
def _wait_for_response(self):
print "WAITING FOR REQUESTS FROM DEVICE (CHANNEL 1)"
self.serversocket.bind(('10.0.0.16', 5102))
self.serversocket.listen(5) # listen for answer, maximum 5 connections
connection, address = self.serversocket.accept()
# the data is of a specific length I can calculate
if len(data) > 0:
self._process_response(data)
self.serversocket.close()
def _process_response(self, data):
print "RECEIVED:"
print(data)
# here is some code that processes the incoming data and
# responds to the device
# this may or may not result in more incoming data
if __name__ == '__main__':
machine = Device(ip="10.0.0.240")
Device.deviceaction1(...)
这就是(在全球范围内,我忽略了敏感信息)我现在正在做的事情。如您所见,一切都是顺序的。如果有人可以在单独的线程中提供监听服务器的示例(最好使用greenlets)以及从监听服务器返回到生成线程的通信方式,那将有很大帮助。
谢谢。
编辑: 尝试了几种方法后,我决定使用 Python 的默认select()方法来解决这个问题。这行得通,所以我关于线程使用的问题不再相关。感谢为您的时间和精力提供意见的人。