Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WSX — WebSocket Extended (wsx)

An extension-based WebSocket gateway for Go, over RFC 6455. The sibling of rex.

Go Version Coverage License

Alpha. The gateway works: it serves, dispatches, broadcasts and shuts down, at 87.8% coverage with -race throughout. Nothing is published, so go get will not resolve it until the first tag.

Overview

wsx is the gateway: address routing, message dispatch, connection pumps, and a listener. It mirrors rex’s module split, its lifecycle and its decision culture — over RFC 6455 instead of HTTP.

Two topologies, one Gateway:

  • Standalonewsx binds its own net/http listener, so a bind failure is returned from Run rather than surfacing in a goroutine.
  • Mountedrextension-wsx registers a rex route that delegates to Gateway.ServeHTTP.

Dispatch is two levels

A channel is an address pattern — /chat/{roomId} — matched by a parameter trie and resolved once, at the handshake. Within a channel, dispatch is by message name read from an envelope, plus a direction.

Authorization therefore happens once, over HTTP, using the schemes rex already has — rather than through a second, WebSocket-specific path, which is how two security implementations drift apart. And the channel table stays static, which is what lets an AsyncAPI document be generated at startup instead of lazily.

The envelope is a codec, and codecs describe themselves

wsxtension.Codec decodes a frame to a name, a correlation id and a payload. wsx ships three as subpackages — wsx/codec/wsxjson, wsx/codec/jsonrpc, wsx/codec/raw — and dead-code elimination means an unimported one costs nothing in a binary.

A codec also describes itself, which is what lets wsxtension-asyncapi document the format an application is actually speaking instead of a hardcoded envelope.

What it takes responsibility for

Gorilla sets no limits and its writes are not concurrency-safe, so the gateway owns all of it rather than leaving it to handlers: exactly one reader and one writer goroutine per connection, a bounded outbound queue that closes a slow connection rather than silently dropping a message from an ordered conversation, a server-initiated ping with a pong deadline so half-open connections cannot accumulate, and a required origin allowlist — because WebSocket is not subject to CORS and the browser sends the request regardless.

Installation

go get github.com/kryovyx/wsx

Testing a handler without a port

wsx/wsxtest connects a real gorilla client to a real net/http.Server over net.Pipe — no listener, no port, no kernel socket. The handshake, the framing, the origin check, the caps and the close handshake are all production code paths.

c, err := wsxtest.Dial(gateway, wsxtest.Options{Path: "/chat/42"})
defer c.Close()

c.SendJSON(map[string]any{"type": "chat.send", "id": "1", "payload": msg})
var reply Envelope
c.ReceiveJSON(&reply)

Without it, every test of a handler, a middleware or a codec in every downstream module would bind a port — which makes them slow, makes them fail in parallel, and makes them fail in a sandbox with no network, so the tests that matter most become the ones people skip.

Where this fits

New in the REX v0.3.0 release, at v0.1.0 — there is nothing to migrate from. MIGRATION.md says what this module is, what it costs to adopt, and links to the guide for every other module in that release.

Status

The gateway is complete and tested: 87.8% coverage, -race throughout, and the pumps and the send queue were tested before the dispatcher existed — which caught a time.NewTicker(0) panic, a read deadline of now+0 that dropped every connection instantly, and a select whose random case choice made Send-after-close succeed half the time.

What is uncovered is the double-fault paths: a write that fails while a close is already in progress, an encode that fails while answering an encode failure. Reaching them needs a socket that fails on command in the middle of a real handshake.

Not published. External contributions open at v1.0.0 — see CONTRIBUTING.md. Issues are welcome now.

License

MIT — see LICENSE.

About

WebSocket eXperience — an extension-based WebSocket gateway for Go. Channel dispatch, connection pumps, per-connection dependency scopes and lifecycle management.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages