首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么此SSE处理程序导致客户端连接处于挂起状态?

为什么此SSE处理程序导致客户端连接处于挂起状态?
EN

Stack Overflow用户
提问于 2020-02-07 10:56:31
回答 1查看 635关注 0票数 0

在本例https://github.com/kljensen/golang-html5-sse-example/blob/d4eba81ddea2b4191f039adb6929086ca6b39c0f/server.go#L130中,您可以在通道上阻塞。但在我的HandleExecute中这样做会导致浏览器/客户端连接状态停留在挂起状态,并且不会向客户端发送任何内容。

如果我删除了for循环,并在默认情况下使用select语句不写回数据,那么它就可以工作(execute写入和刷新数据),只是处理程序每5秒返回一次,客户端每5秒重新连接一次,而不是保持连接。当我这样做时,客户端仅在重新连接间隔获得流数据。

因此,用户最终会看到延迟持续时间少于5秒,这取决于HandleExecuteRequest被击中的时间。HandleExecute可能已准备好写入,但客户端可能尚未重新连接。我希望这是有意义的。

我如何编写这些处理程序来保持持续的连接而不是重新连接?

代码语言:javascript
运行
复制
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>"
};

如果我将HandleExecute更新到下面,我会得到一个持续的连接,但当命中时,HandleExecuteRequest就会被挂起。在这种情况下,这可能是我设置客户端和处理通道的方式。

代码语言:javascript
运行
复制
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")
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2020-02-08 02:38:42

我的问题与SSE处理程序的设置无关。我的频道设置不正确,并且阻塞了连接。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60106498

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档