什么是WebSocket?
WebSocket是一种在客户端和服务器之间建立持久性连接的通信协议,它允许客户端和服务器之间进行全双工通信。
为什么使用WebSocket?
- WebSocket 允许服务器主动向客户端推送数据,同时也支持客户端向服务器发送数据。
- WebSocket 在客户端和服务器之间建议一次连接后,将保持持久性的连接,避免了像HTTP协议中的每次请求都需要建立和断开连接的开销。
- WebSocket是基于TCP协议的,通信延迟性较低,适用于实时性要求比较高的场景。
在gin中如何用WebSocket实现群聊和私聊?
实现群聊还是私聊的关键在于消息发送给谁,如果发送给所有人就是最大的广播了,如果发送给指定人,就实现了私聊还是群聊。
就比如我们建一个群,群里6个人,我们获取到那5个人的id,然后将自己发送的消息,指定给他们接收,那就可以实现群聊了。如果一对一聊天,那我们只用获取到对方一个人的id就行了。
1. 建立WebSocket连接
先建立一个map集合,用来存储所有连接信息。
var clients = make(map[int]*websocket.Conn)
建立一个互斥锁,保证对 clients 的并发安全访问。
var clientMutex sync.Mutex
然后可以使用 websocket.Upgrade()
函数将当前HTTP请求升级为WebSocket连接。
同时也要获取到当前用户id,为了后面实现私聊的功能。
然后将连接的信息添加到map集合中。
func WebSocketHandler(c *gin.Context) {
userID, err := strconv.Atoi(c.Query("userID")) // 获取用户ID,假设通过查询参数传递
//fmt.Println(userID, "用户id")
ws, err := websocket.Upgrade(c.Writer, c.Request, nil, 1024, 1024)
if err != nil {
panic(err)
}
// 加入新客户端
clientMutex.Lock()
clients[userID] = ws // 将新客户端添加到客户端集合中
clientMutex.Unlock()
// 处理WebSocket消息
go handleWebSocketMessages(userID, ws) // 开启一个 goroutine 处理该客户端的消息
}
2. 接收客户端发送的信息
因为对待这个处理信息的函数,上面开启的有单独的协程来监听,所以会实时监听是否有客户端发送消息。
func handleWebSocketMessages(userID int, ws *websocket.Conn) {
for {
messageType, p, err := ws.ReadMessage() // 阻塞等待读取客户端发送的消息
if err != nil {
break // 无法读取信息,退出循环
}
// 解析消息,识别目标客户端或群组
// 根据消息内容选择性发送给特定客户端或群组
// 例如,如果消息格式为私聊消息,则根据消息中指定的目标用户ID发送给特定客户端
// 如果消息格式为群聊消息,则将消息发送给所有群组成员
recipientIDs := []int{10, 12} // 限定发送人群
broadcastMessage(recipientIDs, messageType, p) // 广播消息给所有客户端
}
clientMutex.Lock()
defer clientMutex.Unlock()
delete(clients, userID) // 删除客户端连接
ws.Close() // 关闭 WebSocket 连接
}
3. 将消息广播发送出去 / 发送给指定的群体成员
这里是一旦上面服务端接收到了客户端的消息,就调用这个方法,将接收到的消息实时广播出去,也可以不广播,选择指定人群发送。具体发送给谁,可以由下面那个for循环决定,我这里是写的比较简单,在上面那个函数中指定了一些固定要发送的人群。正常来说,具体发送给谁,可以通过前端传值的方法确定。
func broadcastMessage(recipientIDs []int, messageType int, p []byte) {
clientMutex.Lock()
defer clientMutex.Unlock()
// 遍历所有客户端连接
for id, client := range clients {
// 检查当前客户端是否在接收者列表中 -- 私聊功能
for _, recipientID := range recipientIDs {
if id == recipientID {
// 向当前客户端发送消息
err := client.WriteMessage(messageType, p)
if err != nil {
// 发送消息失败,关闭连接并删除客户端
client.Close()
delete(clients, id)
}
break
}
}
}
}
就是这些代码就够实现简单的群聊 / 私聊了!
下面展示一下我自己写的一个简单聊天室吧!
这就是开了两个窗口,实现了实时聊天!
WebSocket 的应用场景?
WebSocket在需要实时通讯、数据实时更新和实时交互的各种应用场景中都有着广泛的应用。
比如:
- 实时通讯:WebSocket 可以用于实现即时通讯应用,例如在线聊天、即时消息传递等。它提供了双向通信的能力,允许客户端和服务器之间实时地交换数据,可以快速响应用户的输入并将数据推送给其他用户。
- 实时数据更新:WebSocket 可以用于实时数据更新的场景,例如股票行情推送、实时数据监控等。通过 WebSocket,服务器可以实时地将数据推送给客户端,而不需要客户端发起多次请求。
- 在线游戏:WebSocket 在在线游戏中具有重要应用,可以用于实现实时的游戏交互和多人游戏的联机模式。它提供了低延迟、高效率的通信方式,适合于需要实时响应的游戏场景。
- 协作应用:WebSocket 可以用于实现协作应用,如实时文档编辑、实时协作绘图等。多个用户可以同时编辑同一份文档或绘图,并实时地看到其他用户的操作,从而实现实时协作。
实时地图服务:WebSocket 可以用于实现实时地图服务,例如实时显示车辆位置、实时交通路况等。服务器可以实时地将车辆位置数据推送给客户端,并在地图上实时更新。 - 在线直播和视频会议:WebSocket 可以用于实现在线直播和视频会议服务,允许主播实时地向观众推送视频流,同时观众可以实时地与主播交流。这种实时性要求较高的应用场景非常适合使用 WebSocket。