websockets-rs / websockets-rs/rust-websocket

Bidirectional communication - the async-client example needs some clarification

Open
#212 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
1.6k
Forks
225
PR merge metrics
No merged PRs in 30d

Description

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?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with examples/async-client.rs and the futures 0.1 Stream documentation referenced in the issue. Trace how filter_map, select, and forward interact, then clarify the example or its surrounding documentation so the message flow is unambiguous. Done means a newcomer can understand which messages are sent to the WebSocket sink and which are only handled locally.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
documentation
Issue type
Documentation
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.