gin websocket 简单分布式实现
2018-09-18
2018年03月18日 15:55:09 阅读数:829
main.go
import ( "github.com/gin-gonic/gin")func main() { ... // 连接ws会先发Get,正常返回101 r.GET("/ws", func(c *gin.Context) { WsHandler(c.Writer, c.Request) }) ... r.Run()}1
2
3
4
5
6
7
8
9
10
11
12
13
handler.go
websocket接入:
import "github.com/gorilla/websocket"var wsupgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, HandshakeTimeout: 5 * time.Second, // 取消ws跨域校验 CheckOrigin: func(r *http.Request) bool { return true },}// 处理ws请求func WsHandler(w http.ResponseWriter, r *http.Request) { var conn *websocket.Conn var err error conn, err = wsupgrader.Upgrade(w, r, nil) if err != nil { fmt.Println("Failed to set websocket upgrade: %+v", err) return } // 必须死循环,gin通过协程调用该handler函数,一旦退出函数,ws会被主动销毁 for { // recieve t, reply, err := conn.ReadMessage() if err != nil { break } // todo:业务操作 }}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
分布式扩展,使用rds或者kafka等解耦合
当ws建立连接后,可轮询共享内存(rds)是否有新消息,若有新消息,则往ws写数据。
配合客户端重连机制,很好实现分布式长连接IM和PUSH扩展。
// 业务操作调用写rdsfunc SendMsg2Rds(uid int64, msg *WsMsg) { // list 或者 pubsub 结构}// 业务操作调用读rdsfunc ReadMsgFromRds(uid int64) *WsMsg { // list 或者 pubsub 结构}// 协程轮询rds:go RevAndSendfunc RevAndSend(uid int64,ws *websocket.Conn) { for { // 若ws断开,则break if msg := ReadMsgFromRds(uid); msg != nil { // 向rds写数据 ws.WriteMessage(websocket.TextMessage, []byte(msg.ToJson())) } }}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
websocket 握手协议
客户端会发送Get请求,带有核心字段:
Upgrade: websocketSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==1
2
服务端会将101作为返回码返回,作为握手成功的标示
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_17612199/article/details/79601318
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。
http://www.pinlue.com/style/images/nopic.gif