首頁  >  文章  >  後端開發  >  如何在Golang中啟動和關閉Websocket連接

如何在Golang中啟動和關閉Websocket連接

PHPz
PHPz原創
2023-04-14 09:33:141967瀏覽

Websocket是一種能夠在客戶端和伺服器之間進行即時雙向通訊的網路協定。它可以在不使用HTTP輪詢的情況下,同時實現高效率的資料傳輸和低延遲的互動效果。 Golang是一種開源的高效能程式語言,擁有卓越的並發效能和優秀的程式碼品質。在Websocket通訊中,Golang也有著優秀的實作方式。本文將介紹如何在Golang中啟動和關閉Websocket連線。

Websocket在Golang中的實作

在Golang中實作Websocket,需要進行以下幾個步驟:

    ##匯入對應的套件
#在Go語言中,實作Websocket需要WebSocket和Http套件的支援。程式碼如下:

import (
    "net/http"
    
    "github.com/gorilla/websocket"
)
其中,github.com/gorilla/websocket是一個優秀的、支援多種協定的WebSocket套件。它包含了一些WebSocket相關的結構體和函數,我們可以用它來快速實現一個WebSocket的連接。

    定義WebSocket連線處理函數
在處理WebSocket連線的函數中,我們需要完成以下幾個任務:

a. 定義WebSocket升級

對於一個HTTP請求,如果需要升級為WebSocket連接,我們需要對其進行處理,並傳回相關的升級請求。程式碼如下:

var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    // 升级为WebSocket连接
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(err)
        return
    }
    
    // 实现WebSocket通信
    ...
}
在這段程式碼中,我們使用了Upgrader結構體,它是gorilla/websocket函式庫中實作WebSocket升級的函數。

Upgrader包含了讀寫快取區大小和CheckOrigin函數。檢查Origin用於檢查請求是否是來自一個合法的來源。如果該方法回傳false,那麼升級請求就會被拒絕。由於我們在本範例中並不需要檢查合法性,因此我們的CheckOrigin總是回傳true。

在呼叫Upgrader.Upgrade方法後,我們會得到一個WebSocket物件ws。在該物件上,我們可以呼叫ReadMessage和WriteMessage等方法,完成後續的WebSocket通訊。

b. 讀取WebSocket訊息

在得到WebSocket連線之後,我們需要不斷讀取客戶端發送過來的訊息。讀取WebSocket訊息可以使用ReadMessage方法。程式碼如下:

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    ...
    
    for {
        // 读取消息
        _, message, err := ws.ReadMessage()
        if err != nil {
            log.Println(err)
            break
        }
        
        // 处理消息
        ...
    }
}
在這段程式碼中,我們利用for迴圈來不斷地從WebSocket中讀取訊息。如果讀取失敗,則表示WebSocket連線已經關閉,我們退出循環。

c. 傳送WebSocket訊息

在處理完客戶端所傳送的訊息之後,我們可能需要將一些處理結果傳送給客戶端。發送WebSocket訊息可以使用WriteMessage方法。程式碼如下:

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    ...
    
    for {
        ...
        
        // 发送消息
        err = ws.WriteMessage(websocket.TextMessage, []byte(reply))
        if err != nil {
            log.Println(err)
            break
        }
    }
}
在這段程式碼中,我們透過WriteMessage方法向客戶端發送了一個訊息。這個方法的第一個參數是訊息的類型,我們可以指定為TextMessage或BinaryMessage;第二個參數是一個位元組數組,它包含了要傳送的資料。

    啟動WebSocket服務
在完成上述步驟之後,我們就可以啟動一個WebSocket服務。程式碼如下:

func main() {
    http.HandleFunc("/ws", websocketHandler)
    log.Println("Server started at http://127.0.0.1:8080")
    http.ListenAndServe(":8080", nil)
}
在這段程式碼中,我們呼叫了http.HandleFunc函數,將"/ws"路徑對應到我們的WebSocket處理函數websocketHandler。最後,我們呼叫http.ListenAndServe啟動服務。

關閉WebSocket連線

在使用WebSocket之後,我們需要手動關閉連線。正常地關閉WebSocket連線需要注意以下幾點:

a. 伺服器端主動關閉

當伺服器端需要關閉WebSocket連線時,可以呼叫WebSocket.Close方法。程式碼如下:

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    defer ws.Close() // 关闭WebSocket连接
    
    for {
        ...
    }
}
在程式碼中,我們使用defer語句在websocket函數結束時,自動關閉WebSocket連線。

b. 客戶端主動關閉

當客戶端需要關閉WebSocket連線時,可以向伺服器發送Close訊息。伺服器會收到Close訊息,並在收到訊息後主動關閉WebSocket連線。

我們可以在伺服器端的websocket函數中增加一個處理Close訊息的分支。程式碼如下:

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    ...
    
    for {
        // 读取消息
        messageType, message, err := ws.ReadMessage()
        if err != nil {
            log.Println(err)
            break
        }
        
        // 处理消息
        switch messageType {
        case websocket.CloseMessage:
            // 收到关闭消息,关闭连接
            return
        case websocket.TextMessage:
            // 收到文本消息,处理消息
            ...
        case websocket.BinaryMessage:
            ...
        }
    }
    
    // 关闭WebSocket连接
    ws.Close()
}
在該程式碼中,我們增加了一個訊息類型為CloseMessage的處理分支。在收到Close訊息之後,我們立即退出websocket函數,並關閉WebSocket連線。

c. 異常關閉

當WebSocket連線發生例外時,需要及時關閉連線。例如網路中斷、客戶端與伺服器端連線逾時等情況下,都需要關閉WebSocket連線。

我們可以在websocket函數中捕捉異常,並在捕捉到異常時關閉WebSocket連線。程式碼如下:

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    defer ws.Close() // 当函数退出时关掉WebSocket连接
    
    for {
        _, message, err := ws.ReadMessage()
        if err != nil {
            if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
                log.Printf("error: %v", err)
            }
            break
        }
        
        // 处理消息
        ...
    }
}
在該程式碼中,我們透過defer語句在websocket函數返回之前手動關閉WebSocket連線。在ReadMessage操作中,我們增加了對異常錯誤的捕捉並進行日誌輸出。

總結

在Golang中,可以透過gorilla/websocket函式庫來實作Websocket連線。我們可以在WebSocket通訊的處理函數中,使用Upgrader結構體將HTTP協定升級為WebSocket。在WebSocket連接時,我們需要實作一些WebSocket訊息的讀取和發送操作。

為了確保WebSocket連線的正常關閉,我們需要注意以下幾點:

  1. 伺服器在完成操作後,必須手動關閉WebSocket連線;
  2. 當客戶端收到Close訊息時,伺服器應該立即關閉WebSocket連線;
  3. 當WebSocket連線發生異常時,需要在捕捉到異常之後及時關閉連線。

以上是如何在Golang中啟動和關閉Websocket連接的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn