It handles both HTTP1 and HTTP2 connections.
use std::net::SocketAddr;
use pavex::server::Server;
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
Server::new()
.bind(addr)
.await?
// Both the routing function and the application state will usually
// be code-generated by Pavex, starting from your `Blueprint`.
// You don't have to define them manually!
.serve(router, application_state)
// The `serve` method returns a `ServerHandle` that you can use to
// interact with the server.
// Calling `.await` on the handle lets you wait until the server
// shuts down.
.await;
Server::new
returns a new Server
with default configuration.
You can customize the server default settings by creating your own ServerConfiguration
and invoking Server::set_config
.
By default, Server::serve
creates a worker per CPU core and distributes connection from an
acceptor thread using a round-robin strategy.
Each worker has its own single-threaded [tokio
] runtime—there is no work stealing across
workers.
Each worker takes care to invoke your routing and request handling logic, with the help
of [hyper
].
Configure this Server
according to the values set in the ServerConfiguration
passed as input parameter.
It will overwrite any previous configuration set on this Server
.
If you want to retrieve the current configuration, use Server::get_config
.
Get a reference to the ServerConfiguration
for this Server
.
If you want to overwrite the existing configuration, use Server::set_config
.
Bind the server to the given address: the server will accept incoming connections from this
address when started.
Binding an address may fail (e.g. if the address is already in use), therefore this method
may return an error.
Check out Server::listen
for an alternative binding mechanism as well as a
discussion of the pros and cons of Server::bind
vs Server::listen
.
A Server
can be bound to multiple addresses: just call this method multiple times with
all the addresses you want to bind to.
use std::net::SocketAddr;
use pavex::server::Server;
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
Server::new()
.bind(addr)
.await?
// [...]
use std::net::SocketAddr;
use pavex::server::Server;
let addr1 = SocketAddr::from(([127, 0, 0, 1], 8080));
let addr2 = SocketAddr::from(([127, 0, 0, 1], 4000));
Server::new()
.bind(addr1)
.await?
.bind(addr2)
.await?
// [...]
Ask the server to process incoming connections from the provided IncomingStream
.
Server::listen
vs Server::bind
Server::bind
only requires you to specify the address you want to listen at. The
socket configuration is handled by the Server
, with a set of reasonable default
parameters. You have no access to the IncomingStream
that gets bound to the address
you specified.
Server::listen
, instead, expects an IncomingStream
.
You are free to configure the socket as you see please and the Server
will just
poll it for incoming connections.
It also allows you to interact with the bound IncomingStream
directly
use std::net::SocketAddr;
use pavex::server::{IncomingStream, Server};
// `0` is a special port: it tells the OS to assign us
// a random **unused** port
let addr = SocketAddr::from(([127, 0, 0, 1], 0));
let incoming = IncomingStream::bind(addr).await?;
// We can then retrieve the actual port we were assigned
// by the OS.
let addr = incoming.local_addr()?.to_owned();
Server::new()
.listen(incoming);
// [...]
use std::net::SocketAddr;
use socket2::Domain;
use pavex::server::{IncomingStream, Server};
// `0` is a special port: it tells the OS to assign us
// a random **unused** port
let addr = SocketAddr::from(([127, 0, 0, 1], 0));
let socket = socket2::Socket::new(
Domain::for_address(addr),
socket2::Type::STREAM,
Some(socket2::Protocol::TCP),
)
.expect("Failed to create a socket");
socket.set_reuse_address(true)?;
socket.set_nonblocking(true)?;
socket.bind(&addr.into())?;
// The custom backlog!
socket.listen(2048_i32)?;
let listener = std::net::TcpListener::from(socket);
Server::new()
.listen(listener.try_into()?)
// [...]
A Server
can listen to multiple streams of incoming connections: just call this method
multiple times!
Start listening for incoming connections.
You must specify:
Both the handler function and the application state are usually code-generated by Pavex
starting from your Blueprint
.
serve
returns a ServerHandle
.
Calling .await
on the handle lets you wait until the server shuts down.
This method will panic if the Server
has no registered source of incoming connections,
i.e. if you did not call Server::bind
or Server::listen
before calling serve
.