Trait ConnectionHandler
pub trait ConnectionHandler: Send + 'static {
type FromBehaviour: Debug + Send + 'static;
type ToBehaviour: Debug + Send + 'static;
type InboundProtocol: InboundUpgradeSend;
type OutboundProtocol: OutboundUpgradeSend;
type InboundOpenInfo: Send + 'static;
type OutboundOpenInfo: Send + 'static;
// Required methods
fn listen_protocol(
&self,
) -> SubstreamProtocol<Self::InboundProtocol, Self::InboundOpenInfo>;
fn poll(
&mut self,
cx: &mut Context<'_>,
) -> Poll<ConnectionHandlerEvent<Self::OutboundProtocol, Self::OutboundOpenInfo, Self::ToBehaviour>>;
fn on_behaviour_event(&mut self, _event: Self::FromBehaviour);
fn on_connection_event(
&mut self,
event: ConnectionEvent<'_, Self::InboundProtocol, Self::OutboundProtocol, Self::InboundOpenInfo, Self::OutboundOpenInfo>,
);
// Provided methods
fn connection_keep_alive(&self) -> bool { ... }
fn poll_close(
&mut self,
_: &mut Context<'_>,
) -> Poll<Option<Self::ToBehaviour>> { ... }
fn map_in_event<TNewIn, TMap>(
self,
map: TMap,
) -> MapInEvent<Self, TNewIn, TMap>
where Self: Sized,
TMap: Fn(&TNewIn) -> Option<&Self::FromBehaviour> { ... }
fn map_out_event<TMap, TNewOut>(self, map: TMap) -> MapOutEvent<Self, TMap>
where Self: Sized,
TMap: FnMut(Self::ToBehaviour) -> TNewOut { ... }
fn select<TProto2>(
self,
other: TProto2,
) -> ConnectionHandlerSelect<Self, TProto2>
where Self: Sized { ... }
}
Expand description
A handler for a set of protocols used on a connection with a remote.
This trait should be implemented for a type that maintains the state for the execution of a specific protocol with a remote.
§Handling a protocol
Communication with a remote over a set of protocols is initiated in one of two ways:
-
Dialing by initiating a new outbound substream. In order to do so,
ConnectionHandler::poll()
must return anConnectionHandlerEvent::OutboundSubstreamRequest
, providing an instance oflibp2p_core::upgrade::OutboundUpgrade
that is used to negotiate the protocol(s). Upon success,ConnectionHandler::on_connection_event
is called withConnectionEvent::FullyNegotiatedOutbound
translating the final output of the upgrade. -
Listening by accepting a new inbound substream. When a new inbound substream is created on a connection,
ConnectionHandler::listen_protocol
is called to obtain an instance oflibp2p_core::upgrade::InboundUpgrade
that is used to negotiate the protocol(s). Upon success,ConnectionHandler::on_connection_event
is called withConnectionEvent::FullyNegotiatedInbound
translating the final output of the upgrade.
§Connection Keep-Alive
A ConnectionHandler
can influence the lifetime of the underlying connection
through ConnectionHandler::connection_keep_alive
. That is, the protocol
implemented by the handler can include conditions for terminating the connection.
The lifetime of successfully negotiated substreams is fully controlled by the handler.
Implementors of this trait should keep in mind that the connection can be closed at any time. When a connection is closed gracefully, the substreams used by the handler may still continue reading data until the remote closes its side of the connection.
Required Associated Types§
type FromBehaviour: Debug + Send + 'static
type FromBehaviour: Debug + Send + 'static
A type representing the message(s) a NetworkBehaviour
can send to a ConnectionHandler
via ToSwarm::NotifyHandler
type ToBehaviour: Debug + Send + 'static
type ToBehaviour: Debug + Send + 'static
A type representing message(s) a ConnectionHandler
can send to a NetworkBehaviour
via ConnectionHandlerEvent::NotifyBehaviour
.
type InboundProtocol: InboundUpgradeSend
type InboundProtocol: InboundUpgradeSend
The inbound upgrade for the protocol(s) used by the handler.
type OutboundProtocol: OutboundUpgradeSend
type OutboundProtocol: OutboundUpgradeSend
The outbound upgrade for the protocol(s) used by the handler.
type InboundOpenInfo: Send + 'static
type InboundOpenInfo: Send + 'static
The type of additional information returned from listen_protocol
.
type OutboundOpenInfo: Send + 'static
type OutboundOpenInfo: Send + 'static
The type of additional information passed to an OutboundSubstreamRequest
.
Required Methods§
fn listen_protocol(
&self,
) -> SubstreamProtocol<Self::InboundProtocol, Self::InboundOpenInfo>
fn listen_protocol( &self, ) -> SubstreamProtocol<Self::InboundProtocol, Self::InboundOpenInfo>
The InboundUpgrade
to apply on inbound
substreams to negotiate the desired protocols.
Note: The returned
InboundUpgrade
should always accept all the generally supported protocols, even if in a specific context a particular one is not supported, (eg. when only allowing one substream at a time for a protocol). This allows a remote to put the list of supported protocols in a cache.
fn poll(
&mut self,
cx: &mut Context<'_>,
) -> Poll<ConnectionHandlerEvent<Self::OutboundProtocol, Self::OutboundOpenInfo, Self::ToBehaviour>>
fn poll( &mut self, cx: &mut Context<'_>, ) -> Poll<ConnectionHandlerEvent<Self::OutboundProtocol, Self::OutboundOpenInfo, Self::ToBehaviour>>
Should behave like Stream::poll()
.
fn on_behaviour_event(&mut self, _event: Self::FromBehaviour)
fn on_behaviour_event(&mut self, _event: Self::FromBehaviour)
Informs the handler about an event from the NetworkBehaviour
.
fn on_connection_event( &mut self, event: ConnectionEvent<'_, Self::InboundProtocol, Self::OutboundProtocol, Self::InboundOpenInfo, Self::OutboundOpenInfo>, )
Provided Methods§
fn connection_keep_alive(&self) -> bool
fn connection_keep_alive(&self) -> bool
Returns whether the connection should be kept alive.
§Keep alive algorithm
A connection is always kept alive:
- Whilst a
ConnectionHandler
returnsPoll::Ready
. - We are negotiating inbound or outbound streams.
- There are active
Stream
s on the connection.
The combination of the above means that most protocols will not need to override this method.
This method is only invoked when all of the above are false
, i.e. when the connection is entirely idle.
§Exceptions
- Protocols like circuit-relay v2 need to keep a connection alive beyond these circumstances and can thus override this method.
- Protocols like ping don’t want to keep a connection alive despite an active streams.
In that case, protocol authors can use Stream::ignore_for_keep_alive
to opt-out a particular stream from the keep-alive algorithm.
fn poll_close(&mut self, _: &mut Context<'_>) -> Poll<Option<Self::ToBehaviour>>
fn poll_close(&mut self, _: &mut Context<'_>) -> Poll<Option<Self::ToBehaviour>>
Gracefully close the ConnectionHandler
.
The contract for this function is equivalent to a Stream
.
When a connection is being shut down, we will first poll this function to completion.
Following that, the physical connection will be shut down.
This is also called when the shutdown was initiated due to an error on the connection. We therefore cannot guarantee that performing IO within here will succeed.
To signal completion, [Poll::Ready(None)
] should be returned.
Implementations MUST have a fuse
-like behaviour.
That is, [Poll::Ready(None)
] MUST be returned on repeated calls to ConnectionHandler::poll_close
.
fn map_in_event<TNewIn, TMap>(self, map: TMap) -> MapInEvent<Self, TNewIn, TMap>
fn map_in_event<TNewIn, TMap>(self, map: TMap) -> MapInEvent<Self, TNewIn, TMap>
Adds a closure that turns the input event into something else.
fn map_out_event<TMap, TNewOut>(self, map: TMap) -> MapOutEvent<Self, TMap>
fn map_out_event<TMap, TNewOut>(self, map: TMap) -> MapOutEvent<Self, TMap>
Adds a closure that turns the output event into something else.
fn select<TProto2>(
self,
other: TProto2,
) -> ConnectionHandlerSelect<Self, TProto2>where
Self: Sized,
fn select<TProto2>(
self,
other: TProto2,
) -> ConnectionHandlerSelect<Self, TProto2>where
Self: Sized,
Creates a new ConnectionHandler
that selects either this handler or
other
by delegating methods calls appropriately.
Implementations on Foreign Types§
§impl<L, R> ConnectionHandler for Either<L, R>where
L: ConnectionHandler,
R: ConnectionHandler,
impl<L, R> ConnectionHandler for Either<L, R>where
L: ConnectionHandler,
R: ConnectionHandler,
Implementation of a ConnectionHandler
that represents either of two ConnectionHandler
implementations.