Websocket是一種能夠在客戶端和伺服器之間進行即時雙向通訊的網路協定。它可以在不使用HTTP輪詢的情況下,同時實現高效率的資料傳輸和低延遲的互動效果。 Golang是一種開源的高效能程式語言,擁有卓越的並發效能和優秀的程式碼品質。在Websocket通訊中,Golang也有著優秀的實作方式。本文將介紹如何在Golang中啟動和關閉Websocket連線。
Websocket在Golang中的實作
在Golang中實作Websocket,需要進行以下幾個步驟:
import ( "net/http" "github.com/gorilla/websocket" )其中,github.com/gorilla/websocket是一個優秀的、支援多種協定的WebSocket套件。它包含了一些WebSocket相關的結構體和函數,我們可以用它來快速實現一個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;第二個參數是一個位元組數組,它包含了要傳送的資料。
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連線的正常關閉,我們需要注意以下幾點:
以上是如何在Golang中啟動和關閉Websocket連接的詳細內容。更多資訊請關注PHP中文網其他相關文章!