Предисловие, вы можете перейти к следующему разделу
Поэтому я решил попробовать Rust для моего нового относительно небольшого проекта, потому что мне нравится, что он создает один исполняемый файл, который легко развернуть на моей цели на основе ARM с относительно небольшими ресурсами с точки зрения оперативной памяти и дискового пространства. У меня нет предыдущего опыта работы с Rust, но большой опыт работы с другими языками, и до сих пор я немного разочарован. Похоже, что для многих библиотек Rust и, возможно, для самого Rust API-интерфейсы меняются так быстро, что 90% образца кода, найденного в сети, не будут компилироваться с последними версиями библиотек, такими как tokio
, tokio-util
et c. Кроме того, документация часто вводит в заблуждение. Например, если вы Google для LinesCodec
, он будет отображаться в tokio_io::codec::LinesCodec
, tokio::codec::LinesCodec
, tokio_codec::LinesCodec
и tokio_util::codec::LinesCodec
, который в конечном итоге, похоже, будет использоваться на сегодняшний день. То же самое происходит с другими вещами, такими как FramedRead
, в некоторых из которых были функции-члены and_then
и map
, но в последней версии их, похоже, не существует. Наконец, количество вопросов и ответов, связанных с Rust на SO, намного меньше, чем для других языков, которые я использовал, что затрудняет начало использования Rust. То, что я пытаюсь сделать в течение последних двух дней, относительно легко решается на большинстве языков программирования, и я считаю, что и в Rust должно быть простое решение, но пока я не добился успеха.
Сам вопрос
Мне нужно подключить TCP-клиент к удаленному серверу и бесконечно читать и обрабатывать данные построчно, как указано в . Это нужно делать асинхронно, потому что тот же процесс также действует как HTTP-сервер, поэтому я использую tokio
.
Насколько я понимаю, довольно распространенным способом является использование TcpStream
, slit это к частям RX / TX, затем я пытаюсь подключить LinesCodec
(с FramedRead
), но я не могу соединить все это вместе без ошибок компиляции.
[dependencies]
futures = "*"
hyper = "*"
tokio = { version = "*", features = ["full"] }
tokio-util = "0.2.0"
tokio-modbus = { version = "*", features = ["tcp", "server", "tcp-server-unstable"], git = "https://github.com/slowtec/tokio-modbus" }
let stream = TcpStream::connect("172.16.100.10:1001").await.unwrap();
let transport = FramedRead::new(stream, LinesCodec::new()); // need to split?
/* ... what to do next to process incoming data line-by-line ...? */
Пока что я пришел с этим решением, хотя не уверен, насколько оно хорошо
tokio::spawn(async {
let connection = TcpStream::connect("172.16.100.10:1001").await.unwrap();
let mut reader = BufReader::new(connection);
loop {
let mut line = String::new();
reader.read_line(&mut line).await.unwrap();
println!("{}", line);
}
});