我正在使用 HTTP 和 Websockets 构建一个单页面应用程序。用户提交表单,我将响应流式传输给客户端。下面是一个片段客户端。
var html = `<!DOCTYPE html>
<meta charset="utf-8">
<head>
</head>
<body>
<script>
var ws = new WebSocket("ws://localhost:8000/ws")
ws.onmessage = function(e) {
document.getElementById("output").innerHTML += e.data + "<br>"
}
function submitFunction() {
document.getElementById("output").innerHTML += ""
return false
}
</script>
<form
enctype="multipart/x-www-form-urlencoded"
action="http://localhost:8000/"
method="post"
>`
这是服务器。如果请求不是 POST,我会编写/渲染 html (parseAndExecute),以建立新的 websocket 连接。如果请求是 POST(来自表单),那么我开始处理并最终写入 websocket。
func (c *Config) ServeHtml(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
//process
channel <- data
}
c.parseAndExecute(w)
}
func (sh *SocketHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
w.Write([]byte(fmt.Sprintf("", err)))
return
}
//defer ws.Close()
// discard received messages
go func(c *websocket.Conn) {
for {
if _, _, err := c.NextReader(); err != nil {
c.Close()
break
}
}
}(ws)
data <- channel
仅当我不刷新页面时,一切都会按我的预期进行。如果我不刷新,我可以继续提交表单并看到不同的输出逐行出现。澄清一下,它实际上只有在页面已经启动时才有效,因此parseAndExecute永远不会被调用。该函数解析并执行 html/template 创建一个新的 websocket 客户端。
任何页面刷新或最初浏览 localhost:8000 都会websocket: close sent在服务器上引起。
我不知道如何解决这个问题。服务器是否需要优雅地处理断开连接并允许重新连接?或者客户需要做些什么?似乎服务器应该升级任何连接,/ws因此创建多少个新的 websocket 客户端并不重要,但显然我的理解是错误的。
我不会关闭服务器上的 websocket 连接,因为只要程序运行,它就应该保持连接状态。当用户停止该程序时,我认为它会自动关闭。
慕后森
相关分类