pub struct ProtocolListener { /* private fields */ }Expand description
Accept inbound WebSocket peers and drive each one through the
protocol-client state machine. Construct via
ProtocolClientBuilder::listen.
Sendspin’s protocol-client/server roles are independent of who
initiates the TCP connection — the protocol-client always sends
client/hello first. This listener handles the server-initiated
case; the ProtocolClient returned by Self::accept is
indistinguishable in shape from one returned by
ProtocolClientBuilder::connect.
Self::accept drives the full protocol handshake before returning, so
it serves one inbound connection at a time — a slow handshake blocks the
next accept(). If you need concurrent handshakes, or want to own the
transport (custom TLS, HTTP routing, …), accept your own streams and drive
ProtocolClientBuilder::accept on each, tokio::spawn-ing per peer.
The Sendspin spec allows multiple servers to initiate connections to the
same client. The keep-or-switch policy belongs to the application: read
ProtocolClient::server_hello for server_id and connection_reason,
compare against your persisted last-played server, and send
GoodbyeReason::AnotherServer to the loser. This listener does not
enforce a policy.
Practical notes:
- Disconnect consumes the handle. Call
ProtocolClient::disconnectpre-split, orconnection.guard.disconnect(...)post-split. Self::acceptis serial. If the loser’s goodbye is on the critical path, run it on a spawned task so the next inbound peer can handshake while the previous one is tearing down.
Implementations§
Source§impl ProtocolListener
impl ProtocolListener
Sourcepub fn path(self, path: impl Into<String>) -> Self
pub fn path(self, path: impl Into<String>) -> Self
Restrict accepted connections to a specific HTTP path. Mismatches are rejected with HTTP 404 during the WebSocket handshake; the listener stays bound. Defaults to accepting any path.
Matching is exact: /sendspin does not match /sendspin/. A missing
leading slash is added, so "sendspin" and "/sendspin" are
equivalent — request paths always start with /, and the raw form
would otherwise reject every connection.
Sourcepub async fn accept(&self) -> Result<(ProtocolClient, SocketAddr), Error>
pub async fn accept(&self) -> Result<(ProtocolClient, SocketAddr), Error>
Accept the next inbound connection, returning the driven
ProtocolClient and the peer’s address. Performs the WebSocket
handshake and protocol-client hello/state exchange.
Per-peer failures surface as Error without affecting the
listener; callers typically call accept() in a loop.
Not cancel-safe: dropping the returned future mid-handshake tears down that connection. A peer that connects but stalls the handshake will block this future indefinitely, so wrap it in a timeout if untrusted peers can reach the socket.
Sourcepub fn local_addr(&self) -> Result<SocketAddr, Error>
pub fn local_addr(&self) -> Result<SocketAddr, Error>
Local bound address.