Во-первых, если у вас есть контроль над целевым API, я бы предложил реализовать ответ для каждого сообщения. Ответ ACK (подтверждение) для каждого отправленного сообщения сделает ваш API более надежным и полностью устранит эту проблему.
Если это не вариант, то я хотел бы создать классы для различных типов сообщений:
class Message(object):
def __init__(self, msg):
self.msg = msg
class MessageWReply(Message):
await_reply = True
class MessageNoReply(Message):
await_reply = False
Создать все ваши классы сообщений, а затем использовать их, как это:
def send_message(self, message, host):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((host, self.PORT))
s.send(bytes(message, 'ascii'))
if message.await_reply:
data = s.recv(1024)
print(data)
В качестве альтернативы , если вы не хотите накладных расходов на создание всех классов, вы можете использовать словарь для сопоставления сообщений с правильным действием:
messages = {
'message with reply 1': True, # wait for reply
'message with reply 2': True,
'message with reply 2': True,
'message without reply 1': False, # don't wait for reply
'message without reply 2': False
}
Тогда это сделать:
def send_message(self, message, host):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((host, self.PORT))
s.send(bytes(message, 'ascii'))
if messages[message]:
data = s.recv(1024)
print(data)
Второй способ имеет чистую инициализацию (менее шаблонный код), но немного менее ясна. Для кого-то, не знакомого с кодом, неясно, что на самом деле означает значение, хранящееся в messages[message]
, а message.await_reply
- кристально чистое. Что-то вроде named tuples может быть хорошим компромиссом - вы можете инициализировать все в одной структуре данных, все еще используя явные поля для ясности.
может зависеть от вашей ОС, но, возможно, модуль 'select' будет работать на вас? – thebjorn