Enum interprocess::local_socket::tokio::Listener
source · pub enum Listener {
UdSocket(Listener),
}
Available on crate feature
tokio
only.Expand description
Tokio-based local socket server, listening for connections.
This struct is created by ListenerOptions
.
Name reclamation is performed by default on backends that necessitate it.
§Examples
§Basic server
use interprocess::local_socket::{
tokio::{prelude::*, Stream},
GenericNamespaced, ListenerOptions,
};
use std::io;
use tokio::{
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
try_join,
};
// Describe the things we do when we've got a connection ready.
async fn handle_conn(conn: Stream) -> io::Result<()> {
let mut recver = BufReader::new(&conn);
let mut sender = &conn;
// Allocate a sizeable buffer for receiving. This size should be big enough and easy to
// find for the allocator.
let mut buffer = String::with_capacity(128);
// Describe the send operation as sending our whole message.
let send = sender.write_all(b"Hello from server!\n");
// Describe the receive operation as receiving a line into our big buffer.
let recv = recver.read_line(&mut buffer);
// Run both operations concurrently.
try_join!(recv, send)?;
// Produce our output!
println!("Client answered: {}", buffer.trim());
Ok(())
}
// Pick a name.
let printname = "example.sock";
let name = printname.to_ns_name::<GenericNamespaced>()?;
// Configure our listener...
let opts = ListenerOptions::new().name(name);
// ...and create it.
let listener = match opts.create_tokio() {
Err(e) if e.kind() == io::ErrorKind::AddrInUse => {
// When a program that uses a file-type socket name terminates its socket server
// without deleting the file, a "corpse socket" remains, which can neither be
// connected to nor reused by a new listener. Normally, Interprocess takes care of
// this on affected platforms by deleting the socket file when the listener is
// dropped. (This is vulnerable to all sorts of races and thus can be disabled.)
// There are multiple ways this error can be handled, if it occurs, but when the
// listener only comes from Interprocess, it can be assumed that its previous instance
// either has crashed or simply hasn't exited yet. In this example, we leave cleanup
// up to the user, but in a real application, you usually don't want to do that.
eprintln!(
"
Error: could not start server because the socket file is occupied. Please check if {printname}
is in use by another process and try again."
);
return Err(e.into());
}
x => x?,
};
// The syncronization between the server and client, if any is used, goes here.
eprintln!("Server running at {printname}");
// Set up our loop boilerplate that processes our incoming connections.
loop {
// Sort out situations when establishing an incoming connection caused an error.
let conn = match listener.accept().await {
Ok(c) => c,
Err(e) => {
eprintln!("There was an error with an incoming connection: {e}");
continue;
}
};
// Spawn new parallel asynchronous tasks onto the Tokio runtime and hand the connection
// over to them so that multiple clients could be processed simultaneously in a
// lightweight fashion.
tokio::spawn(async move {
// The outer match processes errors that happen when we're connecting to something.
// The inner if-let processes errors that happen during the connection.
if let Err(e) = handle_conn(conn).await {
eprintln!("Error while handling connection: {e}");
}
});
}
Variants§
UdSocket(Listener)
Available on Unix only.
Makes use of Unix domain sockets.
Click the struct name in the parentheses to learn more.
Trait Implementations§
source§impl Listener for Listener
impl Listener for Listener
source§fn from_options(options: ListenerOptions<'_>) -> Result<Self>
fn from_options(options: ListenerOptions<'_>) -> Result<Self>
Creates a socket server using the specified options.
source§async fn accept(&self) -> Result<Stream>
async fn accept(&self) -> Result<Stream>
Asynchronously listens for incoming connections to the socket, returning a future that
finishes only when a client is connected.
source§fn do_not_reclaim_name_on_drop(&mut self)
fn do_not_reclaim_name_on_drop(&mut self)
Disables name reclamation on the listener.
Auto Trait Implementations§
impl !Freeze for Listener
impl RefUnwindSafe for Listener
impl Send for Listener
impl Sync for Listener
impl Unpin for Listener
impl UnwindSafe for Listener
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
Mutably borrows from an owned value. Read more