Rust 无法使用struct';tokio::spawn函数中的s成员变量

Rust 无法使用struct';tokio::spawn函数中的s成员变量,rust,grpc,rust-tokio,rust-tonic,Rust,Grpc,Rust Tokio,Rust Tonic,我实现了一个gRPC服务器,它将数据流传输到它的客户机。我希望服务器开始通过“通道通知”发回另一个模块事件的数据 为了说明要点,我将实现简化为“hello”服务器。gRPC原型文件为: syntax = "proto3"; package hello; service Greeter { rpc SayHello (HelloRequest) returns (stream HelloReply) {} } message HelloRequest {

我实现了一个gRPC服务器,它将数据流传输到它的客户机。我希望服务器开始通过“通道通知”发回另一个模块事件的数据

为了说明要点,我将实现简化为“hello”服务器。gRPC原型文件为:

syntax = "proto3";

package hello;

service Greeter {
    rpc SayHello (HelloRequest) returns (stream HelloReply) {}
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}
而且
rs
文件很简单:

pub mod hello_world {
    tonic::include_proto!("hello");
}

// This is my server's implementation.
pub struct MyGreeter {
    // The new data is sent over to gRPC server via this mpsc::Receiver channel.
    notifer: mpsc::Receiver<i32>,
}


#[tonic::async_trait]
impl Greeter for MyGreeter {

    type SayHelloStream = ReceiverStream<Result<HelloReply, Status>>;

    async fn say_hello(
        &self,
        request: Request<HelloRequest>,
    ) -> Result<Response<Self::SayHelloStream>, Status> {
        println!("Got a request from {:?}", request.remote_addr());

        // compiling error here: this data with lifetime `'life0`...
        let (api_tx, api_rx) = mpsc::channel(3);

        tokio::spawn(async move {

            // compiling error here: ...and is required to live as long as `'static` here
            self.notifer.recv().await.unwrap();

            api_tx.send(Ok(HelloReply {
                message: format!("Hello {}!", request.into_inner().name),
            })).await.unwrap();
        });

        Ok(Response::new(ReceiverStream::new(api_rx)))
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let addr = "[::1]:50051".parse().unwrap();

    // Create a pair of channel endpoint
    // tx is used somewhere for sending new data.
    let (tx, rx) = mpsc::channel(3);

    let greeter = MyGreeter {
        // the receiver endpoint
        notifer: rx,
    };

    println!("GreeterServer listening on {}", addr);

    Server::builder()
        .add_service(GreeterServer::new(greeter))
        .serve(addr)
        .await?;

    Ok(())
}
pub mod hello\u world{
主音:包括原音(“你好”);
}
//这是我的服务器的实现。
发布结构MyGreeter{
//新数据通过此mpsc::Receiver通道发送到gRPC服务器。
通知人:mpsc::接收人,
}
#[主音::异步\u特征]
我的迎宾员的impl迎宾员{
类型SayHelloStream=接收流;
异步fn打招呼(
&自我,
请求:请求,
)->结果{
println!(“从{:?}获得请求”,request.remote_addr());
//此处编译错误:此数据的生存期为“life0”。。。
let(api_-tx,api_-rx)=mpsc::信道(3);
东京:产卵(异步移动){
//此处编译错误:…并且需要与此处的“static”一样长时间存在
self.notifer.recv().wait.unwrap();
api_发送(正常(HelloReply{
消息:format!(“Hello{}!”,request.into_inner().name),
})).等待;
});
正常(响应::新(接收流::新(api_rx)))
}
}
#[tokio::main]
异步fn main()->结果{
let addr=“[::1]:50051.parse().unwrap();
//创建一对通道端点
//tx用于发送新数据。
let(tx,rx)=mpsc::信道(3);
让迎宾员=我的迎宾员{
//接收端
notifer:rx,
};
println!(“{}上侦听的GreeterServer”,addr);
服务器::生成器()
.add_服务(GreeterServer::new(greeter))
.发球(地址)
.等待?;
好(())
}
我在main中创建了一对通道端点,然后在gRPC服务器中将接收方端点用作notifier。发送端点被分配给另一个模块,该模块在发送新生成数据的代码中被省略


我知道这个错误一定与锈菌的所有权有关。我尝试将通道端点包装在
弧中
,并由
互斥锁保护。但是,它不起作用。

我认为问题在于您的通知程序是mpsc,这意味着多个生产者和单个消费者。您的代码可能会产生多个此类任务,因此您需要多个使用者,即接收端为
Clone
的MPMC通道。例如,参见提供可克隆接收器的。然后您可以编写
let notifier=self.notifier.clone()在闭包外,只需在闭包内使用
通知程序