#websocket #hyper #async

hyper-tungstenite

websockets for hyper servers using tungstenite

7 releases

0.3.2 Apr 11, 2021
0.3.1 Apr 3, 2021
0.3.0 Mar 2, 2021
0.2.1 Feb 12, 2021
0.1.1 Feb 6, 2021

#15 in WebSocket

Download history 65/week @ 2021-02-06 65/week @ 2021-02-13 23/week @ 2021-02-20 48/week @ 2021-02-27 66/week @ 2021-03-06 13/week @ 2021-03-13 24/week @ 2021-03-20 32/week @ 2021-03-27 36/week @ 2021-04-03 45/week @ 2021-04-10 24/week @ 2021-04-17 51/week @ 2021-04-24 90/week @ 2021-05-01

124 downloads per month
Used in 2 crates (via penguin)

BSD-2-Clause

13KB
103 lines

Docs.rs CI

hyper-tungstenite

This crate allows hyper servers to accept websocket connections, backed by tungstenite.

The upgrade function allows you to upgrade a HTTP connection to a websocket connection. It returns a HTTP response to send to the client, and a future that resolves to a WebSocketStream. The response must be sent to the client for the future to be resolved. In practise this means that you must spawn the future in a different task.

Note that the upgrade function itself does not check if the request is actually an upgrade request. For simple cases, you can check this using the is_upgrade_request function before calling upgrade. For more complicated cases where the server should support multiple upgrade protocols, you can manually inspect the Connection and Upgrade headers.

Example

use futures::{sink::SinkExt, stream::StreamExt};
use hyper::{Body, Request, Response};
use hyper_tungstenite::{tungstenite, HyperWebsocket};
use tungstenite::Message;

/// Handle a HTTP or WebSocket request.
async fn handle_request(request: Request<Body>) -> Result<Response<Body>, Box<dyn std::error::Error>> {
    // Check if the request is a websocket upgrade request.
    if hyper_tungstenite::is_upgrade_request(&request) {
        let (response, websocket) = hyper_tungstenite::upgrade(request, None)?;

        // Spawn a task to handle the websocket connection.
        tokio::spawn(async move {
            if let Err(e) = serve_websocket(websocket).await {
                eprintln!("Error in websocket connection: {}", e);
            }
        });

        // Return the response so the spawned future can continue.
        Ok(response)
    } else {
        // Handle regular HTTP requests here.
        Ok(Response::new(Body::from("Hello HTTP!")))
    }
}

/// Handle a websocket connection.
async fn serve_websocket(websocket: HyperWebsocket) -> Result<(), Box<dyn std::error::Error>> {
    let mut websocket = websocket.await?;
    while let Some(message) = websocket.next().await {
        let message = message?;

        // Do something with the message.
        foo(&message);

        // Send a reply.
        websocket.send(Message::text("Thank you, come again.")).await?;
    }

    Ok(())
}

Dependencies

~8MB
~172K SLoC