0

I'm trying to make console using sse that shows client what server is doing. Currently it does what I want except it has a delay (about 2sec). I added http.Flusher but is seems to do absolutely nothing. I call UpdateLogMessage using goroutines: go UpdateLogMessage("Example")

SSE:

type Upl struct {
    log string
}

var Log chan *Upl

func DashboardHandler(w http.ResponseWriter, r *http.Request) {
    f, ok := w.(http.Flusher)
    if !ok {
        fmt.Println("Streaming unsuported")
    }

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

    msg := <-Log
    fmt.Fprintf(w, "data: %v\n\n", msg.log)
    f.Flush()
}

//Updates log message with curent time and message content
func UpdateLogMessage(msg string) {
    curentTime := time.Now().Format("15:04:05")
    ul := fmt.Sprintf("<%v> %v", curentTime, msg)
    up := &Upl{
        log: ul,
    }
    Log <- up
}

func MakeChan() {
    Log = make(chan *Upl)
}

Javascript:

function onLoaded(){
    var source = new EventSource("sse/dashboard")
    var logg = "";
    var currentmsg = "";

    source.onmessage = function (event){
        var dashboard = event.data;
        //If message changed print it to console
        if (dashboard != currentmsg){
            console.log("OnMessage called:");
            console.dir(event);
            currentmsg = dashboard;
            logg += currentmsg + "<br/>";
            console.log(logg);
            document.getElementById("console").innerHTML = logg;
        }
    }
}
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
batijo
  • 41
  • 1
  • 8
  • 2
    The code you posted does not explain any delay, but this is not how SSE is used (or should be used). You return from the handler once sending back the first message. Usually SSE handlers have a loop to keep sending back updates to the client. Also the way you receive from the `Log` channel is dangerous, if multiple clients connect to the SSE endpoint, they will race who get the message, and you don't handle context cancellation. – icza Mar 13 '19 at 14:04
  • And if there is no client listening, you will leak goroutines with `go UpdateLogMessage("Example")`, as that won't be able to send on the channel and thus hang forever. Check out this example: [Why is Golang http.ResponseWriter execution being delayed?](https://stackoverflow.com/questions/48267616/why-is-golang-http-responsewriter-execution-being-delayed/48270817#48270817) – icza Mar 13 '19 at 14:04
  • Thanks! Delay probably happened because with every message I returned from handler as you said. I now changed that by adding loop so it should work fine, but since I use upload form when I start to upload file HTTP connection closes and I get 0 messages during uploading. I probably need to use Ajax for file upload to make it work properly. – batijo Mar 14 '19 at 12:43

0 Answers0