Server-sent events for Go

eventsource

Build Status

eventsource provides server-sent events for net/http server.

Usage

SSE with default options

package main

import (
    "gopkg.in/antage/eventsource.v1"
    "log"
    "net/http"
    "strconv"
    "time"
)

func main() {
    es := eventsource.New(nil, nil)
    defer es.Close()
    http.Handle("/events", es)
    go func() {
        id := 1
        for {
            es.SendEventMessage("tick", "tick-event", strconv.Itoa(id))
            id++
            time.Sleep(2 * time.Second)
        }
    }()
    log.Fatal(http.ListenAndServe(":8080", nil))
}

SSE with custom options

package main

import (
    "gopkg.in/antage/eventsource.v1"
    "log"
    "net/http"
    "strconv"
    "time"
)

func main() {
    es := eventsource.New(
        &eventsource.Settings{
            Timeout: 5 * time.Second,
            CloseOnTimeout: false,
            IdleTimeout: 30 * time.Minute,
        }, nil)
    es.SendRetryMessage(3 * time.Second)
    defer es.Close()
    http.Handle("/events", es)
    go func() {
        id := 1
        for {
            es.SendEventMessage("tick", "tick-event", strconv.Itoa(id))
            id++
            time.Sleep(2 * time.Second)
        }
    }()
    log.Fatal(http.ListenAndServe(":8080", nil))
}

SSE with custom HTTP headers

package main

import (
    "gopkg.in/antage/eventsource.v1"
    "log"
    "net/http"
    "strconv"
    "time"
)

func main() {
    es := eventsource.New(
        eventsource.DefaultSettings(),
        func(req *http.Request) [][]byte {
            return [][]byte{
                []byte("X-Accel-Buffering: no"),
                []byte("Access-Control-Allow-Origin: *"),
            }
        },
    )
    defer es.Close()
    http.Handle("/events", es)
    go func() {
        id := 1
        for {
            es.SendEventMessage("tick", "tick-event", strconv.Itoa(id))
            id++
            time.Sleep(2 * time.Second)
        }
    }()
    log.Fatal(http.ListenAndServe(":8080", nil))
}
Comments
  • Set write deadline to zero

    Set write deadline to zero

    If the HTTP server has been created with a write timeout, the hijacked connection will have a write deadline set. Since eventsource has no timeouts of its own, it never resets the deadline and writes to the connection will eventually fail.

    In Go 1.0.3, this is not an issue because of a bug that prevents the correct checking of the deadline, but revision 14943, which will be part of Go 1.1, fixes this.

  • Detect and close dead client connections

    Detect and close dead client connections

    Previously, consumers were never being removed from the event source since the range over consumer.in would block. This uses a select statement and an arbitrary 5min timeout to close connections if they have been inactive and remove them from the event source.

  • Simultaneously closing two more connections causes the event source to quit responsing

    Simultaneously closing two more connections causes the event source to quit responsing

    I think the problem is related to the stall code, but what do I know. I am just learning a bit of Go.

    This will be a really handy library if I can get past the connection closing problem.

  • Getting net::ERR_INCOMPLETE_CHUNKED_ENCODING error on a client

    Getting net::ERR_INCOMPLETE_CHUNKED_ENCODING error on a client

    Hello, During streaming on a client side, I'm continuously getting an error, which drops connection with a server.

    GET /stream net::ERR_INCOMPLETE_CHUNKED_ENCODING
    

    Can you please advice, what could be a problem? Thanks.

  • Do not close any channels to avoid racy

    Do not close any channels to avoid racy "send on closed channel" panics

    Example panic, happened after the eventsource was closed:

    panic: runtime error: send on closed channel
    
    goroutine 147858 [running]:
    runtime.panic(0x465000, 0x77641e)
        /usr/local/Cellar/go/1.3.1/libexec/src/pkg/runtime/panic.c:279 +0xf5
    github.com/sporttech/eventsource.func·001()
        /Users/mrbrbr/dev/go/src/github.com/sporttech/eventsource/consumer.go:73 +0x384
    

    There is no need to close any channels — it does not impact the GC, but is only a signal to receivers that no data will be following (see here).

    As nothing in this package listens to close() of any channel, simply removing all close() calls both simplifies the code and avoids unexpected panic()s.

  • Do not close channels to avoid racy

    Do not close channels to avoid racy "send on closed channel" panics

    Example panic, happened after the eventsource was closed:

    panic: runtime error: send on closed channel
    
    goroutine 147858 [running]:
    runtime.panic(0x465000, 0x77641e)
        /usr/local/Cellar/go/1.3.1/libexec/src/pkg/runtime/panic.c:279 +0xf5
    github.com/sporttech/eventsource.func·001()
        /Users/mrbrbr/dev/go/src/github.com/sporttech/eventsource/consumer.go:73 +0x384
    

    There is no need to close channels except .in — it does not impact the GC, but is only a signal to receivers that no data will be following (see here).

    As nothing in this package listens to close() of any channel except .in, simply removing close() calls both simplifies the code and avoids unexpected panic()s.

  • What is the best way to separate consumers?

    What is the best way to separate consumers?

    Hi,

    If I got multiple consumers with "private" channels*, should I create a new EventSource instance for each one or is there an internal way to handle this?

    • I.e. that I want to send separate messages to each consumer.
  • How do I handle disconnecting consumers manually?

    How do I handle disconnecting consumers manually?

    I'm not seeing a good mechanism here to disconnect a consumer manually.

    My use-case is this: a client will make a POST /some-route which kicks off a back-end service and allows other clients to watch for SSE on GET /events and I'm simply forwarding all output from the back-end service to the clients via es.SendMessage. I would like to close the SSE connections on those clients when the back-end service is finished.

    Do you have any ideas? Thanks!

  • Add go.mod

    Add go.mod

    This adds a go.mod file to the repo, making it more compliant with Go modules. Things are compiling fine without it, but the missing go.mod does confuse some Go tooling into thinking it's not a library.

  • Disable Gzip by default

    Disable Gzip by default

    Golang's Gzip implementation will allocate a ~1MB buffer per connection. This really adds up when you have more than a thousand consumers listening for events. I think it would be best to turn off Gzip to save some memory.

    Here are some heap profiles taken from an eventsource program with about 30 consumers to illustrate the problem: With compression Without compression

    Having Gzip enabled for will probably not be beneficial in most cases since the sent messages are very short anyway. If people really need compression when sending large messages they can just re-enable it via the config.

  • Buffering delays?

    Buffering delays?

    Have you ever experienced an issue when the 200 OK + Content-Type is buffered up on non-local connections and are sent when there's enough data in the pipe or when some timeout is reached? I see this behaviour when I connect to my local dev server through ngrok.com proxy, and, what is much worse, it looks like such responses are immediately halted by Amazon ELBs (or at least this is how I currently interpret the fact that these requests are immediatelly marked as "cancelled" by Chrome)

  • How to detect client disconnection ?

    How to detect client disconnection ?

    Hello, I'm developping chat rooms based on Twitter hashtag with Server sent events. I have a problem concerning the disconnection of the client. I run a goroutine to send messages to the client, but when the client disconnects, the goroutine still runs. I don't know how to detect on the server side that the client is disconnected. You can find a part of my code here : https://gist.github.com/Guiguillermo/f214fbda9aacec1ea5d9

    Thanks !

Fibonacci RESTful API - HTTP server that listens on a given port

Fibonacci RESTful API - HTTP server that listens on a given port

Jan 19, 2022
Fully featured, spec-compliant HTML5 server-sent events library

go-sse Lightweight, fully spec-compliant HTML5 server-sent events library. Table of contents go-sse Table of contents Installation and usage Implement

Dec 5, 2022
A brief demo of real-time plotting with Plotly, Go, and server-sent events
A brief demo of real-time plotting with Plotly, Go, and server-sent events

Golang SSE Demo A brief demo of real-time plotting with Plotly, Go, and server-side events. Overview I first learned about Server-Sent Events from @mr

Nov 28, 2022
This POC is built with the goal to collect events/logs from the host systems such as Kubernetes, Docker, VMs, etc. A buffering layer is added to buffer events from the collector
This POC is built with the goal to collect events/logs from the host systems such as Kubernetes, Docker, VMs, etc. A buffering layer is added to buffer events from the collector

What is does This POC is build with the goal to collect events/logs from the host systems such as Kubernetes, docker, VMs etc. A buffering layer is ad

Nov 11, 2022
Server-sent live updates: protocol and reference implementation
Server-sent live updates: protocol and reference implementation

Protocol and Reference Implementation Mercure is a protocol allowing to push data updates to web browsers and other HTTP clients in a convenient, fast

Jan 1, 2023
A tool to sent comments to Issues or Pull Requests in Github from CI tools.

CommentCI A tool to sent comments to Issues or Pull Requests in Github from CI tools. Usage Required environment variables: GITHUB_COMMENT_USER - User

Apr 10, 2022
🤖 Chegg answers requested and sent by the Discord BOT to the targeted user.
🤖 Chegg answers requested and sent by the Discord BOT to the targeted user.

"I believe that open-source resources are a must for everyone around. Especially in the field of education. As Chegg costs some money monthly, unfortunately, not all of us are capable of to charge ourselves that cost, which ends up blocking all those valuable resources to us. That is why, I have developed this bot, which unblurs the blurred question answers and sends them to you. I will develop it to a next level in the upcoming days, whereas, it will send the images/text, answers in short, directly through the Discord server you are in, or just DM/PM."

Aug 20, 2021
a simple api that sent spam via sms and email

a simple api that sent spam via sms and email routes: /sms /email example request with python

Oct 19, 2021
Send email and SMS broadcasts to your contacts. SMS are sent via your Android phone connected to your PC.

Polysender Send email and SMS broadcasts to your contacts. Polysender is a desktop application, so it does not require a complicated server setup. Ema

Aug 11, 2022
Extract sent emojis from your Discord messages, and download them
Extract sent emojis from your Discord messages, and download them

discord-emoji-extractor Download all the emojis you've ever sent inside messages on Discord. Supports skipping duplicates and resuming downloads. Usag

Nov 7, 2022
HTTP server receives events and publishes them to STAN
HTTP server receives events and publishes them to STAN

Publishes events to Nats Streaming(STAN) synchornously and asynchronously. Cache events's publish-state using Redis and Store events using MongoDB.

Dec 30, 2022
Scalable datastore for metrics, events, and real-time analytics

InfluxDB InfluxDB is an open source time series platform. This includes APIs for storing and querying data, processing it in the background for ETL or

Jan 5, 2023
Golang client library for adding support for interacting and monitoring Celery workers, tasks and events.

Celeriac Golang client library for adding support for interacting and monitoring Celery workers and tasks. It provides functionality to place tasks on

Oct 28, 2022
Emits events in Go way, with wildcard, predicates, cancellation possibilities and many other good wins

Emitter The emitter package implements a channel-based pubsub pattern. The design goals are to use Golang concurrency model instead of flat callbacks

Jan 4, 2023
Go cross-platform glfw library for creating an OpenGL context and receiving events.

glfw Package glfw experimentally provides a glfw-like API with desktop (via glfw) and browser (via HTML5 canvas) backends. It is used for creating a G

Sep 27, 2022
Stream database events from PostgreSQL to Kafka

PSQL-Streamer This service receives the database events from PostgreSQL using logical replication protocol and feeds them to sinks based on the config

Dec 20, 2022
A Go REST API allowing me to send messages to myself, on my phone, according to some events.
A Go REST API allowing me to send messages to myself, on my phone, according to some events.

go-telegram-notifier go-telegram-notifier A Go REST API wrapping the official Telegram API and used to send myself notifications, on my phone, based o

Apr 27, 2022
Scalable datastore for metrics, events, and real-time analytics

InfluxDB InfluxDB is an open source time series platform. This includes APIs for storing and querying data, processing it in the background for ETL or

Jan 4, 2023
Pixie gives you instant visibility by giving access to metrics, events, traces and logs without changing code.
Pixie gives you instant visibility by giving access to metrics, events, traces and logs without changing code.

Pixie gives you instant visibility by giving access to metrics, events, traces and logs without changing code.

Jan 4, 2023
Generate QR-Codes for checking into events using the official Corona Warn App.

Corona Warn App QR-Code Generator Generate QR-Codes for checking into events using the official Corona Warn App. Table of Contents Introduction Instal

Oct 5, 2022