基于Gin + WebSocket + MongoDB 的IM即时聊天Demo(二)

349 阅读1分钟

「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。

github地址:github.com/CocaineCong…

B站教程地址:www.bilibili.com/video/BV1BP…

2.2 进行连接

我们这一章中进行ws连接

  • 定义一个管理Manager
var Manager  = ClientManager{
	Clients	 : 	make(map[string]*Client),   
	Broadcast:	make(chan *Broadcast),
	Register : 	make(chan *Client),
	Reply 	 : 	make(chan *Client),
	Unregister:	make(chan *Client),
}
  • Clients:参与连接的用户,出于性能的考虑,需要设置最大连接数
  • Broadcast:进行广播
  • Register:进行用户的注册连接
  • Reply:消息回复
  • Unregister:断开连接

2.2.1 服务器监听连接

用 for 不断进行监听查看哪个用户进入通道通信,对用户一旦有用户进来,就 Register 进行注册

for {
case conn := <- Manager.Register:
        log.Printf("建立新连接: %v", conn.ID)
        Manager.Clients[conn.ID] = conn
        replyMsg := &ReplyMsg{
                Code:    e.WebsocketSuccess,
                Content: "已连接至服务器",
        }
        msg , _ := json.Marshal(replyMsg)
        _ = conn.Socket.WriteMessage(websocket.TextMessage, msg)
}

2.2.2 服务器监听断开连接

同样的,也可以用来对服务器和用户之间连接的断开。

case conn := <-Manager.Unregister: // 断开连接
                log.Printf("连接失败:%v", conn.ID)
                if _, ok := Manager.Clients[conn.ID]; ok {
                        replyMsg := &ReplyMsg{
                                Code:    e.WebsocketEnd,
                                Content: "连接已断开",
                        }
                        msg , _ := json.Marshal(replyMsg)
                        _ = conn.Socket.WriteMessage(websocket.TextMessage, msg)
                        close(conn.Send)
                        delete(Manager.Clients, conn.ID)
                }

2.2.3 用户连接服务器

我们采用的是gin框架,所以这里我们可以先引入路由

r := gin.Default()
r.Use(gin.Recovery(),gin.Logger())
v1 := r.Group("/")
{
        v1.GET("ping", func(c *gin.Context) {
                c.JSON(200,"SUCCESS")
        })
        v1.GET("ws",service.WsHandler)
}

再在service层创建一个handler处理

  • 读取两人的id
uid:=c.Query("uid") // 自己的id
toUid:=c.Query("toUid") // 对方的id
  • 升级ws协议
conn, err := (&websocket.Upgrader{
        CheckOrigin: func(r *http.Request) bool {
        return true
}}).Upgrade(c.Writer, c.Request, nil) 

CheckOrigin是为了解决跨域问题 Upgrade升级成ws协议

  • 创建用户实例
client := &Client{
        ID : createId(uid,toUid),
        SendID	: createId(toUid,uid),
        Socket	: conn,
        Send	: make(chan []byte),
}
  • 用户注册到用户管理上面
Manager.Register <- client
  • 开通两个协程, 一个读,一个写
go client.Read()
go client.Write()

那么此时我们就已经连接成功了,下一章中我们将进行通信。