我正在开发一个 Flask/gevent WSGIserver Web 服务器,它需要使用 XML 通过两个套接字与硬件设备进行通信(在后台)。
一个套接字由客户端(我的应用程序)启动,我可以向设备发送 XML 命令。设备在不同的端口上应答并发回我的应用程序必须确认的信息。所以我的应用程序必须监听第二个端口。
到目前为止,我已经发出命令,打开第二个端口作为服务器,等待设备的响应并关闭第二个端口。
问题是设备可能会发送多个我必须确认的响应。所以我的解决方案是保持端口打开并继续响应传入的请求。然而,最终设备完成发送请求,而我的应用程序仍在侦听(我不知道设备何时完成),从而阻止了其他一切。
这似乎是线程的完美用例,因此我的应用程序在单独的线程中启动侦听服务器。因为我已经使用 gevent 作为 Flask 的 WSGI 服务器,所以我可以使用 greenlet。
问题是,我一直在寻找此类事情的一个很好的示例,但我所能找到的只是单个套接字服务器的多线程处理程序的示例。我不需要处理套接字服务器上的大量连接,但我需要在单独的线程中启动它,以便它可以侦听和处理传入消息,同时我的主程序可以继续发送消息。
我遇到的第二个问题是在服务器中,我需要使用“主”类中的一些方法。作为 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(...)
这就是(在全球范围内,我遗漏了敏感信息)我现在正在做的事情。正如你所看到的,一切都是有顺序的。
如果任何人都可以提供一个单独线程中的侦听服务器的示例(最好使用 greenlet)以及从侦听服务器返回到生成线程的通信方式,这将有很大帮助。
Thanks.
EDIT:尝试了几种方法后,我决定使用Python默认的select()方法来解决这个问题。这有效,所以我关于线程使用的问题不再相关。感谢那些为您的时间和精力提供意见的人们。