17 个版本

0.8.0 2024 年 3 月 8 日
0.7.1 2021 年 11 月 8 日
0.7.0 2021 年 9 月 29 日
0.6.0 2021 年 6 月 15 日
0.2.2 2019 年 6 月 25 日

#8 in WebSocket

Download history 83143/week @ 2024-04-29 91507/week @ 2024-05-06 101825/week @ 2024-05-13 87625/week @ 2024-05-20 98338/week @ 2024-05-27 104605/week @ 2024-06-03 99277/week @ 2024-06-10 95821/week @ 2024-06-17 115253/week @ 2024-06-24 115038/week @ 2024-07-01 117108/week @ 2024-07-08 129501/week @ 2024-07-15 138993/week @ 2024-07-22 132355/week @ 2024-07-29 137568/week @ 2024-08-05 163602/week @ 2024-08-12

579,465 每月下载量
用于 462 个 Crates(直接使用 23 个)

Apache-2.0 OR MIT

105KB
2.5K SLoC

Soketto

实现 RFC 6455 WebSocket 协议。这个包是对 twist 包的一个大幅修改的分支。


lib.rs:

实现 RFC 6455 WebSocket 协议。

要开始一个 WebSocket 连接,首先需要执行一个 握手,无论是作为 客户端 还是 服务器,以便将 HTTP 升级。一旦成功,客户端或服务器可以过渡到连接,即 发送者/接收者 对,发送和接收文本或二进制数据。

注意:虽然可以只接收 WebSocket 消息,但不能只发送 WebSocket 消息。接收数据是为了对控制帧(如 PING 或 CLOSE)做出反应。虽然这些会透明地得到响应,但它们必须首先接收,因此调用 connection::Receiver::receive 是必要的。

注意:没有哪个 async 方法是安全的,因此它们的 Future 不能被丢弃,除非它们返回 Poll::Ready

客户端示例

use soketto::handshake::{Client, ServerResponse};

// First, we need to establish a TCP connection.
let socket = tokio::net::TcpStream::connect("...").await?;

// Then we configure the client handshake.
let mut client = Client::new(socket.compat(), "...", "/");

// And finally we perform the handshake and handle the result.
let (mut sender, mut receiver) = match client.handshake().await? {
    ServerResponse::Accepted { .. } => client.into_builder().finish(),
    ServerResponse::Redirect { status_code, location } => unimplemented!("follow location URL"),
    ServerResponse::Rejected { status_code } => unimplemented!("handle failure")
};

// Over the established websocket connection we can send
sender.send_text("some text").await?;
sender.send_text("some more text").await?;
sender.flush().await?;

// ... and receive data.
let mut data = Vec::new();
receiver.receive_data(&mut data).await?;


服务器示例

use soketto::{handshake::{Server, ClientRequest, server::Response}};

// First, we listen for incoming connections.
let listener = tokio::net::TcpListener::bind("...").await?;
let mut incoming = TcpListenerStream::new(listener);

while let Some(socket) = incoming.next().await {
    // For each incoming connection we perform a handshake.
    let mut server = Server::new(socket?.compat());

    let websocket_key = {
        let req = server.receive_request().await?;
        req.key()
    };

    // Here we accept the client unconditionally.
    let accept = Response::Accept { key: websocket_key, protocol: None };
    server.send_response(&accept).await?;

    // And we can finally transition to a websocket connection.
    let (mut sender, mut receiver) = server.into_builder().finish();

    let mut data = Vec::new();
    let data_type = receiver.receive_data(&mut data).await?;

    if data_type.is_text() {
        sender.send_text(std::str::from_utf8(&data)?).await?
    } else {
        sender.send_binary(&data).await?
    }

    sender.close().await?
}


查看此包仓库中的 examples/hyper_server.rs 以获取在 Hyper HTTP 服务器旁边启动 WebSocket 服务器的示例。

依赖项

~2.9–4.5MB
~84K SLoC