简体   繁体   English

为什么这个 SSE 处理程序会导致客户端连接卡在待处理状态?

[英]Why does this SSE handler cause the client connection to be stuck in pending?

In this example, https://github.com/kljensen/golang-html5-sse-example/blob/d4eba81ddea2b4191f039adb6929086ca6b39c0f/server.go#L130 , you can block on a channel.在这个例子中, https://github.com/kljensen/golang-html5-sse-example/blob/d4eba81ddea2b4191f039adb6929086ca6b39c0f/server.go#L130 ,你可以在一个频道上屏蔽。 But doing that in my HandleExecute results in the browser/client connection status to remain stuck in a pending state and nothing gets sent to the client.但是在我的HandleExecute这样做会导致浏览器/客户端连接状态保持在挂起状态,并且没有任何内容发送到客户端。

If I remove the for loop and use a select statement with a default case writing back no data, then it works ( execute writes and flushes data) except that the handler returns and the client re-connects every 5 seconds instead of maintaining the connection.如果我删除 for 循环并使用带有默认情况下不回写数据的 select 语句,那么它可以工作( execute写入和刷新数据),除了处理程序返回并且客户端每 5 秒重新连接而不是维护连接。 When I do it that way, the client gets streamed data only on the reconnect intervals.当我这样做时,客户端仅在重新连接间隔内获取流数据。

So users end up seeing a delay lasting anywhere less than 5 seconds depending on when HandleExecuteRequest gets hit.因此,根据HandleExecuteRequest何时被击中,用户最终会看到持续不到 5 秒的延迟。 HandleExecute could be ready to write but the client may not have reconnected yet. HandleExecute可能已准备好写入,但客户端可能尚未重新连接。 I hope that makes sense.我希望这是有道理的。

How can I write these handlers to maintain a constant connection instead of reconnecting?我如何编写这些处理程序来保持持续连接而不是重新连接?

func (s *Server) HandleExecuteRequest(w http.ResponseWriter, r *http.Request) {
    err := r.ParseForm()
    if err != nil {
        log.Printf("Error parsing request: %v", err)
        fmt.Fprintf(w, "Error parsing request: %v", err)
        return
    }

    decoder := schema.NewDecoder()
    var f Form
    err = decoder.Decode(&f, r.PostForm)
    if err != nil {
        log.Printf("Error decoding form: %v", err)
        fmt.Fprintf(w, "Error decoding form: %v", err)
        return
    }

    s.clientMap[r.RemoteAddr] <- buildCommand(&f)
}

func (s *Server) HandleExecute(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")

    s.addClient(r)

    for {
        cmd := <-s.clientMap[r.RemoteAddr]
        execute(w, cmd)
    }
}

Javascript Javascript

var source = new EventSource('<host>/execute');
source.onmessage = function(e) {
document.querySelector("code").innerHTML +="<span class='font-weight-bold' style='white-space: pre-wrap; padding-left: 200px;'>" + e.data + "</span>" + "<br>"
};

If I update HandleExecute to below, I get a continuous connection but then HandleExecuteRequest gets stuck in pending when that is hit.如果我将HandleExecute更新到下面,我会得到一个连续的连接,但是当它被击中时HandleExecuteRequest会卡在挂起状态。 It could how I'm setting up the clients and handling the channels in this case.在这种情况下,这可能是我设置客户端和处理渠道的方式。

func (s *Server) HandleExecute(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")

    s.addClient(r)

    for {
        select {
        case cmd := <-s.clientMap[r.RemoteAddr]:
            execute(w, cmd)
        default:
            fmt.Fprint(w, ": no data\n\n")
        }
    }
}

My issue had nothing to do with how the SSE handler was set up.我的问题与 SSE 处理程序的设置方式无关。 My channel was not being setup correctly and was blocking connections.我的频道没有正确设置,并且阻止了连接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我的javascript Promise卡住为“待处理”? - Why is my javascript Promise stuck as “pending”? 为什么使用numeric.toString()作为数组键会导致我的脚本卡住 - Why does using numeric.toString() as an array key cause my script to get stuck 如何使用javascript-client关闭与sseflux的连接? - How to close connection to sse flux with javascript-client? 为什么我的事件处理程序会导致“不是函数”错误,但是可以从Firebug控制台运行? - Why does my event handler cause an “is not a function” error, but works from the Firebug console? 为什么在Firefox或Chrome中重新加载页面会导致浏览器调用服务器后触发卸载事件处理程序? - Why does reloading page in Firefox or Chrome cause the unload event handler to trigger after the browser calls the server? 为什么倒计时停留在“ 1”? - Why does the Countdown stuck at “1”? 为什么 bundle.js 在我的网页上停留在待处理状态? - Why is bundle.js stuck in pending status on my web page? 如果在执行处理程序期间注销,为什么 promise 的 state 会“挂起”? - Why is the state of a promise 'pending' if logged out during executing it's handler? 为什么 Promise.all(..) 在附加的 then 处理程序中传递未解决/待处理的承诺? - Why is Promise.all(..) passing unresolved/pending promises in attached then handler? 为什么firefox连接后不发出(客户端) - why firefox does not emit after connection (client side)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM