websocket

WebSocket client and server for Kit using native Zig FFI (RFC 6455)

Files

FileDescription
.editorconfigEditor formatting configuration
.gitignoreGit ignore rules for build artifacts and dependencies
.tool-versionsasdf tool versions (Zig, Kit)
LICENSEMIT license file
README.mdThis file
docs/Generated API documentation directory
examples/websocket.kitWebSocket client usage example
kit.tomlPackage manifest with metadata, capabilities, tasks, and exclusions
src/websocket.kitPublic Kit API, typed errors, and extern Zig declarations
tests/websocket.test.kitTests for error types, matching, and close-code constants
zig/kit_ffi.zigShared Kit FFI value helpers for local Zig tests
zig/websocket.zigRFC 6455 framing, handshake, and socket FFI implementation

Dependencies

No Kit package dependencies.

This package uses Zig FFI and requires the ffi and net capabilities declared in kit.toml.

Installation

kit add gitlab.com/kit-lang/packages/kit-websocket.git

Usage

import Kit.Websocket as websocket

main = fn =>
  connect-result = websocket.connect "ws://localhost:8080/socket"

  match connect-result
    | Err e ->
      println "Connection failed: ${show e}"

    | Ok conn ->
      defer websocket.close conn

      match websocket.send conn "Hello from Kit!"
        | Ok _ -> println "Message sent"
        | Err e -> println "Send failed: ${show e}"

      match websocket.recv conn
        | Ok message ->
          println "Received ${message.type}: ${message.data}"
        | Err e ->
          println "Receive failed: ${show e}"

main

Client API

FunctionDescription
connect urlConnect to a ws:// WebSocket endpoint
connect-with-headers url headersConnect with custom HTTP upgrade headers
connect-with-subprotocol url subprotocolRequest a WebSocket subprotocol during the handshake
send conn textSend a text frame
send-binary conn dataSend a binary frame using a Kit string as byte data
recv connReceive the next text or binary message
recv-timeout conn timeout-msReceive with a timeout and return Option Record
ping conn / ping-with-data conn dataSend ping frames
pong conn dataSend a pong frame
close connClose with status code 1000
close-with-reason conn code reasonClose with an explicit code and reason
is-open? connInspect the connection record's open flag
subprotocol connReturn the negotiated subprotocol, if present

Server Helpers

The server-side helpers operate on raw socket integers supplied by other networking code:

FunctionDescription
accept-key client-keyCompute the Sec-WebSocket-Accept response header
send-server socket textSend an unmasked text frame from a server
send-binary-server socket dataSend an unmasked binary frame from a server
recv-server socketReceive a client frame and require client masking
close-server socketSend a normal close frame and close the socket
ping-server socket / pong-server socket dataSend server control frames

Notes

  • wss:// secure WebSocket connections are currently rejected with WebSocketConnectionError. Use ws:// endpoints until TLS support is added.
  • Client frames are masked, as required by RFC 6455.
  • Server frames are unmasked, as required by RFC 6455.
  • Ping and pong payloads are limited to 125 bytes.
  • Message records have {type: String, data: String} where type is "text" or "binary".
  • Error values use WebSocketError variants with Show and Error implementations.

Architecture

WebSocket Handshake

sequenceDiagram participant Client participant Server Client->>Server: HTTP Upgrade Request Server->>Client: 101 Switching Protocols Note over Client,Server: WebSocket Connection Open Client->>Server: Text/Binary Frame Server->>Client: Text/Binary Frame Client->>Server: Ping Server->>Client: Pong Client->>Server: Close Frame Server->>Client: Close Frame Note over Client,Server: Connection Closed

FFI Structure

graph TD A[Kit Code] -->|import Kit.Websocket| B[src/websocket.kit] B -->|extern-zig| C[zig/websocket.zig] C --> D[Kit FFI Value Helpers] C --> E[Zig POSIX Socket APIs]

Development

Running Examples

Run examples with the interpreter:

kit run examples/websocket.kit

Compile examples to a native binary:

kit build examples/websocket.kit -o websocket-example
./websocket-example

Running Tests

Run the test suite:

kit test

Run the test suite with coverage:

kit test --coverage

Running kit dev

Run the standard development workflow (format, check, test):

kit dev

This will:

  1. Format and check source files in src/, examples/, and tests/
  2. Run tests in tests/ with coverage

Running Parity Checks

Compare interpreter and compiler behavior for examples:

kit parity --failures-only

The example imports the local source file with a lowercase alias so parity checks this checkout and avoids compiled module-alias collisions.

Generating Documentation

Generate API documentation from doc comments:

kit doc

Note: Kit sources with doc comments (##) will generate HTML documents in docs/*.html.

Cleaning Build Artifacts

Remove generated files, caches, and build artifacts:

kit task clean

Note: Defined in kit.toml.

Local Installation

To install this package locally for development:

kit install

This installs the package to ~/.kit/packages/@kit/websocket/, making it available for import as Kit.Websocket in other projects.

License

This package is released under the MIT License - see LICENSE for details.

Exported Functions & Types

WebSocketError

WebSocket error type for typed error handling. Variants distinguish between different failure modes.

Variants

WebSocketConnectionError {message}
WebSocketHandshakeError {message}
WebSocketSendError {message}
WebSocketRecvError {message}
WebSocketProtocolError {message}