Во-первых, я давно скрываюсь, но в первый раз я хочу поблагодарить вас всех за создание сайта!
Я нахожусь в ситуации, когда мне нужно реализовать клиентскую часть проприетарного протокола. Протокол использует TCP / IP внизу, и поток сообщений можно обобщить следующим образом:
- Клиент подключается к серверу
- Клиент проявляет интерес к данным определенного типа
- Если у сервера есть такие данные, они отправляются клиенту
- Клиент подтверждает прием на сервер
- Клиенту теперь нужно сообщить серверу, что он все еще интересуется данными того же типа
- Сервер отправляет данные клиенту по мере поступления
- Клиент должен время от времени отправлять на сервер запросы поддержки активности на уровне приложения (например, каждую минуту или около того)
- Некоторые сообщения с сервера требуют, чтобы клиент отправил ответ обратно на сервер
- Клиент отключается
Все это должно произойти в течение одного TCP-сеанса, который должен быть долгоживущим, вроде WebSocket, который я себе представляю.
Другое дело, что клиент должен быть развернут на многопоточном сервере и должен обеспечивать одновременный доступ из нескольких потоков, что означает, что один поток должен иметь возможность «подписаться» на сообщения определенного типа из сервер, а также должен иметь возможность отправлять сообщения на него.
Я хорошо осведомлен о GIL, поэтому я думаю, что это не имеет смысла комментировать это, я только пишу клиент, я не могу изменить какие-либо другие части архитектуры.
Так что дело в том, что мне никогда не приходилось копаться ниже уровня HTTP, мне посчастливилось всегда использовать некоторые уже существующие библиотеки, а с другой стороны, я не так много занимался сетевым программированием, что в первый раз я сам стану чем-то подобным.
Мне бы хотелось, чтобы у меня была возможность узнать больше обо всех асинхронных библиотеках / инструментах / инструментариях, таких как select, epoll, libev или gevent.
Проблема в том, что большинство ресурсов в сети имеют дело с серверами записи, и я даже не уверен, что развертывание клиента на многопоточном означает, что не все они будут делать много. Все серверы, очевидно, являются однопоточными, но не ясно, потому что не нужны несколько потоков или потому, что такие вещи, как epoll, на самом деле не любят, когда их используют несколько потоков.
Сервер явно обрабатывает все клиенты, как если бы они были однопоточными модулями, поэтому я думаю, что мне нужно будет сериализовать доступ к клиенту. Я не могу понять, как убедиться, что ответы сервера совпадают с потоками, и наоборот. Если один поток получает сообщение, но другой поток должен подтвердить сообщение, которое он получил до того, как предыдущий получит возможность подтвердить его, то как я могу быть уверен, что сообщения просто не перепутались?
Что вы думаете обо всем этом? Являются ли асинхронные библиотеки хорошим выбором в этом случае? Можете ли вы вспомнить примеры кода, на которые я мог бы взглянуть? Я использую Python, но я думаю, что вопрос достаточно общий, чтобы я мог использовать C, C ++ или Java для вдохновения.
Большое, большое спасибо!