「这是我参与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()
那么此时我们就已经连接成功了,下一章中我们将进行通信。