我正在检索所有本地 IP 地址,并且我想从每个 IP 地址创建 Websocket 连接。
如何循环遍历所有
ips
并创建多个 stream
?
use std::net::{IpAddr, Ipv4Addr};
use tokio;
use tokio_tungstenite::connect_async;
#[tokio::main]
async fn main() {
let ips: Vec<IpAddr> = vec![
IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)),
IpAddr::V4(Ipv4Addr::new(2, 2, 2, 2))
];
// How do I cycle through all `ips` and create multiple `stream`s?
let (mut stream, _) = connect_async("wss://echo.websocket.org").await.unwrap();
loop {
tokio::select! {
Some(msg) = stream.next() => {
println!("{}", msg);
}
}
}
}
为了能够确定您的本地地址,您必须手动创建
TcpStream
并切换到 client_async
而不是 connect_async
:
use futures::{stream::SelectAll, StreamExt};
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use tokio::net::{lookup_host, TcpSocket};
use tokio_tungstenite::client_async;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// we set the ports here to 0 so the OS can pick one for us
let ips: Vec<SocketAddr> = vec![
SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(1, 1, 1, 1), 0)),
SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(2, 2, 2, 2), 0)),
];
let mut streams = SelectAll::new();
// get the first remote address you might want to try them one after the other or maybe `zip` them with the ones from `ips`, …
let target = lookup_host("echo.websocket.org:443")
.await?
.next()
.ok_or("no IP for \"echo.websocket.org:443\"")?;
for ip in ips {
let socket = TcpSocket::new_v4()?;
socket.bind(ip)?;
let tcp_stream = socket.connect(target).await?;
let (ws_stream, _) = client_async("wss://echo.websocket.org", tcp_stream)
.await?;
streams.push(ws_stream);
}
loop {
tokio::select! {
Some(msg) = streams.next() => {
println!("{:?}", msg);
}
}
}
}
我使用
SelectAll
将所有流合并为一个,您可能需要将其替换为 Vec
以访问所有不同的流。