Нужно ли мне уходить от Tokio, поскольку я не могу разделить потоки в соединениях TLS? - PullRequest
0 голосов
/ 07 апреля 2020

Я использую Tokio для создания простых сокетов TCP, вызываю tokio::io::split(), и половинки чтения / записи передаются в отдельные потоки. Они используют asyn c API чтения / записи для сокетов с await для выполнения sh ввода-вывода. Наш поток данных достаточно изолирован в направлениях ввода / вывода, поэтому в нашем случае эта модель хорошо работает. Все идет нормально.

Теперь я смотрю на добавление поддержки TLS сверху. Некоторые библиотеки TLS не позволяют разделять поток по разным причинам:

  • tokio-rustls (реализовано с rustls) позволяет разделять, но это относительно новый

  • Я бы предпочел использовать tokio-openssl (реализованный с openssl), который существует намного дольше, но openssl не поддерживает его . Вероятно, это связано с тем, что такие события, как пересогласование TLS, необходимо распространять на половинки для чтения / записи (рустами управляет это, потому что это собственная реализация Rust).

Таким образом, тот же поток должен выполнить чтения / записи. Это означает, что сокет должен теперь стать неблокирующим: не может ждать поступления данных, поскольку данные могут потребоваться немедленно (и наоборот).

Если я правильно понимаю, Парадигма Tokio / await не имеет смысла с неблокирующими сокетами. Правильно ли мое понимание?

Любые другие идеи в этом сценарии также приветствуются. Я надеюсь, что нам не нужно отказываться от Токио после всех усилий, приложенных до сих пор.

1 Ответ

2 голосов
/ 08 апреля 2020

Это правда, что библиотеки TLS с включенной асинхронной / ожидающей поддержкой, такие как tokio-tls, требуют, чтобы указанный поток не был разделен, однако после того, как вы завернули свой поток в слой TLS, вы можете разделить что обернутый поток с использованием tokio::io::split.

Использование потоков таким образом правильно обрабатывает все детали, касающиеся блокирующего и неблокирующего ввода-вывода. Вам не нужно вручную настраивать флаги, такие как O_NONBLOCK, поскольку TcpStream и 1016 *TlsStream Токио обрабатывают эти детали для вас за кулисами.

Использование библиотеки, которая предоставляет блокирующие сокеты, естественно, было бы несовместимо с Tokio. Это не ново и по тем же причинам, по которым вы не можете использовать std::net::TcpStream в Tokio, так как это блокирующий поток. Tokio предоставляет альтернативные типы потоков для этих целей, чтобы избежать этих проблем.

Если вы хотите использовать ssl-ящик, не поддерживающий асинхронность / ожидание, вы можете выполнить шифрование в буферах в памяти и вручную записать зашифрованные данные с использованием Токио TcpStream. Все ssl-библиотеки с поддержкой async / await функционируют таким образом.

...