第三方包

websocket?鏈接時支持配置項:

type Upgrader struct {
// 指定升級 websocket 握手完成的超時時間
HandshakeTimeout time.Duration

// 指定 io 操作的緩存大小,如果不指定就會自動分配。
ReadBufferSize, WriteBufferSize int

// 寫數據操作的緩存池,如果沒有設置值,write buffers 將會分配到鏈接生命周期里。
WriteBufferPool BufferPool

//按順序指定服務支持的協議,如值存在,則服務會從第一個開始匹配客戶端的協議。
Subprotocols []string

// 指定 http 的錯誤響應函數,如果沒有設置 Error 則,會生成 http.Error 的錯誤響應。
Error func(w http.ResponseWriter, r *http.Request, status int, reason error)

// 請求檢查函數,用于統一的鏈接檢查,以防止跨站點請求偽造。如果不檢查,就設置一個返回值為 true 的函數。
// 如果請求 Origin 標頭可以接受,CheckOrigin 將返回 true。 如果 CheckOrigin 為nil,則使用安全默認值:如果 Origin 請求頭存在且原始主機不等于請求主機頭,則返回 false
CheckOrigin func(r *http.Request) bool

// EnableCompression 指定服務器是否應嘗試協商每個郵件壓縮(RFC 7692)。
// 將此值設置為true并不能保證將支持壓縮。
// 目前僅支持“無上下文接管”模式
EnableCompression bool
}

Upgrade?函數可將?http?升級到?WebSocket?協議:

// responseHeader 包含在對客戶端升級請求的響應中。 
// 使用 responseHeader 指定 cookie(Set-Cookie)和應用程序協商的子協議(Sec-WebSocket-Protocol)。
// 如果升級失敗,則升級將使用 HTTP 錯誤響應回復客戶端
// 返回一個 Conn 指針,拿到他后,可使用 Conn 讀寫數據與客戶端通信。
func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error)

代碼封裝

封裝一個?socket_server,同時支持使用日志、數據庫、緩存等操作:

type Server interface {

// OnMessage 接收消息
OnMessage()

// OnSend 發送消息
OnSend(message []byte) error

// OnClose 關閉
OnClose()
}

func New(logger *zap.Logger, db db.Repo, cache cache.Repo, conn *websocket.Conn) (Server, error) {

...

}

封裝一個?socket_conn

func (h *handler) Connect() core.HandlerFunc {
var upGrader = websocket.Upgrader{
HandshakeTimeout: 5 * time.Second,
CheckOrigin: func(r *http.Request) bool {
return true
},
}

return func(ctx core.Context) {
ws, err := upGrader.Upgrade(ctx.ResponseWriter(), ctx.Request(), nil)
if err != nil {
return
}

server, err = socket_server.New(h.logger, h.db, h.cache, ws)
if err != nil {
return
}

go server.OnMessage()
}
}

socket_conn 是一個 HandlerFunc,可直接在路由中使用。

項目中?websocket?鏈接地址為:/socket/system/message,發送消息的接口為:/api/tool/send_message

JavaScript?示例代碼:

const ws = new WebSocket("ws://127.0.0.1:9999/socket/system/message");

//連接打開時觸發
ws.onopen = function (evt) {
...
};

//接收到消息時觸發
ws.onmessage = function (evt) {
...
};

//連接關閉時觸發
ws.onclose = function (evt) {
...
};

在項目中 實用工具箱 -> WebSocket 界面,右側請求接口發送消息,在左側可以實時收到消息。

小結

本文純屬拋磚引玉,有問題,歡迎批評指正。

go-gin-api[2]?項目開箱即用,支持 WEB 界面一鍵安裝,趕快去試試吧。

參考資料

[1]gorilla/websocket:?https://github.com/gorilla/websocket

[2]go-gin-api:?https://github.com/xinliangnote/go-gin-api

文章轉自微信公眾號@程序員新亮

上一篇:

使用gin搭建api后臺系統之框架搭建

下一篇:

Go工程化(四) API 設計上: 項目結構 & 設計
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費