Rust 如何同时运行包含借用TcpStream的期货?

Rust 如何同时运行包含借用TcpStream的期货?,rust,async-await,future,asyncsocket,Rust,Async Await,Future,Asyncsocket,我试图使这个代码段并发运行,而不是按顺序运行,因为对等点的数量可能是一个很大的值。我使用的是async_std 1.4和rust1.41 pub结构对等{ pub peer_id:String, 发布tcp_流:Arc, 发布公钥:[u8;32], } 异步fn将\u发送到\u所有\u对等方(消息:协议,对等方:&HashMap)->结果{ 对于对等中的对等。值(){ 让mut stream=&*peer.tcp_stream; stream.write_all(&bincode::序列化(&m

我试图使这个代码段并发运行,而不是按顺序运行,因为对等点的数量可能是一个很大的值。我使用的是
async_std 1.4
和rust
1.41

pub结构对等{
pub peer_id:String,
发布tcp_流:Arc,
发布公钥:[u8;32],
}
异步fn将\u发送到\u所有\u对等方(消息:协议,对等方:&HashMap)->结果{
对于对等中的对等。值(){
让mut stream=&*peer.tcp_stream;
stream.write_all(&bincode::序列化(&message)?)。wait?;
}
好(())
}
由于在
async\u std::task::spawn
中包装我创建并使用的未来需要一个静态生存期,因此我尝试使用
futures::future::future::join\u all
方法时没有任何运气。以下是我尝试过的:

async fn向所有对等方发送(消息:协议、对等方:&HashMap){
让handles=peers.values().进入|iter().map(| peer |{
任务::繁殖(
异步的{
让mut stream=&*peer.tcp_stream;
如果let Err(Err)=流
.write_all(&bincode::序列化(&message).unwrap())
.等待
{
错误!(“写入tcp_流时出错:{}”,错误);
}
}
)
});
期货::期货::加入所有(句柄)。等待;
}

我确信我缺少了一些方法,谢谢你的帮助

你试过类似的东西吗

let handles = peers.values().into_iter().map(|peer| {
   let mut stream = &*peer.tcp_stream;
   stream.write_all(&bincode::serialize(&message).unwrap())
}
let results = futures::future::join_all(handles).await
?


请注意.map闭包是如何不等待的,而是直接返回一个未来,然后传递给join_all,然后等待

由于您试图同时发送消息,因此每个任务都必须有自己的消息副本:

use async_std::{task, net::TcpStream};
use futures::{future, io::AsyncWriteExt};
use serde::Serialize;
use std::{
    collections::HashMap,
    error::Error,
    sync::Arc,
};

pub struct Peer {
    pub peer_id: String,
    pub tcp_stream: Arc<TcpStream>,
    pub public_key: [u8; 32],
}

#[derive(Serialize)]
struct Protocol;

async fn send_to_all_peers(
    message: Protocol,
    peers: &HashMap<String, Peer>)
    -> Result<(), Box<dyn Error>>
{
    let msg = bincode::serialize(&message)?;
    let handles = peers.values()
        .map(|peer| {
            let msg = msg.clone();
            let socket = peer.tcp_stream.clone();
            task::spawn(async move {
                let mut socket = &*socket;
                socket.write_all(&msg).await
            })
        });

    future::try_join_all(handles).await?;
    Ok(())
}
使用async_std:{task,net::TcpStream};
使用未来:{future,io::asyncWriteText};
使用serde::序列化;
使用std::{
集合::HashMap,
错误::错误,
sync::Arc,
};
发布结构对等{
pub peer_id:String,
发布tcp_流:Arc,
发布公钥:[u8;32],
}
#[导出(序列化)]
结构协议;
异步fn向所有\u对等方发送\u(
信息:协议,
对等点:&哈希映射)
->结果
{
让msg=bincode::序列化(&message)?;
让handles=peers.values()
.map(| peer |{
让msg=msg.clone();
让socket=peer.tcp_stream.clone();
任务::生成(异步移动){
让mut socket=&*socket;
socket.write_all(&msg)。等待
})
});
未来::尝试加入所有(句柄)。等待?;
好(())
}

我在另一个生命周期问题上尝试了这一点,这是错误的基本jist:
rust stream.write\u all(message)返回一个引用当前函数拥有的数据的值
谢谢!这就解决了问题。我希望我能绕过克隆
Arc
,但我想这是不可能安全完成的。