All Projects → mroth → sseserver

mroth / sseserver

Licence: AGPL-3.0 license
🏄 High-performance Server-Sent Events endpoint for Go

Programming Languages

go
31211 projects - #10 most used programming language
HTML
75241 projects

Projects that are alternatives of or similar to sseserver

Pulsar Beam
Pulsar Beam is a streaming service via HTTP built on Apache Pulsar.
Stars: ✭ 37 (-57.95%)
Mutual labels:  streaming, sse
Demo Spring Sse
'Server-Sent Events (SSE) in Spring 5 with Web MVC and Web Flux' article and source code.
Stars: ✭ 102 (+15.91%)
Mutual labels:  sse, eventsource
Eventsource
EventSource client for Node.js and Browser (polyfill)
Stars: ✭ 541 (+514.77%)
Mutual labels:  sse, eventsource
Php Sse
A simple and efficient library implemented HTML5's server-sent events by PHP, is used to real-time push events from server to client, and easier than Websocket, instead of AJAX request.
Stars: ✭ 237 (+169.32%)
Mutual labels:  sse, eventsource
Centrifugo
Scalable real-time messaging server in a language-agnostic way. Set up once and forever.
Stars: ✭ 5,649 (+6319.32%)
Mutual labels:  streaming, eventsource
Eventsource
A simple Swift client library for the Server Sent Events (SSE)
Stars: ✭ 241 (+173.86%)
Mutual labels:  sse, eventsource
Unifrost
Making it easier to push pubsub events directly to the browser.
Stars: ✭ 166 (+88.64%)
Mutual labels:  sse, eventsource
Swell
Swell: API development tool that enables developers to test endpoints served over streaming technologies including Server-Sent Events (SSE), WebSockets, HTTP2, GraphQL, and gRPC.
Stars: ✭ 517 (+487.5%)
Mutual labels:  streaming, sse
react-native-sse
Event Source implementation for React Native. Server-Sent Events (SSE) for iOS and Android 🚀
Stars: ✭ 51 (-42.05%)
Mutual labels:  sse, eventsource
SimpleRemoteDesktop
Remote desktop client based on h264 steam. like splashtop and other
Stars: ✭ 17 (-80.68%)
Mutual labels:  streaming
ruby-stream-api
Ruby Stream API. Inspired by Java 8's Stream API.
Stars: ✭ 21 (-76.14%)
Mutual labels:  streaming
live-cryptocurrency-streaming-flutter
A Flutter app with live cryptocurrency updates, powered by Ably
Stars: ✭ 26 (-70.45%)
Mutual labels:  streaming
libdvbtee
dvbtee: a digital television streamer / parser / service information aggregator supporting various interfaces including telnet CLI & http control
Stars: ✭ 65 (-26.14%)
Mutual labels:  streaming
theWorldInSafety
Surveillance System Against Violence
Stars: ✭ 31 (-64.77%)
Mutual labels:  streaming
LazyMan-iOS
A simple app that lets you stream every live and archived NHL and MLB game from any of your iOS devices.
Stars: ✭ 73 (-17.05%)
Mutual labels:  streaming
RTP-Audio-and-Video-for-the-Internet-Chinese-Version
No description or website provided.
Stars: ✭ 30 (-65.91%)
Mutual labels:  streaming
telemetry-streaming
Spark Streaming ETL jobs for Mozilla Telemetry
Stars: ✭ 16 (-81.82%)
Mutual labels:  streaming
sse
HTML5 Server-Sent-Events for Go
Stars: ✭ 84 (-4.55%)
Mutual labels:  sse
fs2-google-pubsub
Google Cloud Pub/Sub stream-based client built on top of cats-effect, fs2 and http4s.
Stars: ✭ 32 (-63.64%)
Mutual labels:  streaming
rtsp-simple-proxy
DEPRECATED - please use https://github.com/aler9/rtsp-simple-server
Stars: ✭ 41 (-53.41%)
Mutual labels:  streaming

sseserver 🏄‍♂️

PkgGoDev Build Status CodeFactor Go Report Card

A high performance and thread-safe Server-Sent Events server for Go with hierarchical namespacing support.

This library has powered the streaming API endpoint for 💫 Emojitracker in production since 2014, where it routinely handles dispatching hundreds of messages per second to thousands of simultaneous clients, on a single Heroku dyno.

Introduction

Hierarchical Namespaced Channels*

A client can subscribe to channels reflecting the content they are interested in. For example, say you are broadcasting events to the namespaces /pets/cats and /pets/dogs. A client could subscribe to the parent channel /pets in the hierarchy and receive all messages for either.

In sseserver, channels have infinite depth and are automatically created on the fly with zero setup -- just broadcast and it works.

(*There's probably a more accurate term for this. If you know it, let me know.)

Performance

Designed for high throughput as primary performance consideration. In my preliminary benchmarking (on v1.0, circa 2014) this can handle ~100K/sec messages broadcast across ~1000 open HTTP connections on a 3.4GHz Intel Core i7 (using a single core, e.g. with GOMAXPROCS=1). There still remains quite a bit of optimization to be done so it should be able to get faster if needed.

SSE vs Websockets

SSE is the oft-overlooked uni-directional cousin of websockets. Being "just HTTP" it has some benefits:

  • Trvially easier to understand, plaintext format. Can be debugged by a human with curl.
  • Supported in most major browsers for a long time now. Everything except IE/Edge, but an easy polyfill!
  • Built-in standard support for automatic reconnection, event binding, etc.
  • Works with HTTP/2.

See also Smashing Magazine: "Using SSE Instead Of WebSockets For Unidirectional Data Flow Over HTTP/2".

Documentation

GoDoc

Namespaces are URLs

For clients, no need to think about protocol. To subscribe to one of the above namespaces from the previous example, just connect to http://$SERVER/pets/dogs. Done.

Example Usage

A simple Go program utilizing this package:

package main

import (
    "time"
    "github.com/mroth/sseserver"
)

func main() {
    s := sseserver.NewServer() // create a new server instance

    // broadcast the time every second to the "/time" namespace
    go func() {
        ticker := time.Tick(time.Duration(1 * time.Second))
        for {
            // wait for the ticker to fire
            t := <-ticker
            // create the message payload, can be any []byte value
            data := []byte(t.Format("3:04:05 pm (MST)"))
            // send a message without an event on the "/time" namespace
            s.Broadcast <- sseserver.SSEMessage{"", data, "/time"}
        }
    }()

    // simulate sending some scoped events on the "/pets" namespace
    go func() {
        time.Sleep(5 * time.Second)
        s.Broadcast <- sseserver.SSEMessage{"new-dog", []byte("Corgi"), "/pets/dogs"}
        s.Broadcast <- sseserver.SSEMessage{"new-cat", []byte("Persian"), "/pets/cats"}
        time.Sleep(1 * time.Second)
        s.Broadcast <- sseserver.SSEMessage{"new-dog", []byte("Terrier"), "/pets/dogs"}
        s.Broadcast <- sseserver.SSEMessage{"new-dog", []byte("Dauchsand"), "/pets/cats"}
        time.Sleep(2 * time.Second)
        s.Broadcast <- sseserver.SSEMessage{"new-cat", []byte("LOLcat"), "/pets/cats"}
    }()

    s.Serve(":8001") // bind to port and begin serving connections
}

All these event namespaces are exposed via HTTP endpoint in the /subscribe/:namespace route.

On the client, we can easily connect to those endpoints using built-in functions in JS:

// connect to an event source endpoint and print results
var es1 = new EventSource("http://localhost:8001/subscribe/time");
es1.onmessage = function(event) {
    console.log("TICK! The time is currently: " + event.data);
};

// connect to a different event source endpoint and register event handlers
// note that by subscribing to the "parent" namespace, we get all events
// contained within the pets hierarchy.
var es2 = new EventSource("http://localhost:8001/subscribe/pets")
es2.addEventListener("new-dog", function(event) {
    console.log("WOOF! Hello " + event.data);
}, false);

es2.addEventListener("new-cat", function(event) {
    console.log("MEOW! Hello " + event.data);
}, false);

Which when connecting to the server would yield results:

TICK! The time is currently: 6:07:17 pm (EDT)
TICK! The time is currently: 6:07:18 pm (EDT)
TICK! The time is currently: 6:07:19 pm (EDT)
TICK! The time is currently: 6:07:20 pm (EDT)
WOOF! Hello Corgi
MEOW! Hello Persian
TICK! The time is currently: 6:07:21 pm (EDT)
WOOF! Hello Terrier
WOOF! Hello Dauchsand
TICK! The time is currently: 6:07:22 pm (EDT)
TICK! The time is currently: 6:07:23 pm (EDT)
MEOW! Hello LOLcat
TICK! The time is currently: 6:07:24 pm (EDT)

Of course you could easily send JSON objects in the data payload instead, and most likely will be doing this often.

Another advantage of the SSE protocol is that the wire-format is so simple. Unlike WebSockets, we can connect with curl to an endpoint directly and just read what's going on:

$ curl http://localhost:8001/subscribe/pets
event:new-dog
data:Corgi

event:new-cat
data:Persian

event:new-dog
data:Terrier

event:new-dog
data:Dauchsand

event:new-cat
data:LOLcat

Yep, it's that simple.

Keep-Alives

All connections will send periodic :keepalive messages as recommended in the WHATWG spec (by default, every 15 seconds). Any library adhering to the EventSource standard should already automatically ignore and filter out these messages for you.

Admin Page

By default, an admin status page is available for easy monitoring.

screenshot

It's powered by a simple JSON API endpoint, which you can also use to build your own reporting. These endpoints can be disabled in the settings (see Server.Options).

HTTP Middleware

sseserver.Server implements the standard Go http.Handler interface, so you can easily integrate it with most existing HTTP middleware, and easily plug it into whatever you are using for your current routing, etc.

License

AGPL-3.0. Dual commercial licensing available upon request.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].