Skip to main content

WebSocketHandler

Trait WebSocketHandler 

Source
pub trait WebSocketHandler:
    Send
    + Sync
    + 'static {
    // Required method
    fn on_message<'life0, 'life1, 'async_trait>(
        &'life0 self,
        socket: &'life1 Socket,
        message: Message,
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait;

    // Provided methods
    fn on_connect<'life0, 'life1, 'async_trait>(
        &'life0 self,
        socket: &'life1 Socket,
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait { ... }
    fn on_close<'life0, 'life1, 'async_trait>(
        &'life0 self,
        socket: &'life1 Socket,
    ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait { ... }
    fn authorize(&self, request: &Request) -> bool { ... }
}
Expand description

One WebSocket endpoint.

ⓘ
pub struct Chat;

#[async_trait]
impl WebSocketHandler for Chat {
    async fn on_message(&self, socket: &Socket, message: Message) -> Result<()> {
        socket.send(format!("you said: {}", message.as_text().unwrap_or("")))
    }
}

§The three hooks

on_connect runs once, after the handshake. on_message runs per frame. on_close runs once, whatever ended the connection — a clean close, a dropped TCP connection, or an error from one of the other two. That last guarantee is the one worth relying on: a room registry that only cleaned up on a polite goodbye would leak an entry for every client that closed its laptop.

§Errors

An error from on_connect or on_message closes the connection and is logged. It is not sent to the client — the same rule a 5xx follows, and for the same reason: an error message is written for you, not for whoever is connected.

Required Methods§

Source

fn on_message<'life0, 'life1, 'async_trait>( &'life0 self, socket: &'life1 Socket, message: Message, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

A frame arrived.

Provided Methods§

Source

fn on_connect<'life0, 'life1, 'async_trait>( &'life0 self, socket: &'life1 Socket, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

A new client has finished the handshake.

The place to greet them, register them in a room, or close the connection because they should not be here.

Source

fn on_close<'life0, 'life1, 'async_trait>( &'life0 self, socket: &'life1 Socket, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

The connection has ended, however it ended.

Runs exactly once per connection. Cannot fail, because there is nothing left to fail into — clean up and log.

Source

fn authorize(&self, request: &Request) -> bool

Whether this request may open a socket at all.

Runs before the handshake, with the HTTP request that asked to upgrade — so it has the headers, the cookies and whatever the middleware put in the extensions. Returning false answers 403 and no socket is created.

The default allows everyone, which is right for a public feed and wrong for anything else. A socket is a route: it needs the same thought about who may reach it.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§