網頁

2022/12/12

Golang WebSocket idle connection timeout

Go以WebSocket連線時,當client閒置一段時間都沒傳送訊息的情況下主動中斷連線的方法如下。


範例環境:

  • Go 1.19
  • github.com/gorilla/websocket v1.5.0


範例

下面在「Golang WebSocket hello world」的程式中加上websocket.Conn.SetReadDeadline方法傳入time.Time設定讀取訊息的截止時間為現在時後5秒,若連線超過設定的時間未收到訊息便會關閉WebSocket連線。

main.go

package main

import (
    "fmt"
    "net/http"
    "time"

    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool {
        return true // allow CORS request's Origin header
    },
}

func main() {
    http.HandleFunc("/echo", echoHandler)
    http.ListenAndServe(":8080", nil)
}

func echoHandler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil) // get a websocket connection
    if err != nil {
        panic(err)
    }
    defer conn.Close()
    for {
        conn.SetReadDeadline(time.Now().Add(time.Second * 5)) // set read deadline is 5 seconds later
        mt, message, err := conn.ReadMessage()                // read messages from client
        if err != nil {
            panic(err)
        }

        fmt.Printf("receive: %s\n", message)
        err = conn.WriteMessage(mt, message) // write messages to client
        if err != nil {
            panic(err)
        }
    }

}


測試

啟動Go專案,若超過deadline後才發送訊息,則執行到Conn.ReadMessage()讀取訊息時會發生read tcp [::1]:8080->[::1]:51453: i/o timeout錯誤。

2022/12/12 23:08:23 http: panic serving [::1]:51435: read tcp [::1]:8080->[::1]:51435: i/o timeout
goroutine 19 [running]:
net/http.(*conn).serve.func1()
        /usr/local/Cellar/go/1.19.3/libexec/src/net/http/server.go:1850 +0xbf
panic({0x1256020, 0xc0000a4330})
        /usr/local/Cellar/go/1.19.3/libexec/src/runtime/panic.go:890 +0x262
main.echoHandler({0x1301d70?, 0xc000114000?}, 0x10a3e33?)
        /.../go-demo/main.go:32 +0x197

沒有留言:

張貼留言