Server-Sent Event: One Directed Data Transmission Server to Client

Nightsilver Academy - May 5 - - Dev Community

Preamble

SSE is unidirectional data transfer mechanism from the server to the client, that you need to perform GET request with Content-Type as text/event-stream, for tells the server you need to established server event channel and the server will keeps send you data changes, when you trigger an event.


Use Cases

  1. Live Feeds, retrieve feeds data in real time.
  2. Events, retrieve data when specific event was triggered.
  3. Polling, retrieve data when there is a change.

Why not using WebSocket?

If you need bidirectional communication you can use websocket, even websocket can be used for unidirectional, but SSE is much simpler for communication with one direction (unidirectional).


Make SSE Server with Go

You can just copy this code into main.go for start learning how SSE works, after that you can read the code.

package main

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

// data variable
var messageChan chan string

func prepareHeaderForSSE(w http.ResponseWriter) {
    // prepare the header
    w.Header().Set("Content-Type", "text/event-stream")
    w.Header().Set("Cache-Control", "no-cache")
    w.Header().Set("Connection", "keep-alive")
    w.Header().Set("Access-Control-Allow-Origin", "*")
}

func writeData(w http.ResponseWriter) (int, error) {
    // set data into response writer
    return fmt.Fprintf(w, "data: %s\n\n", <-messageChan)
}

func sseStream() http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // call prepareHeaderForSSE for start endpoint as SSE server
        prepareHeaderForSSE(w)

        // initialize messageChan
        messageChan = make(chan string)

        // calling anonymous function that
        // closing messageChan channel and
        // set it to nil
        defer func() {
            close(messageChan)
            messageChan = nil
        }()

        // create http http.Flusher that allows
        // http handler to flush buffered data to
        // client until closed
        flusher, _ := w.(http.Flusher)
        for {
            write, err := writeData(w)
            if err != nil {
                log.Println(err)
            }
            log.Println(write)
            flusher.Flush()
        }
    }
}


// sendMessage used to write data into messageChan and flushed to client through sseStream
func sseMessage(message string) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        if messageChan != nil {
            messageChan <- message
        }
    }
}

func main() {
    http.HandleFunc("/stream", sseStream())
    http.HandleFunc("/send", sseMessage("you can put json in here as the data"))
    http.HandleFunc("/right", sseMessage("right"))
    http.HandleFunc("/left", sseMessage("left"))
    log.Fatal("HTTP server error: ", http.ListenAndServe("localhost:8080", nil))
}
Enter fullscreen mode Exit fullscreen mode

Once the server successfully running, you can test it via google chrome that will pretend like client side, and listen for data through stream endpoint that we have configured as SSE stream.


Using Google Chrome console for client

We use google chrome console, because its more representing server and client, (SSE) acting as the server & (google chrome console) acting as the client. you can start with this JavaScript code.

JavaScript code for SSE Client in google chrome console

After that you can test sending data with /send, /left, /right endpoint, for seeing data will be printed using console.log.

Using cURL for Trigger the Event

Send event endpoint trigger

curl http://localhost:8080/send
Enter fullscreen mode Exit fullscreen mode

Send event response after triggered

Send event response in Google Chrome Console

Left event endpoint trigger

curl http://localhost:8080/left
Enter fullscreen mode Exit fullscreen mode

Left event response after triggered

Left event response in Google Chrome Console

Right event endpoint trigger

curl http://localhost:8080/right
Enter fullscreen mode Exit fullscreen mode

Right event response after triggered

Right event response in Google Chrome Console


Conclusion

As you can see the value of data that google chrome console received from /stream endpoint is different every time we call 3 different endpoints, you can do the same like google chrome console does inside React.js framework using axios, or other programming language. And SSE server is only can handle one client and cannot be more, because the purpose of SSE is just to send data depends on event endpoints that we trigger through http request.


My Thanks

Thank you for visiting! This article was originally published on another website. You can find the original source here. I'm excited to bring it over here. I hope you found it useful and enjoyable. Don't hesitate to reach out if you have any questions or feedback. Happy reading!

. . . . . . .