Skip to content
CryoCryo home
Stdlibnet::ws

conn

import std::net::ws::conn; · source

WebSocket<S>

type struct WebSocket<S> {
    conn:      BufStream<S>;
    is_client: boolean;
    closed:    boolean;

    static of(conn: BufStream<S>, is_client: boolean) -> WebSocket<S>;
    connection(mut &this) -> BufStream<S>*;
    is_closed(&this) -> boolean;
    async client_handshake(mut &this, host: Str, path: Str) -> Result<(), IoError>
    where S: AsyncTransport;
    async server_handshake(mut &this) -> Result<(), IoError>
    where S: AsyncTransport;
    async send_text(mut &this, text: Str) -> Result<(), IoError>
    where S: AsyncTransport;
    async send_binary(mut &this, data: Slice<u8>) -> Result<(), IoError>
    where S: AsyncTransport;
    async ping(mut &this, data: Slice<u8>) -> Result<(), IoError>
    where S: AsyncTransport;
    async close(mut &this, code: u16, reason: Str) -> Result<(), IoError>
    where S: AsyncTransport;
    async recv(mut &this) -> Result<Message, IoError>
    where S: AsyncTransport;
}
async function connect(sock: TcpStream, host: Str, path: Str) -> Result<WebSocket<TcpStream>, IoError>;
async function accept(sock: TcpStream) -> Result<WebSocket<TcpStream>, IoError>;

A WebSocket<S> owns a BufStream<S> over any AsyncTransport. connect(sock, host, path) and accept(sock) wrap a plain TcpStream and run the handshake in one step. For a TLS transport, or to control the buffering, build with of(conn, is_client) and call client_handshake(host, path) or server_handshake() yourself. The handshake is an HTTP/1.1 Upgrade.

mut ws: WebSocket<TlsStream> = WebSocket<TlsStream>::of(BufStream<TlsStream>::of(tls), true);
await ws.client_handshake(host, path)?;

The message surface is send_text, send_binary, ping, close(code, reason), and recv — all async. Framing covers text and binary messages, fragmentation reassembly, and the Ping/Pong/Close control frames. recv yields application messages only: it answers a Ping with a Pong itself, skips incoming Pongs, and surfaces a Close frame as Message::Close. A bounded number of control frames is serviced per recv, so a peer flooding pings cannot keep the call from ever returning. is_closed() reports whether a close has been sent or received; connection() surfaces the transport for socket options, not for I/O.

Clients mask every frame they send and servers must not, as the RFC requires; is_client is what decides, and a frame arriving with the wrong masking is a protocol error.

Message

type enum Message {
    Text(String);
    Binary(Array<u8>);
    Close;
}

What recv yields: a reassembled text or binary message, or the peer's close.

Trait implementations

implement trait Drop for struct WebSocket<S>

Dropping the socket drops the connection. Send close first if you want the peer to see a clean shutdown rather than a reset.