插座生 rust ,等待断开连接?

ws51t4hk  于 2023-02-23  发布在  其他
关注(0)|答案(1)|浏览(180)

我在尝试使用rust_socketio时遇到了一个问题,emit方法要么挂起了执行(有循环),要么是因为它是异步运行的,超过了emit调用,我从来没有得到回调(没有循环)。rust_socketio有一个标准的方法来等待某种信号吗?我在文档中没有看到任何演示,我在github上也找不到客户端的很多用法。
我想在循环中调用emit的阻塞行为,但我不知道如何让执行在它被调用后继续。我尝试从回调中调用socket.disconnect(),但它仍然挂起。
编辑:它实际上并不阻塞使用循环,我正在研究如何使它阻塞

fn main() {
    loop {
        // ... get some user input
        let socket = ClientBuilder::new("http://localhost:3000")
            .on("custom_event", response_handler)
            .on("error", |err, _| eprintln!("Error: {:#?}", err))
            .connect()
            .expect("Connection failed");
        let _result = socket.emit("custom_event", json!({ "query": input })).unwrap();
        // The callbacks are triggered happily, and the socket is disconnected, but...
        // execution hangs here and the print is never run
        println!("hello...?");
    }
}

https://docs.rs/rust_socketio/latest/rust_socketio/client/struct.Client.html#method.emit

5vf7fwbs

5vf7fwbs1#

找到了。它实际上没有挂起,回调的输出掩盖了它已经完成循环并返回到输入阶段的事实。我现在只需要找到如何等待连接。
我使用静态AtomicBool来保持main函数,直到回调以某种方式完成。

static IS_HANDLING_RESPONSES: AtomicBool = AtomicBool::new(false);

则在主循环中:

let _result = socket
            .emit("custom_event", json!({ "query": input }))
            .expect("Failed to emit");
        while IS_HANDLING_RESPONSES.load(Ordering::Relaxed) {
            // wait for the server to respond
        }

然后在回调中当我们到达完成状态时:

IS_HANDLING_RESPONSES.swap(false, Ordering::Relaxed);

我发现的另一个避免全局变量的选择是使用通道来与主函数通信,我创建了一个函数,它返回一个闭包,该闭包可以访问通道的发送器。

use std::sync::mpsc;
use std::sync::mpsc::Sender;

fn response_handler(is_done: Sender<bool>, payload: Payload, _socket: RawClient) {
// ... implementation
    // when it's time to wrap up use the channel
    _ = is_done.send(true);
// ...
}

fn make_response_handler(is_done: Sender<bool>) -> impl Fn(Payload, RawClient) {
    move |payload: Payload, socket: RawClient| {
        response_handler(is_done.clone(), payload, socket);
    }
}

然后在主循环中:

let (is_done, rx) = mpsc::channel();
    let handler = make_response_handler(is_done);
    // ... go get input
    let _result = socket
        .emit("custom_event", json!({ "query": input }))
        .expect("Failed to emit");
    // This blocks until the callback sends back a completion message
    let _is_done = rx.recv();

相关问题