pub enum NetworkBehaviourAction<TOutEvent, THandler: IntoConnectionHandler, TInEvent = <<THandler as IntoConnectionHandler>::Handler as ConnectionHandler>::InEvent> {
GenerateEvent(TOutEvent),
Dial {
opts: DialOpts,
handler: THandler,
},
NotifyHandler {
peer_id: PeerId,
handler: NotifyHandler,
event: TInEvent,
},
ReportObservedAddr {
address: Multiaddr,
score: AddressScore,
},
CloseConnection {
peer_id: PeerId,
connection: CloseConnection,
},
}
Expand description
An action that a NetworkBehaviour
can trigger in the Swarm
in whose context it is executing.
Variants§
GenerateEvent(TOutEvent)
Instructs the Swarm
to return an event when it is being polled.
Dial
Instructs the swarm to start a dial.
On success, NetworkBehaviour::inject_connection_established
is invoked.
On failure, NetworkBehaviour::inject_dial_failure
is invoked.
Note that the provided handler is returned to the NetworkBehaviour
on connection failure
and connection closing. Thus it can be used to carry state, which otherwise would have to be
tracked in the NetworkBehaviour
itself. E.g. a message destined to an unconnected peer
can be included in the handler, and thus directly send on connection success or extracted by
the NetworkBehaviour
on connection failure.
Example carrying state in the handler
// Super precious message that we should better not lose.
let message = PreciousMessage("My precious message".to_string());
// Unfortunately this peer is offline, thus sending our message to it will fail.
let offline_peer = PeerId::random();
// Let's send it anyways. We should get it back in case connecting to the peer fails.
swarm.behaviour_mut().send(offline_peer, message);
block_on(async {
// As expected, sending failed. But great news, we got our message back.
matches!(
swarm.next().await.expect("Infinite stream"),
SwarmEvent::Behaviour(PreciousMessage(_))
);
});
#[derive(Default)]
struct MyBehaviour {
outbox_to_swarm: VecDeque<NetworkBehaviourAction<PreciousMessage, MyHandler>>,
}
impl MyBehaviour {
fn send(&mut self, peer_id: PeerId, msg: PreciousMessage) {
self.outbox_to_swarm
.push_back(NetworkBehaviourAction::Dial {
opts: DialOpts::peer_id(peer_id)
.condition(PeerCondition::Always)
.build(),
handler: MyHandler { message: Some(msg) },
});
}
}
impl NetworkBehaviour for MyBehaviour {
fn inject_dial_failure(
&mut self,
_: Option<PeerId>,
handler: Self::ConnectionHandler,
_: &DialError,
) {
// As expected, sending the message failed. But lucky us, we got the handler back, thus
// the precious message is not lost and we can return it back to the user.
let msg = handler.message.unwrap();
self.outbox_to_swarm
.push_back(NetworkBehaviourAction::GenerateEvent(msg))
}
}
NotifyHandler
Fields
peer_id: PeerId
The peer for whom a ConnectionHandler
should be notified.
handler: NotifyHandler
The options w.r.t. which connection handler to notify of the event.
event: TInEvent
The event to send.
Instructs the Swarm
to send an event to the handler dedicated to a
connection with a peer.
If the Swarm
is connected to the peer, the message is delivered to the
ConnectionHandler
instance identified by the peer ID and connection ID.
If the specified connection no longer exists, the event is silently dropped.
Typically the connection ID given is the same as the one passed to
NetworkBehaviour::inject_event
, i.e. whenever the behaviour wishes to
respond to a request on the same connection (and possibly the same
substream, as per the implementation of ConnectionHandler
).
Note that even if the peer is currently connected, connections can get closed at any time and thus the event may not reach a handler.
ReportObservedAddr
Fields
address: Multiaddr
The observed address of the local node.
score: AddressScore
The score to associate with this observation, i.e. an indicator for the trusworthiness of this address relative to other observed addresses.
Informs the Swarm
about an address observed by a remote for
the local node by which the local node is supposedly publicly
reachable.
It is advisable to issue ReportObservedAddr
actions at a fixed frequency
per node. This way address information will be more accurate over time
and individual outliers carry less weight.
CloseConnection
Fields
connection: CloseConnection
Whether to close a specific or all connections to the given peer.
Instructs the Swarm
to initiate a graceful close of one or all connections
with the given peer.
Note: Closing a connection via
NetworkBehaviourAction::CloseConnection
does not inform the
corresponding ConnectionHandler
.
Closing a connection via a ConnectionHandler
can be done
either in a collaborative manner across ConnectionHandler
s
with ConnectionHandler::connection_keep_alive
or directly with
ConnectionHandlerEvent::Close
.
Implementations§
source§impl<TOutEvent, THandler: IntoConnectionHandler, TInEventOld> NetworkBehaviourAction<TOutEvent, THandler, TInEventOld>
impl<TOutEvent, THandler: IntoConnectionHandler, TInEventOld> NetworkBehaviourAction<TOutEvent, THandler, TInEventOld>
sourcepub fn map_in<TInEventNew>(
self,
f: impl FnOnce(TInEventOld) -> TInEventNew
) -> NetworkBehaviourAction<TOutEvent, THandler, TInEventNew>
pub fn map_in<TInEventNew>(
self,
f: impl FnOnce(TInEventOld) -> TInEventNew
) -> NetworkBehaviourAction<TOutEvent, THandler, TInEventNew>
Map the handler event.
source§impl<TOutEvent, THandler: IntoConnectionHandler> NetworkBehaviourAction<TOutEvent, THandler>
impl<TOutEvent, THandler: IntoConnectionHandler> NetworkBehaviourAction<TOutEvent, THandler>
sourcepub fn map_out<E>(
self,
f: impl FnOnce(TOutEvent) -> E
) -> NetworkBehaviourAction<E, THandler>
pub fn map_out<E>(
self,
f: impl FnOnce(TOutEvent) -> E
) -> NetworkBehaviourAction<E, THandler>
Map the event the swarm will return.
source§impl<TInEvent, TOutEvent, THandlerOld> NetworkBehaviourAction<TOutEvent, THandlerOld>where
THandlerOld: IntoConnectionHandler,
<THandlerOld as IntoConnectionHandler>::Handler: ConnectionHandler<InEvent = TInEvent>,
impl<TInEvent, TOutEvent, THandlerOld> NetworkBehaviourAction<TOutEvent, THandlerOld>where
THandlerOld: IntoConnectionHandler,
<THandlerOld as IntoConnectionHandler>::Handler: ConnectionHandler<InEvent = TInEvent>,
sourcepub fn map_handler<THandlerNew>(
self,
f: impl FnOnce(THandlerOld) -> THandlerNew
) -> NetworkBehaviourAction<TOutEvent, THandlerNew>where
THandlerNew: IntoConnectionHandler,
<THandlerNew as IntoConnectionHandler>::Handler: ConnectionHandler<InEvent = TInEvent>,
pub fn map_handler<THandlerNew>(
self,
f: impl FnOnce(THandlerOld) -> THandlerNew
) -> NetworkBehaviourAction<TOutEvent, THandlerNew>where
THandlerNew: IntoConnectionHandler,
<THandlerNew as IntoConnectionHandler>::Handler: ConnectionHandler<InEvent = TInEvent>,
Map the handler.
source§impl<TInEventOld, TOutEvent, THandlerOld> NetworkBehaviourAction<TOutEvent, THandlerOld>where
THandlerOld: IntoConnectionHandler,
<THandlerOld as IntoConnectionHandler>::Handler: ConnectionHandler<InEvent = TInEventOld>,
impl<TInEventOld, TOutEvent, THandlerOld> NetworkBehaviourAction<TOutEvent, THandlerOld>where
THandlerOld: IntoConnectionHandler,
<THandlerOld as IntoConnectionHandler>::Handler: ConnectionHandler<InEvent = TInEventOld>,
sourcepub fn map_handler_and_in<THandlerNew, TInEventNew>(
self,
f_handler: impl FnOnce(THandlerOld) -> THandlerNew,
f_in_event: impl FnOnce(TInEventOld) -> TInEventNew
) -> NetworkBehaviourAction<TOutEvent, THandlerNew>where
THandlerNew: IntoConnectionHandler,
<THandlerNew as IntoConnectionHandler>::Handler: ConnectionHandler<InEvent = TInEventNew>,
pub fn map_handler_and_in<THandlerNew, TInEventNew>(
self,
f_handler: impl FnOnce(THandlerOld) -> THandlerNew,
f_in_event: impl FnOnce(TInEventOld) -> TInEventNew
) -> NetworkBehaviourAction<TOutEvent, THandlerNew>where
THandlerNew: IntoConnectionHandler,
<THandlerNew as IntoConnectionHandler>::Handler: ConnectionHandler<InEvent = TInEventNew>,
Map the handler and handler event.