Skip to content

Simple Server Sent Events Library in Go (inspired by Melody)

License

Notifications You must be signed in to change notification settings

christopher-kleine/sse

Repository files navigation

SSE - Melody inspired Server Sent Events Library

go.dev Reference Test Status

Synopsis

A small library providing easy SSE functionality. The API is inspired by the great WebSocket library melody.

Note: This library is mainly for my own use and didn't account for other use-cases. If you need something more stable or a more mature library, check r3labs/sse. Same goes for if you want a SSE Client library. But please feel free to tear the source and I'm open for PRs.

Table of Contents

Features

  • Zero dependencies
  • melody inspired
  • HTML/HTMX
  • Compatible with standard mux handlers

Install

go get github.com/christopher-kleine/sse@latest

How to use it

package main

import (
	"net/http"

	"github.com/christopher-kleine/sse"
)

func main() {
	// Create a new Hub
	hub := sse.New()

	// (Optional): Specify OnConnect and OnDisconnect hooks
	hub.OnConnect = func(session *sse.Session) {}
	hub.OnDisconnect = func(session *sse.Session) {}

	// Specify the endpoint
	http.Handle("/sse", hub)

	// (Optional): Customize the request
	/*
	http.HandleFunc("/sse", func(w http.Response, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "*")
		hub.ServeHTTP(w, r)
	})
	*/

	// Publish some data!
	go func() {
		for {
			hub.Publish(&sse.Event{ Data: "Hello World" })
			time.Sleep(1 * time.Second)
		}
	}()

	http.ListenAndServe(":8080", nil)
}

Filtered/Selected Publish

You can also publish to selected sessions.

// Only sent to users we gave the "villain" role.
ev := &sse.Event{Data: "Hello, Villain. What are your next plans?"}
hub.FilteredPublish(ev, func(session *sse.Session) bool {
	return session.Get("role") == "villain"
})

HTML/HTMX Templates

You can use this library to send HTML templates over SSE, since the Event type implements the io.Writer Interface:

ev := &sse.Event{}
templates.ExecuteTemplate(ev, "index.html", nil)
hub.Publish(ev)

Using Gin

The popular web framework Gin can be used too:

package main

import (
	"net/http"
	"time"

	"github.com/christopher-kleine/sse"
	"github.com/gin-gonic/gin"
)

func main() {
	hub := sse.New()

	go func() {
		hub.Publish(&sse.Event{ Data: "ping" })
		time.Sleep(2 * time.Second)
	}()

	r := gin.Default()
	r.GET("/sse", func(c *gin.Context) {
		hub.ServeHTTP(c.Writer, c.Request)
	})
	r.Run()
}