Go - WebSockets & SSE
          Beginner 10/10
          Teacher 10/10
          Architect 10/10
        
        
        
        
WebSockets & Server-Sent Events (SSE)
Use WebSockets for bidirectional real-time messaging and SSE for unidirectional server-to-client streams.
Try it: Implement SSE that sends a timestamp every second.
SSE with net/http
package main
import (
  "fmt"
  "net/http"
  "time"
)
func sse(w http.ResponseWriter, r *http.Request){
  w.Header().Set("Content-Type", "text/event-stream")
  w.Header().Set("Cache-Control", "no-cache")
  w.Header().Set("Connection", "keep-alive")
  fl, _ := w.(http.Flusher)
  ticker := time.NewTicker(time.Second)
  defer ticker.Stop()
  for i:=0; i<5; i++ { // demo
    <-ticker.C
    fmt.Fprintf(w, "data: %s\n\n", time.Now().Format(time.RFC3339))
    if fl != nil { fl.Flush() }
  }
}
func main(){
  http.HandleFunc("/events", sse)
  http.ListenAndServe(":8080", nil)
}
WebSocket (concept)
You can implement WebSockets using a library (e.g., gorilla/websocket) or manually via net/http hijacking. Libraries handle frames and close semantics.
// Pseudocode with gorilla/websocket
// var upgrader = websocket.Upgrader{}
// func ws(w http.ResponseWriter, r *http.Request){
//   c, _ := upgrader.Upgrade(w, r, nil)
//   defer c.Close()
//   for {
//     _, msg, err := c.ReadMessage(); if err != nil { break }
//     c.WriteMessage(websocket.TextMessage, append([]byte("echo: "), msg...))
//   }
// }
Common errors
- Forgetting to flush SSE responses.
- Not handling client disconnects (browser closed) and breaking out of loops.
- Missing CORS/CSRF considerations on WebSocket endpoints.
Practice
- Add a retryfield in SSE and test reconnect behavior in the browser.
- Implement a ping/pong heartbeat for WebSockets.
Quick quiz
- When would you choose SSE over WebSockets?