作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经从smol
修改了一个websocket服务器example,以将字符串传递给监听功能。
我收到一个错误:
main.rs(79, 17): this return type evaluates to the `'static` lifetime...
main.rs(62, 8): ...can't outlive the lifetime `'_` as defined on the function body at 62:8
main.rs(62, 5): Error originated from macro here``
我相信这是因为它正在传递给异步函数。对于发生的事情是否有更好的解释,是否有解决方法?
Cargo.toml
[dependencies]
num_cpus = "1.13.0"
smol = "*"
anyhow = "*"
async-tungstenite = "*"
futures = "0.3.4"
tungstenite = "0.11.0"
async-native-tls = "0.3.3"
native-tls = "0.2.4"
main.rs
use std::net::{TcpListener, TcpStream};
use std::pin::Pin;
use std::task::{Context, Poll};
use std::thread;
use anyhow::{Context as _, Result};
use async_tungstenite::WebSocketStream;
use futures::prelude::*;
use smol::{Async, Task};
use tungstenite::Message;
/// Echoes messages from the client back to it.
async fn echo(mut stream: WsStream, s: &mut String) -> Result<()> {
let msg = stream.next().await.context("expected a message")??;
stream.send(Message::text(msg.to_string())).await?;
s.push_str(" world!");
Ok(())
}
/// Listens for incoming connections and serves them.
async fn listen(listener: Async<TcpListener>, s: &mut String) -> Result<()> {
let host = format!("ws://{}", listener.get_ref().local_addr()?);
println!("Listening on {}", host);
loop {
// Accept the next connection.
let (stream, _) = listener.accept().await?;
println!("Accepted client: {}", stream.get_ref().peer_addr()?);
let stream = WsStream::Plain(async_tungstenite::accept_async(stream).await?);
Task::spawn(echo(stream, s)).unwrap().detach();
}
}
fn main() -> Result<()> {
let mut s: String = String::from("Hello");
// Create an executor thread pool.
for _ in 0..num_cpus::get().max(1) {
thread::spawn(|| smol::run(future::pending::<()>()));
}
// Start WS and WSS servers.
smol::block_on(async {
let ws = listen(Async::<TcpListener>::bind("127.0.0.1:9000")?, &mut s);
ws.await?;
Ok(())
})
}
/// A WebSocket or WebSocket+TLS connection.
enum WsStream {
/// A plain WebSocket connection.
Plain(WebSocketStream<Async<TcpStream>>),
}
impl Sink<Message> for WsStream {
type Error = tungstenite::Error;
fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match &mut *self {
WsStream::Plain(s) => Pin::new(s).poll_ready(cx),
}
}
fn start_send(mut self: Pin<&mut Self>, item: Message) -> Result<(), Self::Error> {
match &mut *self {
WsStream::Plain(s) => Pin::new(s).start_send(item),
}
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match &mut *self {
WsStream::Plain(s) => Pin::new(s).poll_flush(cx),
}
}
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match &mut *self {
WsStream::Plain(s) => Pin::new(s).poll_close(cx),
}
}
}
impl Stream for WsStream {
type Item = tungstenite::Result<Message>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
match &mut *self {
WsStream::Plain(s) => Pin::new(s).poll_next(cx),
}
}
}
最佳答案
调用s时,借用s的生命周期必须与回声存储在其中的返回时间一样长。但是Task::spawn具有'static
生存期的 future ,因此比在循环结束时返回作用域的时间更长。您可能需要一个Arc<Mutex<String>>
才能完成此工作。
关于asynchronous - 如何将变量传递给异步函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62729952/
我是一名优秀的程序员,十分优秀!