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

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

關(guān)閉在服務(wù)器端發(fā)送但客戶端仍然連接

關(guān)閉在服務(wù)器端發(fā)送但客戶端仍然連接

Go
繁星coding 2023-05-08 18:13:21
我有一個(gè)通過 API 和 websocket 進(jìn)行通信的應(yīng)用程序。websocket 用于將更新的用戶數(shù)據(jù)發(fā)布到客戶端,如果它在數(shù)據(jù)庫(kù)中發(fā)生更改 - 這非常有效,除了在某些情況下 websocket 不接收任何數(shù)據(jù)的情況。幾秒鐘后,websocket 再次開始工作。服務(wù)器日志(首先,websocket 不工作并重新開始工作)msg="無法將數(shù)據(jù)寫入 Websocket: websocket: close sent"msg="正在向客戶端發(fā)送 Ping 消息"msg="無法將 ping 消息寫入 Websocket:websocket:關(guān)閉發(fā)送"msg="正在向客戶端發(fā)送 Ping 消息"msg="正在向客戶端發(fā)送 Ping 消息"msg="正在向客戶端發(fā)送 Ping 消息"msg="正在向客戶端發(fā)送 Ping 消息"客戶端代碼:<html><body><p id="data"></p></body><script>var ws = new WebSocket("wss://example.com/ws");function unloadPage() {    toggleLoader();    ws.onclose = function () {};    ws.close();}ws.onopen = function () {    ws.send('Ping');};ws.onerror = function (error) {    console.log('WebSocket Error ' + error);    var d = document.getElementById("data");    d.innerHTML += "<tr><td>Failed to connect to Server.</td></tr>"};ws.onmessage = function (e) {    console.log(e);    var data = e.data;    var d = document.getElementById("data");    var parsedjson = JSON.parse(data);    d.innerHTML = "";    for (var i = 0; i < parsedjson.length; i++) {        d.innerHTML += parsedjson;    }};ws.onclose = function () {    console.log("Websocket has been closed");};window.addEventListener("beforeunload", unloadPage);</script></html>基本上,我們將當(dāng)前數(shù)據(jù)發(fā)布到新的 Websocket 連接,當(dāng)它更新時(shí)——這總是有效的。之后,如果數(shù)據(jù)庫(kù)發(fā)生變化,它會(huì)將更新后的用戶列表發(fā)布到頻道中——然后 websocket 應(yīng)將其發(fā)布到更新列表的客戶端。我們還發(fā)送 ping 消息 - 失?。ㄈ缟厦娴娜罩舅荆?蛻舳吮旧聿粫?huì)記錄任何錯(cuò)誤或關(guān)閉 websocket。
查看完整描述

1 回答

?
尚方寶劍之說

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

該websocket: close sent錯(cuò)誤表明服務(wù)器向客戶端發(fā)送了關(guān)閉消息。因?yàn)閼?yīng)用程序服務(wù)器代碼不發(fā)送消息,所以連接必須發(fā)送消息以響應(yīng)來自客戶端的關(guān)閉消息。


關(guān)閉消息作為錯(cuò)誤從 websocket 讀取方法返回。因?yàn)闆]有記錄任何消息,所以客戶端一定發(fā)送了“離開”關(guān)閉消息(唯一沒有記錄的錯(cuò)誤)。


當(dāng)websocket連接返回錯(cuò)誤時(shí),讀寫goroutine關(guān)閉連接返回。連接未保持打開狀態(tài)。


讀取和寫入 goroutine 不會(huì)檢測(cè)到另一個(gè)已關(guān)閉連接,直到從連接上的方法調(diào)用返回錯(cuò)誤。讀取 goroutine 會(huì)快速檢測(cè)到關(guān)閉的連接,因?yàn)樗冀K在讀取,但寫入 goroutine 可能會(huì)有延遲。這可能是應(yīng)用程序的問題


要讓寫入 goroutine 快速退出,請(qǐng)使用通道向?qū)懭?goroutine 發(fā)出信號(hào)。有可能dataChan可用于此目的,但我不確定,因?yàn)樵搯栴}不包含有關(guān)如何管理頻道的信息。假設(shè)通道可以使用,讀取 goroutine 應(yīng)該關(guān)閉dataChan。writer 應(yīng)該檢測(cè)到關(guān)閉的通道并退出 goroutine:


...

for {

? ? select {

? ? case data, ok := <-datachan:

? ? ? ? if !ok {

? ? ? ? ? ?// Done writing, return

? ? ? ? ? ?return

? ? ? ? }

? ? ? ? ws.SetWriteDeadline(time.Now().Add(writeWait))

? ? ? ? err := ws.WriteJSON(&data)

? ? ? ? if err != nil {

? ? ? ? ? ? conf.Log.Debugf("Failed to write data to Websocket: %v", err)

? ? ? ? ? ? return

? ? ? ? }

? ? ? ? ...

這是Gorilla Chat Example使用的方法。


如果dataChan不能使用,為此引入一個(gè)新的通道。在處理程序中創(chuàng)建通道并將通道傳遞給讀寫 goroutines:


?done := make(chan struct{})

?go allUserWebsocketWriter(ws, stop, datachan)

?go PingResponse(ws, stop)

從讀取 goroutine 返回時(shí)關(guān)閉通道:


func PingResponse(ws *websocket.Conn, done chan struct{}) {

? ? defer close(done)

? ? conf := storage.GetConfig()

? ? ...

在寫gorountine的通道上選擇:


...

for {

? ? select {

? ? case <-done:

? ? ? ? return

? ? case data := <-datachan:

? ? ? ? ws.SetWriteDeadline(time.Now().Add(writeWait))

? ? ? ? err := ws.WriteJSON(&data)

? ? ? ? ...

這導(dǎo)致寫 goroutine 在讀 goroutine 退出后快速退出。


這兩種方法都降低了在連接上寫入返回錯(cuò)誤的可能性websocket: close sent,但它們并沒有消除這種可能性。該錯(cuò)誤是預(yù)期的,因?yàn)樽x取 goroutine 可以在寫入 goroutine 寫入消息之前關(guān)閉連接。


無論如何,證據(jù)是客戶端正在關(guān)閉連接。未關(guān)閉的連接不是問題所在。


查看完整回答
反對(duì) 回復(fù) 2023-05-08
  • 1 回答
  • 0 關(guān)注
  • 332 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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