Categorygithub.com/microsoft/wsplice
repositorypackage
0.1.0
Repository: https://github.com/microsoft/wsplice.git
Documentation: pkg.go.dev

# Packages

No description provided by the author

# README

wsplice Build Status

wsplice is a websocket multiplexer, allowing you to connect to multiple remote hosts though a single websocket.

Usage

Download a binary from the Releases page. You can then run it from the command line. wsplice can be configured to use client certification authentication, and/or an allowlist of remote hostnames it's allowed to connect to.

# Run a publicly accessible instance with client cert auth
./wsplice --tls-cert=my-cert.pem \
    --tls-key=my-key.pem \
    --tls-ca=my-ca.pem \
    --listen=0.0.0.0:3000

# Omit the CA cert to run it over TLS, and allow it to connect
# to example.com and ws.example.com
./wsplice --tls-cert=my-cert.pem \
    --tls-key=my-key.pem \
    --allowed-hostnames="example.com ws.example.com"

Protocol

Websocket frames are prefixed with two bytes, as a big endian uint16, to describe who that message goes to. The magic control index is [0xff, 0xff], which is a simple JSON RPC protocol. To connect to another server, you might do something like this in Node.js:

const payload = Buffer.concat([
    Buffer.from([0xff, 0xff]),
    Buffer.from(JSON.stringify({
        id: 42,
        type: "method",
        method: "connect",
        params: {
            url: "ws://example.com",
            headers: { /* ... */ }, // optional
            subprotocols: [/* ... */], // optional
        }
    }))
]);

websocket.write(payload);

The response is a JSON object like:

{
  "id": 42,
  "type": "reply",
  "result": {
    "index": 0
  }
}

In this case the socket index is 0. You can send messages to that websocket by prefixing the messages with 0, encoded as a big endian uint16, and likewise wsplice will proxy and prefix messages that it gets from that server with the same. All frames, with the exception of ping and pong frames (which are handled automatically for you) will be proxied.

Once the client disconnects, the wsplice will call onSocketDisconnect. For example:

{
  "id": 0,
  "type": "method",
  "method": "onSocketDisconnect",
  "params": {
    "code": 4123,
    "message": "The socket close reason, if any",
    "index": 0
  }
}

Performance

wsplice spends most time (upwards of 90%) handling network reads/writes; performance is generally bounded by how much data your operating system's kernel and send or receive from a single connection.

Throughputpayload=32Bpayload=128Bpayload=1024Bpayload=4098B
clients=32231 mbps235 mbps2940 mbps11200 mbps
clients=128327 mbps333 mbps2520 mbps14600 mbps
clients=51246.3 mbps533 mbps3570 mbps11200 mbps
Latency
clients=325.6μs4.6μs5.4μs7.4μs
clients=1284.7μs5.2μs5.7μs5.7μs
clients=5123.7μs4.0μs5.2μs7.1μs

These measurements were taken on an B8 Azure VM running Ubuntu 16.04, using the binary in ./cmd/bench.