aria – Event Driven websocket framework

What is Aria?

Aria is a lightweight, event-driven WebSocket framework for Go.

It is inspired by olahol/melody and built on top of coder/websocket.

The goal of Aria is to make building real-time applications — like chat servers, dashboards, or multiplayer games — simple, reliable, and easy to extend, without sacrificing performance.

Motivation

I’ve used gorilla/websocket for years, but as many know, its maintenance has slowed down (which makes sense since it’s a very mature library).
At the same time, I often found myself rewriting the same boilerplate: handling events like OnConnect/OnClose, broadcasting to multiple clients, and cleaning up dead connections.

Aria was created to solve that pain point:

  • Event hooks for connection lifecycle and messages
  • Built-in broadcast and broadcast filtering
  • Graceful connection cleanup
  • Context-aware handlers

Getting Started

Installation

go get github.com/n9te9/aria

Implemantation (Simple chat)

Create static/index.html:

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <title>Aria Chat</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    #messages { border: 1px solid #ccc; padding: 10px; height: 200px; overflow-y: auto; }
    #input { margin-top: 10px; width: 80%; }
    #send { width: 15%; }
  </style>
</head>
<body>
  <h1>Aria Chat</h1>
  <div id="messages"></div>
  <input id="input" type="text" placeholder="write message..." />
  <button id="send">送信</button>

  <script>
    const ws = new WebSocket("ws://localhost:8080/ws");
    const messages = document.getElementById("messages");
    const input = document.getElementById("input");
    const send = document.getElementById("send");

    ws.onmessage = (event) => {
      const div = document.createElement("div");
      div.textContent = event.data;
      messages.appendChild(div);
      messages.scrollTop = messages.scrollHeight;
    };

    send.onclick = () => {
      if (input.value) {
        ws.send(input.value);
        input.value = "";
      }
    };

    input.addEventListener("keypress", (e) => {
      if (e.key === "Enter") send.onclick();
    });
  </script>
</body>
</html>

Then create main.go:

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"

    "github.com/coder/websocket"
    "github.com/n9te9/aria"
)

func main() {
    a := aria.New()

    a.OnConnect(func(ctx context.Context, conn *aria.Conn) error {
        log.Println("new connection")
        return nil
    })

    a.OnMessage(func(ctx context.Context, conn *aria.Conn, message []byte) error {
        log.Printf("received: %sn", string(message))
        return a.BroadCast(ctx, message)
    })

    a.OnError(func(ctx context.Context, conn *aria.Conn, err error) {
        log.Println("error:", err)
    })

    http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
        if err := a.Handle(w, r); err != nil {
            log.Println("handle error:", err)
        }
    })

    http.Handle("/", http.FileServer(http.Dir("./static")))

    fmt.Println("server started at http://localhost:8080")
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }
}

Now run:

go run main.go

Access http://localhost:8080 in your browser, and you’ll have a simple chat app running on top of Aria!

Contribution

Contributions are welcome!
Please open an issue or PR on GitHub if you have ideas, feedback, or improvements.

Leave a Reply