Golang Websocket on Gin 如何建立

前言

這篇不會涉及太多底層的基礎知識
主要是分享自己在 Golang Websocket on Gin 這邊使用到的程式碼
方便各位進來直接複製🤣
這篇文章會從建立開始
會包含到所使用的套件以及範例的程式碼
到最後的用小程式來驗證

什麼是 Websocket

以下引述自維基百科

WebSocket是一種網絡傳輸協議
可在單個TCP連接上進行全雙工通信,位於OSI模型的應用層。
WebSocket協議在2011年由IETF標準化為RFC 6455,後由RFC 7936補充規範。Web IDL中的WebSocket API由W3C標準化。
WebSocket使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據。在WebSocket API中,瀏覽器和服務器只需要完成一次握手,兩者之間就可以建立持久性的連接,並進行雙向數據傳輸。

幫各位畫了重點

  • 全雙工:無論是 Server 端,或者 Client 端都可以同時傳送跟接收資料
  • 一次握手:跟一般 HTTP 通訊需要完成三方交握不同,Websocket 僅需要完成一次握手

綜合以上兩點,Websocket 就是高即時性,低延遲
但同時,更考驗錯誤處理

再統整一些我的筆記

  • 連線一旦建立之後,除非任何一端關閉,否則連線會一直存在
  • Server 端可以主動傳送資料給 Client,即使 Client 並沒有送請求(就像聊天室)
  • 有兩種 URI
    • ws://:使用於非加密連線
    • wss://:使用於加密連線,使用 443 port

使用套件

Gorilla WebSocket

// import "github.com/gorilla/websocket"

go get -u github.com/gorilla/websocket

Gin

// import "github.com/gin-gonic/gin"

go get -u github.com/gin-gonic/gin

從 HTTP Server 開始

// ServeHTTP ServeHTTP
func ServeHTTP() {
	go func() {
		g := gin.New()
		g.Use(gin.Recovery())
		err := g.SetTrustedProxies(nil)
		if err != nil {
			panic(err)
		}

		public := g.Group("/socket")
		public.GET("", SocketHandler)

		if err := g.Run(":8080"); err != nil {
			panic(err)
		}
	}()
}

到這邊為止
只是用 Gin 建立了一個 http server
並將 /socket 設定為 websocket 路由
HandlerFunc 在文章後面會有說明

使用 upgrader() 將 HTTP 連線轉化成 Websocket

引用自 pkg.go.dev

Upgrader specifies parameters for upgrading an HTTP connection to a WebSocket connection.

It is safe to call Upgrader’s methods concurrently.

upgrader 參數如下
CheckOrigin:會檢查是否跨域,文章後面的測試工具會提到 true, false 差別
Buffer:單位是 bytes,依需求設定(設為 0,則為不限制大小)

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

Golang Websocket on Gin

將 upgrader 加入 Gin API Handler

func SocketHandler(c *gin.Context) {
	upGrader := websocket.Upgrader{
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
	}

	ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		panic(err)
	}

	defer func() {
		closeSocketErr := ws.Close()
		if closeSocketErr != nil {
			panic(err)
		}
	}()

	for {
		msgType, msg, err := ws.ReadMessage()
		if err != nil {
			panic(err)
		}
		fmt.Printf("Message Type: %d, Message: %s\n", msgType, string(msg))
		err = ws.WriteJSON(struct {
			Reply string `json:"reply"`
		}{
			Reply: "Echo...",
		})
		if err != nil {
			panic(err)
		}
	}
}

完整程式碼

測試連線建立(PIE SOCKET)

這邊推薦一個不用寫 Code 就能夠驗證的方法
這是一個 Google Chrome 的外掛(連結
使用方法也很簡單

Golang Websocket on Gin

可以直接輸入 ws://…. 並 CONNECT
或者像我一樣 OPEN FULLSIZE 到新分頁執行

Golang Websocket on Gin

以本篇的範例來說
網址:ws://127.0.0.1:8080/socket

CONNECT 之後會變成 SEND MESSAGE
以下為執行結果

Golang Websocket on Gin
網頁結果
Golang Websocket on Gin
命令列結果

毛毛

可愛宅宅工程師、內容創作者
興趣是寫東東、寫東東跟寫東東。

Follow @Chindada Sponsor

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *