Fiber: 馃 Server Sent Events

Created on 19 Jul 2020  路  2Comments  路  Source: gofiber/fiber

Question description

Would providing sse as a Middleware -or any plugin type - be a good idea for fiber?. I think it would be useful for some cases covered by websocket are a lot complicated and resource consumption

馃 Question

Most helpful comment

Hi @bashery, sorry for the late reply! I personally never worked with SSE, but we are willing to add this to our middleware list if you made one 馃憤

I'm closing this issue, for now, feel free to re-open if you have suggestions/questions or any updates regarding this matter 馃憣

All 2 comments

Hi @bashery, sorry for the late reply! I personally never worked with SSE, but we are willing to add this to our middleware list if you made one 馃憤

I'm closing this issue, for now, feel free to re-open if you have suggestions/questions or any updates regarding this matter 馃憣

This issue is close, but I can use fiber and Server-Sent Events using a gofiber/adaptor

Example:

//main.go
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "github.com/gofiber/adaptor/v2"
    "github.com/gofiber/fiber/v2"
    "math/rand"
    "net/http"
    "time"
)

type (
    Client struct {
        name   string
        events chan *DashBoard
    }
    DashBoard struct {
        User uint
    }
)

func main() {
    app := fiber.New()
    app.Get("/sse/validation", adaptor.HTTPHandler(handler(dashbaordHandler)))
    app.Listen(":3000")
}

func handler(f http.HandlerFunc) http.Handler {
    return http.HandlerFunc(f)
}
func dashbaordHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Println("Client: %v", r.RemoteAddr)
    client := &Client{name: r.RemoteAddr, events: make(chan *DashBoard, 10)}
    go updateDashboard(client)

    w.Header().Set("Access-Control-Allow-Origin", "*")
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    w.Header().Set("Content-Type", "text/event-stream")
    w.Header().Set("Cache-Control", "no-cache")
    w.Header().Set("Connection", "keep-alive")

    timeout := time.After(1 * time.Second)
    select {
    case ev := <-client.events:
        var buf bytes.Buffer
        enc := json.NewEncoder(&buf)
        enc.Encode(ev)
        fmt.Fprintf(w, "data: %v\n\n", buf.String())
        fmt.Printf("data: %v\n", buf.String())
    case <-timeout:
        fmt.Fprintf(w, ": nothing to sent\n\n")
    }

    if f, ok := w.(http.Flusher); ok {
        f.Flush()
    }
}

func updateDashboard(client *Client) {
    for {
        db := &DashBoard{
            User:         uint(rand.Uint32()),
        }
        client.events <- db
    }
}

call this function in you HTML page

//js file
export default function onLoad() {
    var source = new EventSource("http://localhost:3000/sse/validation")
    source.onmessage = (event) => {
        console.log("OnMessage Called:")
        console.log(event)
        console.log(JSON.parse(event.data))
    }
}
Was this page helpful?
0 / 5 - 0 ratings