為開源項目 go-gin-api 增加 WebSocket 模塊
文章目錄:
WebSocket 示例界面
第三方包
代碼封裝
小結(jié)
推薦閱讀
WebSocket 示例界面

第三方包
gorilla/websocket[1]
websocket 鏈接時支持配置項:
type?Upgrader?struct?{
????//?指定升級?websocket?握手完成的超時時間
????HandshakeTimeout?time.Duration
????//?指定 io 操作的緩存大小,如果不指定就會自動分配。
????ReadBufferSize,?WriteBufferSize?int
????//?寫數(shù)據(jù)操作的緩存池,如果沒有設(shè)置值,write buffers 將會分配到鏈接生命周期里。
????WriteBufferPool?BufferPool
????//按順序指定服務(wù)支持的協(xié)議,如值存在,則服務(wù)會從第一個開始匹配客戶端的協(xié)議。
????Subprotocols?[]string
????//?指定 http 的錯誤響應(yīng)函數(shù),如果沒有設(shè)置 Error 則,會生成 http.Error 的錯誤響應(yīng)。
????Error?func(w?http.ResponseWriter,?r?*http.Request,?status?int,?reason?error)
????//?請求檢查函數(shù),用于統(tǒng)一的鏈接檢查,以防止跨站點請求偽造。如果不檢查,就設(shè)置一個返回值為?true?的函數(shù)。
????//?如果請求?Origin?標(biāo)頭可以接受,CheckOrigin?將返回?true。?如果 CheckOrigin 為nil,則使用安全默認(rèn)值:如果 Origin 請求頭存在且原始主機(jī)不等于請求主機(jī)頭,則返回?false
????CheckOrigin?func(r?*http.Request)?bool
????// EnableCompression 指定服務(wù)器是否應(yīng)嘗試協(xié)商每個郵件壓縮(RFC 7692)。?
????//?將此值設(shè)置為true并不能保證將支持壓縮。?
????//?目前僅支持“無上下文接管”模式
????EnableCompression?bool
}
Upgrade 函數(shù)可將 http 升級到 WebSocket 協(xié)議:
// responseHeader 包含在對客戶端升級請求的響應(yīng)中。?
//?使用 responseHeader 指定 cookie(Set-Cookie)和應(yīng)用程序協(xié)商的子協(xié)議(Sec-WebSocket-Protocol)。
//?如果升級失敗,則升級將使用?HTTP?錯誤響應(yīng)回復(fù)客戶端
//?返回一個 Conn 指針,拿到他后,可使用 Conn 讀寫數(shù)據(jù)與客戶端通信。
func?(u?*Upgrader)?Upgrade(w?http.ResponseWriter,?r?*http.Request,?responseHeader?http.Header)?(*Conn,?error)
代碼封裝
封裝一個 socket_server,同時支持使用日志、數(shù)據(jù)庫、緩存等操作:
type?Server?interface?{
?//?OnMessage?接收消息
?OnMessage()
?//?OnSend?發(fā)送消息
?OnSend(message?[]byte)?error
?//?OnClose?關(guān)閉
?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,發(fā)送消息的接口為:/api/tool/send_message。
JavaScript 示例代碼:
const?ws?=?new?WebSocket("ws://127.0.0.1:9999/socket/system/message");
//連接打開時觸發(fā)
ws.onopen?=?function?(evt)?{
????...
};
//接收到消息時觸發(fā)
ws.onmessage?=?function?(evt)?{
????...
};
//連接關(guān)閉時觸發(fā)
ws.onclose?=?function?(evt)?{
????...
};
在項目中 實用工具箱 -> WebSocket 界面,右側(cè)請求接口發(fā)送消息,在左側(cè)可以實時收到消息。
小結(jié)
本文純屬拋磚引玉,有問題,歡迎批評指正。
go-gin-api[2] 項目開箱即用,支持 WEB 界面一鍵安裝,趕快去試試吧。
參考資料
gorilla/websocket: https://github.com/gorilla/websocket
[2]go-gin-api: https://github.com/xinliangnote/go-gin-api
推薦閱讀
評論
圖片
表情
