Skip to content

Examples

Gerasimos (Makis) Maropoulos edited this page Oct 6, 2026 · 3 revisions

When to use this page

  • You want a working example you can copy and run.
  • You're not sure which neffos feature to use for your problem.

Runnable programs for neffos, ordered the way you would learn it: a tutorial that grows one chat app step by step, then one section per topic. Every example is a single main.go (plus an index.html where a browser page helps) that opens with a comment saying what it shows, what you will be able to do afterwards, how to run and try it, and which example to read next. Every section names the wiki page it pairs with.

Requirements: Go 1.27 or newer. A few examples need more, and say so in a Requires: line: Redis or NATS for scale-out, Docker for its compose file, protoc only to regenerate the protobuf code. New to neffos? Start with 01-getting-started and do the steps in order.

Running an example

All examples share one module, _examples/go.mod, which points github.com/kataras/neffos at the code in this repository. In a clone, run an example from its folder:

cd _examples/01-getting-started/01-echo
go run main.go server          # terminal 1
go run main.go client alice    # terminal 2

In your own module, copy the files and fetch the released library:

mkdir myapp && cd myapp
go mod init myapp
go get github.com/kataras/neffos@latest
# copy the example's main.go (and index.html, if it has one) here, then:
go run . server

Every example listens on :8080 with its websocket endpoint at /ws. The exceptions are the two scale-out examples, which run a second server on :9090, and the load tests, which use :9595. A program with a Go client takes server or client <name> as its first argument, after any flags.

01. Getting started: the Lobby tutorial

Twelve programs that grow one app, the Lobby (a chat with a namespace, rooms, private messages and an operator console), from a single echo event to a tested server with a browser client. Each step is a complete main.go that adds one idea to the previous one, keeping the same function names and order (main, newServer, runServer, runClient, serverEvents, clientEvents), so you can diff two neighbours to see exactly what changed. Do them in order; afterwards the other sections stand alone as references. You should be comfortable with Go and know what a websocket is. No neffos experience is assumed.

Wiki: Getting started, then Namespaces, Rooms and Broadcast.

Step Shows
01-echo The smallest server and Go client: neffos.New, gorilla.DefaultUpgrader, Events, neffos.Reply, Dial, Connect, Emit, NotifyClose
02-namespaces A chat namespace, the user name as the connection ID through IDGenerator, and every lifecycle hook logged
03-broadcast Relaying to everyone else with BroadcastOthers, operator notices with Server.Broadcast, private messages with Message.To, Exclude
04-rooms /join and /leave, room-scoped chat, a staff room gated in OnRoomJoin, IsForced when a connection drops
05-encoding JSON bodies with SendObject, msg.As[T](), Marshal and MessageObjectMarshaler (the encoder is encoding/json/v2); binary frames with EmitBinary and SetBinary
06-ask-and-errors NSConn.Ask and Server.Ask with context deadlines, Message.Err, RegisterKnownError and errors.Is across the wire
07-authentication A bearer token checked by HTTP middleware (401) and by OnConnect, the user kept with Conn.Set and Conn.Get
08-timeouts-and-limits WithTimeout: read and write deadlines, a heartbeat with PingInterval, MaxMessageSize; Send errors sorted with IsTimeoutError and IsDisconnectError
09-close-and-shutdown Kicking a user with Conn.Terminate(4000, reason), reading CloseStatus(c.Err()) on both sides, and Server.Shutdown on Ctrl+C
10-struct-handler The server's handlers as a per-connection struct: NewStruct, EventTrimPrefixMatcher, JoinConnHandlers, and the limits through SetTimeouts, SetPingInterval, SetMaxMessageSize
11-testing main_test.go: httptest.NewServer(newServer()), two Go clients per test, channel and select assertions, close codes
12-browser-client The same chat from the browser: an index.html embedded with //go:embed, neffos.js dial with reconnection, connect, emit, ask, joinRoom, emitBinary

02. Backends

neffos runs on gorilla/websocket, gobwas/ws or coder/websocket; the events code is the same on all three.

Wiki: Upgraders and Dialers, Choosing a backend.

Example Shows
choose-backend One program, three backends: a -backend gorilla|gobwas|coder flag picks the DefaultUpgrader and DefaultDialer pair; any client talks to any server
custom-options Each library's own options side by side: origin checks (CheckOrigin, OriginPatterns, a middleware for gobwas), a subprotocol, buffer sizes, handshake headers
socket-wrapper A frame-counting Socket wrapper through Server.Upgrade that passes on SocketCloser, SocketPinger and SocketReadLimiter

03. Messaging

Wiki: Encoding, Binary messages, Protobufs, Native messages, Errors.

Example Shows
protobuf Protocol Buffers bodies sent as binary frames with EmitBinary, a .proto file and its generated Go code
native-messages Plain websocket clients (a browser WebSocket, websocat) through OnNativeMessage and Message.IsNative
known-errors Error values shared by server and client with RegisterKnownError and errors.Is, a ResolveError method for error texts that carry data, and CloseError{Code: 4001} returned from an event

04. Handlers

Wiki: Struct handlers, Namespaces.

Example Shows
compose-handlers Building handlers in pieces: Events.On, Namespaces.On, JoinConnHandlers and the catch-all OnAnyEvent
struct-injector Struct[T].SetInjector(func(*NSConn) *T) builds each connection's controller with its dependencies; EventPrefixMatcher; two controllers in two namespaces

05. Connections

Wiki: Connections.

Example Shows
users-and-devices One user with several connections: a registry keyed by user that sends to all of their devices
rate-limit A one-second window with Conn.Increment and Conn.Decrement; a client that floods is closed with ClosePolicyViolation and a reason
inspect-and-do An operator console over live connections: GetConnections, GetConnectionsByNamespace, Server.Do, Conn.DisconnectAll, FireDisconnectAlways, ReconnectTries

06. Server push

Wiki: Broadcast.

Example Shows
http-to-websocket POST /notify?user= pushes to one user, or to everyone without user, with Server.Broadcast and Message.To
cron-notifications A scheduled job (robfig/cron) delivering pending notifications to the users who are online

07. Scale out

Wiki: Scale out, Redis, Nats, Writing a custom StackExchange.

Example Shows
redis-or-nats Two servers acting as one through Redis or NATS: -addr and -exchange flags, a browser page, a Dockerfile and compose.yaml
custom-stackexchange A StackExchange of your own, with StackExchangeInitializer and StackExchangeCloser: an in-process bus joins two servers, Server.Ask crosses them, and a test checks both

08. Load testing

Each program prints counts and timings; run them on a quiet machine.

Wiki: Architecture.

Example Shows
server A server that counts connections and reports leftovers and memory; pick gobwas, gorilla or coder
clients Many short-lived Go clients sending test.data, with an optional cap on open connections
broadcast One process, a thousand clients, Server.Broadcast every two seconds until every message arrived

09. Integrations

Wiki: Authentication.

Example Shows
iris-jwt neffos inside an Iris v14 app: middleware/websocket.New behind the middleware/jwt verifier, the verified user read in events with websocket.GetContext and jwt.Get. Its own module, so the shared examples module stays free of the Iris dependency tree

The JavaScript client

Browsers talk to neffos through neffos.js. The pages in these examples load it from a CDN and use the global neffos:

<script src="https://cdn.jsdelivr.net/npm/neffos.js@0.3/dist/neffos.global.min.js"></script>
<script type="module">
  const conn = await neffos.dial("ws://localhost:8080/ws?name=alice", {
    chat: { Chat: (nsConn, msg) => console.log(msg.text()) },
  }, { reconnect: 2000 });
  const chat = await conn.connect("chat");
  chat.emit("Chat", "hello");
</script>

Browsers cannot set handshake headers, so names and tokens travel as query parameters (?name=, ?token=); the Go servers here read both. With a bundler or TypeScript, import * as neffos from "neffos.js". The neffos.js repository has its own examples for Node.js.

Where to go next

  • The wiki explains the concepts behind these examples; every section above names its pages. Coming from v0.0.x? Read Migrating to v0.1.0.
  • The API reference on pkg.go.dev lists every type and method.
  • Questions and bug reports go to GitHub issues.

Clone this wiki locally