@@ -20,9 +20,121 @@ This crate provides stream multiplexing with channels.
2020Channels have their own backpressure that does not affect other channels.
2121
2222Incoming streams are by default set to channel 0 and can be moved to other channels via `ControlMessage`s.
23+
24+ ```rust
25+ use bytes::Bytes;
26+ use tokio::net::TcpListener;
27+ use tokio::io::{AsyncReadExt, AsyncWriteExt};
28+ use tokio::sync::mpsc;
29+ use stream_multiplexer::{Multiplexer, HalvesStream, ControlMessage, IncomingPacket, OutgoingPacket};
30+ use futures::stream::StreamExt;
31+
32+ # tokio::runtime::Builder::new().basic_scheduler().enable_all().build().unwrap().block_on(async move {
33+ // 3 channels of incoming streams, 0 is the channel that new streams join.
34+ // Backpressure is per channel. Streams can be moved between channels by
35+ // sending an OutgoingPackt::ChangeChannel message.
36+ let (channel0_tx, mut channel0_rx) = mpsc::channel(32);
37+ let (channel1_tx, mut channel1_rx) = mpsc::channel(32);
38+ let (channel2_tx, mut channel2_rx) = mpsc::channel(32);
39+
40+ // A Stream for outgoing messages.
41+ let (mut outgoing_tx, outgoing_rx) = mpsc::channel::<OutgoingPacket<Bytes>>(32);
42+
43+ // Construct the multiplexer, giving it the OutgoingPacket stream, and a vector of incoming
44+ // streams. The backlog controls how much of an internal buffer each WriteHalf (TcpSocket in this example) can have.
45+ let outgoing_streams_backlog = 128;
46+ let multiplexer = Multiplexer::new(
47+ outgoing_streams_backlog,
48+ outgoing_rx,
49+ vec![channel0_tx, channel1_tx, channel2_tx],
50+ );
51+
52+ // Bind to a random port on localhost
53+ let socket = TcpListener::bind("127.0.0.1:0").await.unwrap();
54+
55+ let local_addr = socket.local_addr().unwrap();
56+
57+ // Use the HalvesStream utility struct to map the stream of new sockets.
58+ // It will use LengthDelimitedCodec with 2 bytes as the packet size.
59+ let halves = HalvesStream::new(socket, 2);
60+
61+ // Control channel for shutting down the multiplexer
62+ let (control_write, control_read) = mpsc::unbounded_channel();
63+ let mp_joinhandle = tokio::task::spawn(multiplexer.run(halves, control_read));
64+
65+ // Make a test connection:
66+ let mut client = tokio::net::TcpStream::connect(local_addr).await.unwrap();
67+
68+ // Send 'a message'
69+ let mut data = Bytes::from("\x00\x09a message");
70+ client.write_buf(&mut data).await.unwrap();
71+ client.flush();
72+
73+ // Receive 'a message' on channel 0
74+ let incoming_packet = channel0_rx.recv().await.unwrap();
75+ assert_eq!(
76+ incoming_packet
77+ .value()
78+ .expect("should have a value")
79+ .as_ref()
80+ .unwrap(),
81+ &Bytes::from("a message")
82+ );
83+
84+ // Move the client to channel 1
85+ outgoing_tx
86+ .send(OutgoingPacket::ChangeChannel(vec![incoming_packet.id()], 1))
87+ .await
88+ .unwrap();
89+
90+ // Send 'a message' again, on channel 1 this time.
91+ let mut data = Bytes::from("\x00\x09a message");
92+ client.write_buf(&mut data).await.unwrap();
93+ client.flush();
94+
95+ // Receive 'a message' on channel 1
96+ let incoming_packet = channel1_rx.recv().await.unwrap();
97+ assert_eq!(
98+ incoming_packet
99+ .value()
100+ .expect("should have a value")
101+ .as_ref()
102+ .unwrap(),
103+ &Bytes::from("a message")
104+ );
105+
106+ // Move the client to channel 2
107+ outgoing_tx
108+ .send(OutgoingPacket::ChangeChannel(vec![incoming_packet.id()], 2))
109+ .await
110+ .unwrap();
111+
112+ // Send 'a message' again, on channel 2 this time.
113+ let mut data = Bytes::from("\x00\x09a message");
114+ client.write_buf(&mut data).await.unwrap();
115+ client.flush();
116+
117+ // Receive 'a message' on channel 2
118+ let incoming_packet = channel2_rx.recv().await.unwrap();
119+ assert_eq!(
120+ incoming_packet
121+ .value()
122+ .expect("should have a value")
123+ .as_ref()
124+ .unwrap(),
125+ &Bytes::from("a message")
126+ );
127+
128+ // Tell multiplexer te shut down
129+ control_write.send(ControlMessage::Shutdown).unwrap();
130+
131+ mp_joinhandle.await.unwrap();
132+ # });
133+ ```
23134*/
24135mod error;
25136mod halt;
137+ mod halves_stream;
26138mod id_gen;
27139mod multiplexer;
28140mod multiplexer_senders;
@@ -32,6 +144,7 @@ mod stream_mover;
32144
33145pub use error:: * ;
34146use halt:: * ;
147+ pub use halves_stream:: * ;
35148pub use id_gen:: * ;
36149pub use multiplexer:: * ;
37150use multiplexer_senders:: * ;
@@ -45,6 +158,7 @@ type StreamId = usize;
45158pub struct IncomingMessage < V > {
46159 /// Stream Id that the message if for
47160 pub id : StreamId ,
161+
48162 /// Value received from a stream
49163 pub value : V ,
50164}
0 commit comments