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連線的正常關閉,我們需要注意以下幾點:
- 伺服器在完成操作後,必須手動關閉WebSocket連線;
- 當客戶端收到Close訊息時,伺服器應該立即關閉WebSocket連線;
- 當WebSocket連線發生異常時,需要在捕捉到異常之後及時關閉連線。
以上是如何在Golang中啟動和關閉Websocket連接的詳細內容。更多資訊請關注PHP中文網其他相關文章!