使用多个本地 IP 创建到 tokio-tungstenite 中 websocket 的多个连接

问题描述 投票:0回答:1

我正在检索所有本地 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);
            }
        }
    }
}
rust websocket rust-tokio
1个回答
0
投票

为了能够确定您的本地地址,您必须手动创建

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
以访问所有不同的流。

© www.soinside.com 2019 - 2024. All rights reserved.