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
- Live Feeds, retrieve feeds data in real time.
- Events, retrieve data when specific event was triggered.
- 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))
}
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.
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
Send event response after triggered
Left event endpoint trigger
curl http://localhost:8080/left
Left event response after triggered
Right event endpoint trigger
curl http://localhost:8080/right
Right event response after triggered
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!