pub struct Connect<'transport, TransportSinkError, TransportStreamError>(/* private fields */);
rch
only.Expand description
Methods for establishing a connection over a physical transport.
You must poll the returned Connect future or spawn it onto a task for the connection to work.
§Physical transport
All functionality in Remoc requires that a connection over a physical transport is established. The underlying transport can either be of packet type (implementing Sink and Stream) or a socket-like object (implementing AsyncRead and AsyncWrite). In both cases it must be ordered and reliable. That means that all packets must arrive in the order they have been sent and no packets must be lost. The maximum packet size can be limited, see the configuration for that.
TCP is an example of an underlying transport that is suitable. But there are many more candidates, for example, UNIX domain sockets, pipes between processes, serial links, Bluetooth L2CAP streams, etc.
The connect functions are used to establish a base channel connection over a physical transport. Then, additional channels can be opened by sending either the sender or receiver half of them over the established base channel or another connected channel. See the examples in the remote channel module for details.
§Convenience functions
Methods from the ConnectExt trait can be used on the return values of all connect methods. They streamline connection handling when a single value, such as a RTC client, should be exchanged over the connection and the flexibility of a base channel is not necessary.
§Example
In the following example the server listens on TCP port 9875 and the client connects to it.
Then both ends establish a Remoc connection using Connect::io over the TCP connection.
The connection dispatchers are spawned onto new tasks and the client
and server
functions
are called with the established base channel.
use std::net::Ipv4Addr;
use tokio::net::{TcpStream, TcpListener};
use remoc::prelude::*;
#[tokio::main]
async fn main() {
// For demonstration we run both client and server in
// the same process. In real life connect_client() and
// connect_server() would run on different machines.
futures::join!(connect_client(), connect_server());
}
// This would be run on the client.
async fn connect_client() {
// Wait for server to be ready.
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
// Establish TCP connection.
let socket = TcpStream::connect((Ipv4Addr::LOCALHOST, 9875)).await.unwrap();
let (socket_rx, socket_tx) = socket.into_split();
// Establish Remoc connection over TCP.
let (conn, tx, rx) =
remoc::Connect::io(remoc::Cfg::default(), socket_rx, socket_tx).await.unwrap();
tokio::spawn(conn);
// Run client.
client(tx, rx).await;
}
// This would be run on the server.
async fn connect_server() {
// Listen for incoming TCP connection.
let listener = TcpListener::bind((Ipv4Addr::LOCALHOST, 9875)).await.unwrap();
let (socket, _) = listener.accept().await.unwrap();
let (socket_rx, socket_tx) = socket.into_split();
// Establish Remoc connection over TCP.
let (conn, tx, rx) =
remoc::Connect::io(remoc::Cfg::default(), socket_rx, socket_tx).await.unwrap();
tokio::spawn(conn);
// Run server.
server(tx, rx).await;
}
// This would be run on the client.
async fn client(mut tx: rch::base::Sender<u16>, mut rx: rch::base::Receiver<String>) {
tx.send(1).await.unwrap();
assert_eq!(rx.recv().await.unwrap(), Some("1".to_string()));
}
// This would be run on the server.
async fn server(mut tx: rch::base::Sender<String>, mut rx: rch::base::Receiver<u16>) {
while let Some(number) = rx.recv().await.unwrap() {
tx.send(number.to_string()).await.unwrap();
}
}
Implementations§
source§impl<'transport, TransportSinkError, TransportStreamError> Connect<'transport, TransportSinkError, TransportStreamError>
impl<'transport, TransportSinkError, TransportStreamError> Connect<'transport, TransportSinkError, TransportStreamError>
sourcepub async fn framed<TransportSink, TransportStream, Tx, Rx, Codec>(
cfg: Cfg,
transport_sink: TransportSink,
transport_stream: TransportStream,
) -> Result<(Connect<'transport, TransportSinkError, TransportStreamError>, Sender<Tx, Codec>, Receiver<Rx, Codec>), ConnectError<TransportSinkError, TransportStreamError>>where
TransportSink: Sink<Bytes, Error = TransportSinkError> + Send + Sync + Unpin + 'transport,
TransportSinkError: Error + Send + Sync + 'static,
TransportStream: Stream<Item = Result<Bytes, TransportStreamError>> + Send + Sync + Unpin + 'transport,
TransportStreamError: Error + Send + Sync + 'static,
Tx: RemoteSend,
Rx: RemoteSend,
Codec: Codec,
pub async fn framed<TransportSink, TransportStream, Tx, Rx, Codec>(
cfg: Cfg,
transport_sink: TransportSink,
transport_stream: TransportStream,
) -> Result<(Connect<'transport, TransportSinkError, TransportStreamError>, Sender<Tx, Codec>, Receiver<Rx, Codec>), ConnectError<TransportSinkError, TransportStreamError>>where
TransportSink: Sink<Bytes, Error = TransportSinkError> + Send + Sync + Unpin + 'transport,
TransportSinkError: Error + Send + Sync + 'static,
TransportStream: Stream<Item = Result<Bytes, TransportStreamError>> + Send + Sync + Unpin + 'transport,
TransportStreamError: Error + Send + Sync + 'static,
Tx: RemoteSend,
Rx: RemoteSend,
Codec: Codec,
Establishes a connection over a framed transport (a sink and a stream of binary data) and returns a remote sender and receiver.
This establishes a chmux connection over the transport and opens a remote channel.
You must poll the returned Connect future or spawn it for the connection to work.
§Panics
Panics if the chmux configuration is invalid.
source§impl<'transport> Connect<'transport, Error, Error>
impl<'transport> Connect<'transport, Error, Error>
sourcepub async fn io<Read, Write, Tx, Rx, Codec>(
cfg: Cfg,
input: Read,
output: Write,
) -> Result<(Connect<'transport, Error, Error>, Sender<Tx, Codec>, Receiver<Rx, Codec>), ConnectError<Error, Error>>where
Read: AsyncRead + Send + Sync + Unpin + 'transport,
Write: AsyncWrite + Send + Sync + Unpin + 'transport,
Tx: RemoteSend,
Rx: RemoteSend,
Codec: Codec,
pub async fn io<Read, Write, Tx, Rx, Codec>(
cfg: Cfg,
input: Read,
output: Write,
) -> Result<(Connect<'transport, Error, Error>, Sender<Tx, Codec>, Receiver<Rx, Codec>), ConnectError<Error, Error>>where
Read: AsyncRead + Send + Sync + Unpin + 'transport,
Write: AsyncWrite + Send + Sync + Unpin + 'transport,
Tx: RemoteSend,
Rx: RemoteSend,
Codec: Codec,
Establishes a connection over an IO transport (an AsyncRead and AsyncWrite) and returns a remote sender and receiver.
A chmux connection is established over the transport and a remote channel is opened. This prepends a length header to each chmux packet for transportation over the unframed connection.
This method performs no buffering of read and writes and thus may exhibit suboptimal performance if the underlying reader and writer are unbuffered. In this case use io_buffered instead.
You must poll the returned Connect future or spawn it for the connection to work.
§Panics
Panics if the chmux configuration is invalid.
sourcepub async fn io_buffered<Read, Write, Tx, Rx, Codec>(
cfg: Cfg,
input: Read,
output: Write,
buffer: usize,
) -> Result<(Connect<'transport, Error, Error>, Sender<Tx, Codec>, Receiver<Rx, Codec>), ConnectError<Error, Error>>where
Read: AsyncRead + Send + Sync + Unpin + 'transport,
Write: AsyncWrite + Send + Sync + Unpin + 'transport,
Tx: RemoteSend,
Rx: RemoteSend,
Codec: Codec,
pub async fn io_buffered<Read, Write, Tx, Rx, Codec>(
cfg: Cfg,
input: Read,
output: Write,
buffer: usize,
) -> Result<(Connect<'transport, Error, Error>, Sender<Tx, Codec>, Receiver<Rx, Codec>), ConnectError<Error, Error>>where
Read: AsyncRead + Send + Sync + Unpin + 'transport,
Write: AsyncWrite + Send + Sync + Unpin + 'transport,
Tx: RemoteSend,
Rx: RemoteSend,
Codec: Codec,
Establishes a buffered connection over an IO transport (an AsyncRead and AsyncWrite) and returns a remote sender and receiver.
A chmux connection is established over the transport and a remote channel is opened. This prepends a length header to each chmux packet for transportation over the unframed connection.
This method performs internal buffering of reads and writes.
You must poll the returned Connect future or spawn it for the connection to work.
§Panics
Panics if the chmux configuration is invalid.
Trait Implementations§
Auto Trait Implementations§
impl<'transport, TransportSinkError, TransportStreamError> Freeze for Connect<'transport, TransportSinkError, TransportStreamError>
impl<'transport, TransportSinkError, TransportStreamError> !RefUnwindSafe for Connect<'transport, TransportSinkError, TransportStreamError>
impl<'transport, TransportSinkError, TransportStreamError> Send for Connect<'transport, TransportSinkError, TransportStreamError>
impl<'transport, TransportSinkError, TransportStreamError> !Sync for Connect<'transport, TransportSinkError, TransportStreamError>
impl<'transport, TransportSinkError, TransportStreamError> Unpin for Connect<'transport, TransportSinkError, TransportStreamError>
impl<'transport, TransportSinkError, TransportStreamError> !UnwindSafe for Connect<'transport, TransportSinkError, TransportStreamError>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> FutureExt for T
impl<T> FutureExt for T
source§fn map<U, F>(self, f: F) -> Map<Self, F>
fn map<U, F>(self, f: F) -> Map<Self, F>
source§fn map_into<U>(self) -> MapInto<Self, U>
fn map_into<U>(self) -> MapInto<Self, U>
source§fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
f
. Read moresource§fn left_future<B>(self) -> Either<Self, B>
fn left_future<B>(self) -> Either<Self, B>
source§fn right_future<A>(self) -> Either<A, Self>
fn right_future<A>(self) -> Either<A, Self>
source§fn into_stream(self) -> IntoStream<Self>where
Self: Sized,
fn into_stream(self) -> IntoStream<Self>where
Self: Sized,
source§fn flatten(self) -> Flatten<Self>
fn flatten(self) -> Flatten<Self>
source§fn flatten_stream(self) -> FlattenStream<Self>
fn flatten_stream(self) -> FlattenStream<Self>
source§fn fuse(self) -> Fuse<Self>where
Self: Sized,
fn fuse(self) -> Fuse<Self>where
Self: Sized,
poll
will never again be called once it has
completed. This method can be used to turn any Future
into a
FusedFuture
. Read moresource§fn inspect<F>(self, f: F) -> Inspect<Self, F>
fn inspect<F>(self, f: F) -> Inspect<Self, F>
source§fn catch_unwind(self) -> CatchUnwind<Self>where
Self: Sized + UnwindSafe,
fn catch_unwind(self) -> CatchUnwind<Self>where
Self: Sized + UnwindSafe,
source§fn remote_handle(self) -> (Remote<Self>, RemoteHandle<Self::Output>)where
Self: Sized,
fn remote_handle(self) -> (Remote<Self>, RemoteHandle<Self::Output>)where
Self: Sized,
()
on completion and sends
its output to another future on a separate task. Read moresource§fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
source§fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>where
Self: Sized + 'a,
fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>where
Self: Sized + 'a,
source§fn unit_error(self) -> UnitError<Self>where
Self: Sized,
fn unit_error(self) -> UnitError<Self>where
Self: Sized,
Future<Output = T>
into a
TryFuture<Ok = T, Error = ()
>.source§fn never_error(self) -> NeverError<Self>where
Self: Sized,
fn never_error(self) -> NeverError<Self>where
Self: Sized,
Future<Output = T>
into a
TryFuture<Ok = T, Error = Never
>.