Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bidirectional communication - the async-client example needs some clarification #212

Open
lguminski opened this issue Mar 15, 2019 · 3 comments

Comments

@lguminski
Copy link

This is a question related to one of your examples that I originally asked at the rust forum. According to another user, my doubts are justified, so I am reposting my question here:

I am a beginner, very excited to learn how Rust combined the concept of futures with the concept of "green threads". But at the moment I am struggling to understand the example of async-client.rs from websockets-rs crate. I would appreciate some help.

In the example (code) there are 2 streams: one with user input (received via a mpsc channel from another thread and mapped into OwnedMessage), and the second with messages coming from the websocket server (also OwnedMessage).

But then there is a piece of code that confused me:

let (sink, stream) = duplex.split();
stream
    .filter_map(|message| {
        println!("Received Message: {:?}", message);
        match message {
            OwnedMessage::Close(e) => Some(OwnedMessage::Close(e)),
            OwnedMessage::Ping(d) => Some(OwnedMessage::Pong(d)),
            _ => None,
        }       
    })
    .select(stdin_ch.map_err(|_| WebSocketError::NoDataAvailable))
    .forward(sink)

My understanding of the code is that the 2 streams are combined (in a round-robin fashion) via select, and then every message (from the two streams) is forward'ed to sink (the websocket server). This understanding is obviously wrong, because this would mean that whenever the client receives a message from server, it bounces it back. I sniffed the wire and this is not what is happening.

My guess is that I simply cannot read properly the documentation of Stream, but here it is what is says (emphasis is mine):

[The select] combinator will attempt to pull items from both streams. Each stream will be polled in a round-robin fashion, and whenever a stream is ready to yield an item that item is yielded.
This future [produced by forward] will drive the stream to keep producing items until it is exhausted, sending each item to the sink.

Where do I make a mistake?

@vi
Copy link
Member

vi commented Mar 15, 2019

Do you want me to explain what happens in that example? I can try, but later.

My own Rust async programs (recent example) often also boil down to "some tricky combined stream is forwarded to a sink (which may also be tricky and combined)".

@lguminski
Copy link
Author

It was my fault. I misread the example. Now it is clear to me.

Thanks @vi for pointing me to your recent example. Studying it now.

Still the original async-client.rs example would probably benefit from having more comments. And the server as well (#170 )

@kpp
Copy link
Contributor

kpp commented Apr 30, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants