【发布时间】:2020-04-18 09:21:07
【问题描述】:
前言,可以跳到下一节
所以我决定在我的新的相对较小的项目中尝试使用 Rust,因为我喜欢它生成一个单一的可执行文件,该可执行文件很容易在我的基于 ARM 的目标上部署,并且在 RAM 和磁盘空间方面的资源相对较少。我以前没有使用 Rust 的经验,但有很多其他语言的经验,到目前为止我有点失望。似乎对于许多 Rust 库,可能还有 Rust 本身,API 变化如此之快,以至于网上找到的 90% 的示例代码都无法使用最新版本的库(如 tokio、tokio-util 等)进行编译。此外,文档通常误导。例如,如果您在 Google 搜索 LinesCodec,它将显示在 tokio_io::codec::LinesCodec、tokio::codec::LinesCodec、tokio_codec::LinesCodec 和 tokio_util::codec::LinesCodec,这最终似乎是今天可以使用的一个。 FramedRead 等其他事物也有同样的困惑,它在某些版本中具有 and_then 和 map 成员函数,但它们似乎在最新版本中不存在。最后,在 SO 上与 Rust 相关的问题和答案的数量远远少于我使用过的其他语言,这使得开始使用 Rust 变得更加困难。我过去 2 天尝试做的事情在大多数编程语言中都相对容易解决,我相信在 Rust 中也一定有一个简单的解决方案,但到目前为止我还没有成功。
问题本身
我需要将 TCP 客户端连接到远程服务器,并在数据传入时无限期地逐行读取和处理。这需要异步完成,因为同一个进程也充当 HTTP 服务器,所以我使用的是tokio。
据我了解,比较常见的方法是使用 TcpStream,将其分割到 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);
}
});
【问题讨论】:
标签: rust rust-tokio