第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

如何優(yōu)雅地重新連接websocket?

如何優(yōu)雅地重新連接websocket?

Go
慕姐4208626 2023-08-07 10:33:08
我正在使用 HTTP 和 Websockets 構(gòu)建一個(gè)單頁面應(yīng)用程序。用戶提交表單,我將響應(yīng)流式傳輸給客戶端。下面是一個(gè)片段客戶端。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><formenctype="multipart/x-www-form-urlencoded"action="http://localhost:8000/"method="post">`這是服務(wù)器。如果請(qǐng)求不是 POST,我會(huì)編寫/渲染 html (parseAndExecute),以建立新的 websocket 連接。如果請(qǐng)求是 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僅當(dāng)我不刷新頁面時(shí),一切都會(huì)按我的預(yù)期進(jìn)行。如果我不刷新,我可以繼續(xù)提交表單并看到不同的輸出逐行出現(xiàn)。澄清一下,它實(shí)際上只有在頁面已經(jīng)啟動(dòng)時(shí)才有效,因此parseAndExecute永遠(yuǎn)不會(huì)被調(diào)用。該函數(shù)解析并執(zhí)行 html/template 創(chuàng)建一個(gè)新的 websocket 客戶端。任何頁面刷新或最初瀏覽 localhost:8000 都會(huì)websocket: close sent在服務(wù)器上引起。我不知道如何解決這個(gè)問題。服務(wù)器是否需要優(yōu)雅地處理斷開連接并允許重新連接?或者客戶需要做些什么?似乎服務(wù)器應(yīng)該升級(jí)任何連接,/ws因此創(chuàng)建多少個(gè)新的 websocket 客戶端并不重要,但顯然我的理解是錯(cuò)誤的。我不會(huì)關(guān)閉服務(wù)器上的 websocket 連接,因?yàn)橹灰绦蜻\(yùn)行,它就應(yīng)該保持連接狀態(tài)。當(dāng)用戶停止該程序時(shí),我認(rèn)為它會(huì)自動(dòng)關(guān)閉。
查看完整描述

1 回答

?
慕后森

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超5個(gè)贊

Websocket 服務(wù)器應(yīng)用程序必須通過關(guān)閉連接并釋放與該連接關(guān)聯(lián)的資源來處理連接上的錯(cuò)誤。


當(dāng)包含的頁面刷新時(shí),瀏覽器會(huì)關(guān)閉 websocket 連接。瀏覽器關(guān)閉連接后,服務(wù)器最終會(huì)收到讀取或?qū)懭脲e(cuò)誤。


連接關(guān)閉是服務(wù)器可能遇到的幾種錯(cuò)誤之一。服務(wù)器應(yīng)用程序應(yīng)以相同的方式處理連接上的所有錯(cuò)誤:關(guān)閉連接并釋放與該連接關(guān)聯(lián)的資源。


典型的應(yīng)用程序設(shè)計(jì)是讓客戶端在頁面加載時(shí)進(jìn)行連接,并在發(fā)生錯(cuò)誤后重新連接(使用退避)。服務(wù)器假設(shè)客戶端會(huì)隨著時(shí)間的推移而連接和斷開連接。


可以通過添加一個(gè)通過退避重新連接的 onerror 處理程序來改進(jìn) JS 代碼。根據(jù)應(yīng)用程序的不同,您可能還希望顯示指示連接狀態(tài)的 UI。


Go代碼并不會(huì)在所有場(chǎng)景下關(guān)閉連接。正在運(yùn)行的命令是與連接關(guān)聯(lián)的資源。應(yīng)用程序不會(huì)在連接錯(cuò)誤時(shí)終止該程序。以下是一些修復(fù):


defer ws.Close()升級(jí)成功后添加。ws.Close()刪除對(duì)from的其他直接調(diào)用SocketHandler.ServeHTTP。這確保了ws.Close()在所有場(chǎng)景中都被調(diào)用。


從讀寫泵退出時(shí)終止該命令。命令啟動(dòng)后將讀取泵移至。回來就殺掉。


go func(c *websocket.Conn, cmd *exec.Command) {

? ? defer c.Close()

? ? defer cmd.Process.Kill()

? ? for {

? ? ? ? if _, _, err := c.NextReader(); err != nil {

? ? ? ? ? ? break

? ? ? ? }

? ? }

}(ws, cmd)

從寫泵退出時(shí)終止命令:


s := bufio.NewScanner(io.MultiReader(stdout, stderr))

for s.Scan() {

? ? err := ws.WriteMessage(1, s.Bytes())

? ? if err != nil {

? ? ? ? break

? ? }

}

cmd.Process.Kill()

我還沒有運(yùn)行或測(cè)試過這段代碼。有些細(xì)節(jié)可能是錯(cuò)誤的,但這概述了關(guān)閉連接和釋放資源的一般方法。


查看完整回答
反對(duì) 回復(fù) 2023-08-07
  • 1 回答
  • 0 關(guān)注
  • 192 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)