Go MIT

neffos

A modern, fast and scalable websocket framework with elegant API written in Go

K

kataras

Dernière activité 28 mai 2026
kataras/neffos

629

étoiles

52

forks

31

issues ouvertes

gogolangirisneffoswebsocket

Ce README est souvent en anglais.

neffos: real-time framework for Go

neffos chat example

build status report card pkg.go.dev view examples frontend pkg

About neffos

Neffos is a cross-platform real-time framework with an expressive, elegant API written in Go. Neffos eases common tasks needed in real-time backend and frontend applications, such as:

  • Scale-out using redis or nats*, with StackExchangeCloser to release it on shutdown and NSConn.Broadcast for a same-server send
  • Adaptive request upgradation and server dialing
  • Three backends: gorilla, gobwas, coder
  • Acknowledgements
  • Namespaces
  • Rooms
  • Broadcast
  • Event-Driven architecture
  • Request-Response architecture
  • Error Awareness
  • Asynchronous Broadcast
  • Heartbeat, close status codes and a message size limit
  • Graceful shutdown
  • Timeouts
  • Encoding
  • Reconnection (neffos.js)
  • Modern neffos API client for Browsers, Node.js* and Go

Installation

Go 1.27 or later is required.

go get github.com/kataras/neffos@latest

API outline

One Conn per websocket, one NSConn per namespace it connects to, one Room per room it joins. Server and client sides share the same types and methods.

classDiagram
    direction LR

    class Conn {
        ID() string
        IsClient() bool
        Server() *Server
        Connect(ctx, namespace) *NSConn, error
        Namespace(namespace) *NSConn
        Send(Message) error
        Ask(ctx, Message) Message, error
        Set(key, value)
        Value~T~(key) T, bool
        Terminate(code, reason)
        Close()
        Err() error
    }

    class NSConn {
        Conn *Conn
        Send(event, body) error
        SendObject(event, v) error
        Ask(ctx, event, body) Message, error
        AskObject~Reply~(ctx, event, v) Reply, error
        JoinRoom(ctx, name) *Room, error
        Room(name) *Room
        Rooms() []*Room
        Broadcast(msgs...)
        Disconnect(ctx) error
    }

    class Room {
        NSConn *NSConn
        Name string
        Send(event, body) error
        SendObject(event, v) error
        Leave(ctx) error
    }

    class Message {
        Namespace string
        Room string
        Event string
        Body []byte
        Err error
        As~T~() T, error
        Unmarshal(ptr) error
    }

    Conn "1" --> "0..*" NSConn : Connect(namespace)
    NSConn "1" --> "0..*" Room : JoinRoom(name)
    NSConn ..> Message : Send fills Namespace
    Room ..> Message : Send fills Namespace and Room
Loading

Learning neffos

Quick View

Server

import (
    // [...]
    "github.com/kataras/neffos"
    "github.com/kataras/neffos/gorilla"
)

func runServer() {
    events := make(neffos.Namespaces)
    events.On("/v1", "workday", func(ns *neffos.NSConn, msg neffos.Message) error {
        date := string(msg.Body)

        t, err := time.Parse("01-02-2006", date)
        if err != nil {
            // Return the parse error back to the client.
            return err
        }

        if t.Weekday() == time.Saturday || t.Weekday() == time.Sunday {
            // Fire the "notify" client event instead of replying.
            return ns.Send("notify", []byte("day off"))
        }

        // Reply back to the client.
        responseText := fmt.Sprintf("it is %s, do your job.", t.Weekday())
        return neffos.Reply([]byte(responseText))
    })

    // WithTimeout adds a read timeout and a heartbeat on top of the namespaces.
    websocketServer := neffos.New(gorilla.DefaultUpgrader, neffos.WithTimeout{
        ReadTimeout:  60 * time.Second,
        PingInterval: 20 * time.Second,
        Namespaces:   events,
    })

    router := http.NewServeMux()
    router.Handle("/", websocketServer)

    log.Println("Serving websockets on localhost:8080")
    log.Fatal(http.ListenAndServe(":8080", router))
}

Go Client

func runClient() {
    ctx := context.TODO()
    events := make(neffos.Namespaces)
    events.On("/v1", "notify", func(c *neffos.NSConn, msg neffos.Message) error {
        log.Printf("Server says: %s\n", string(msg.Body))
        return nil
    })

    // Connect to the server.
    client, err := neffos.Dial(ctx,
        gorilla.DefaultDialer,
        "ws://localhost:8080",
        events)
    if err != nil {
        panic(err)
    }

    // Connect to a namespace.
    c, err := client.Connect(ctx, "/v1")
    if err != nil {
        panic(err)
    }

    fmt.Println("Please specify a date of format: mm-dd-yyyy")

    for {
        fmt.Print(">> ")
        var date string
        fmt.Scanf("%s", &date)

        // Send to the server and wait for a reply to this message.
        response, err := c.Ask(ctx, "workday", []byte(date))
        if err != nil {
            if neffos.IsCloseError(err) {
                // Check if the error is a close signal,
                // or make use of the `<- client.NotifyClose`
                // read-only channel instead.
                break
            }

            // >> 13-29-2019
            // error received: parsing time "13-29-2019": month out of range
            fmt.Printf("error received: %v\n", err)
            continue
        }

        // >> 06-29-2019
        // it is a day off!
        //
        // >> 06-24-2019
        // it is Monday, do your job.
        fmt.Println(string(response.Body))
    }
}

Browser Client

<script src="https://cdn.jsdelivr.net/npm/neffos.js@0.3/dist/neffos.global.min.js"></script>
<script>(async () => {
  const conn = await neffos.dial("ws://localhost:8080", { "/v1": { notify: (ns, msg) => console.log(msg.Body) } });
  const nsConn = await conn.connect("/v1");
  await nsConn.ask("workday", "06-24-2019");
})();</script>

Javascript Client

Navigate to: https://github.com/kataras/neffos.js

The wiki covers every feature with a page of its own, from the first echo server to scaling out over Redis or NATS.

For detailed technical documentation, head over to pkg.go.dev. For executable code, visit the _examples directory.

What's new

See HISTORY.md for the full changelog. If you are upgrading from a v0.0.x release, read the migration guide on the wiki: Migrating-to-v0.1.0.

Contributing

We'd love to see your contribution to the neffos real-time framework! For more information about contributing to the neffos project please check the CONTRIBUTING.md file.

  • neffos-contrib github organisation for more programming languages support, please invite yourself.

Security Vulnerabilities

If you discover a security vulnerability within neffos, please send an e-mail to neffos-go@outlook.com. All security vulnerabilities will be promptly addressed.

License

The word "neffos" has a greek origin and it is translated to "cloud" in English dictionary.

This project is licensed under the MIT license.

Projets similaires

The fastest HTTP/2 Go Web Framework. New, modern and easy to learn. Fast development with Code you control. Unbeatable cost-performance ratio

Godependency-injectiongogolang
Kkataras
25,6 k étoiles2,4 k

Minimal and idiomatic WebSocket library for Go

Gogohttp2idiomatic
Ccoder
5,5 k étoiles379

A tiny WebSocket library for Go.

Gofastgogolang
Ggobwas
6,5 k étoiles387