futures::sync::mpsc::Sender::send
потребляет Sender
и создает объект Send
, который является будущим, который необходимо запустить до завершения, чтобы фактически отправить данные. Если канал заполнен, он будет блокироваться, пока кто-то еще не получит от канала. По завершении он возвращает вам Sender
, который вы могли бы использовать для отправки дополнительных данных.
В этом случае я не думаю, что вы можете структурировать код только с одним экземпляром Sender
. Вам необходимо его клонировать, чтобы при каждом вызове сервисной функции создавался новый клон. Обратите внимание, что теперь оба закрытия move
:
let http_server = Server::bind(&([127, 0, 0, 1], 3000).into()).serve(move || {
// This closure has one instance of tx_queue that was moved-in here.
// Now we make a copy to be moved into the closure below.
let tx_queue = tx_queue.clone();
service_fn_ok(move |_: Request<Body>| {
// This closure has one instance of tx_queue, but it will be called
// multiple times, so it can not consume it. It must make a copy
// before consuming it.
tx_queue.clone().send(111);
Response::new(Body::from("Hello World!"))
})
});
Но это даст вам следующее предупреждение:
warning: unused `futures::sink::send::Send` that must be used
Как я уже сказал, send
просто дает вам будущее, которое необходимо запустить, чтобы фактически выполнить отправку. Если вы проигнорируете возвращаемое значение, ничего не произойдет. В этом случае было бы лучше, если бы spawn
было выполнено как отдельная задача (чтобы он не блокировал ответ клиенту). Чтобы вызвать его, вам нужен исполнитель из среды выполнения, который также должен быть клонирован для внутреннего закрытия:
let executor = runtime.executor();
let http_server = Server::bind(&([127, 0, 0, 1], 3000).into()).serve(move || {
let tx_queue = tx_queue.clone();
let executor = executor.clone();
service_fn_ok(move |_: Request<Body>| {
executor.spawn(tx_queue.clone().send(111).map(|_| ()).map_err(|err| {
// TODO: Handle the error differenty!
panic!("Error in mpsc {:?}", err);
}));
Response::new(Body::from("Hello World!"))
})
});