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

  • By Damon P. Cortesi
  • Last update: Nov 28, 2022
  • Comments: 1

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 @mroth's How I Built Emojitracker and have been intrigued ever since.

However, it wasn't until I came across @benbjohnson's litestream-read-replica-demo that I realized just how easy they were to use. I thought there was all sorts of complexity, but no!

It's really simple...all you need to do is create a new EventSource in your JavaScript and feed it updates!

var sse = new EventSource("/api/stream");
sse.addEventListener("update", function (e) {
  // Do something!
});

Demo

This repo shows how to use Go to send events to the browser and, of course, draw a real-time chart with Plotly. :)

git clone https://github.com/dacort/golang-sse-demo.git
cd golang-sse-demo
go run *.go

Then browse to http://localhost:3000

💥

Screenshot

Download

golang-sse-demo.zip

Comments(1)

  • 1

    Setting channel is racy

    			notify.mu.Lock()
    			notify.value = rand.Intn(100)
    			notify.mu.Unlock()
    
    			// notify.ch <- struct{}{}
    			close(notify.ch)
    			notify.ch = make(chan struct{})
    

    notify.ch = make(chan struct{}) is not in a lock, so it could race that someone reads it in the middle of a write.

    I think it would be simpler if you had something like:

    type broadcaster struct{ 
      value int
      notifier chan struct{} 
    }
    
    // in main 
    for {
      lock.Lock()
      notify = broadcaster { notifier: make(chan struct{}) }  
      lock.Unlock()
      time.Sleep()
      notify.value = math.Rand()
      close(notify.notifier)
    }
    
    // in the handler
    lock.RLock()
    localnotify := notify
    lock.RUnlock()
    <- localnotify.notifier
    send(localnotify.value)