
1) 【一句话结论】
针对好未来直播课实时音视频传输,用Golang实现WebSocket连接管理器,通过并发安全的连接池、心跳检测、状态管理,实现连接建立、消息广播、断开处理,并设计连接超时、资源限制等机制保证连接稳定性。
2) 【原理/概念讲解】
WebSocket连接管理核心是“持久化连接与消息同步”,需理解三个关键模块:
sync.Map或互斥锁保护map)存储活跃连接,类比“客服团队”,每个连接是“客服”,负责与客户端通信,支持快速增删。3) 【对比与适用场景】
| 对比项 | WebSocket | HTTP长连接(如Server-Socket) |
|---|---|---|
| 定义 | 全双工持久连接,单次握手后保持通信 | 半双工,需多次请求建立连接 |
| 特性 | 低延迟、低开销、持久连接 | 需频繁建立连接,资源消耗大 |
| 使用场景 | 实时音视频、实时聊天、在线游戏 | 简单实时性要求,资源有限场景 |
| 注意点 | 需处理连接断开、心跳 | 需频繁维护连接状态 |
4) 【示例】(伪代码)
package main
import (
"sync"
"time"
"github.com/gorilla/websocket"
)
type WebSocketManager struct {
activeConn sync.Map // 并发安全存储活跃连接
maxConn int // 最大连接数(假设1000)
broadcast chan Message // 有序消息队列
closeChan chan *websocket.Conn // 关闭连接通道
heartbeat *time.Ticker // 心跳定时器(30秒)
msgSeq int // 消息序列号
}
type Message struct {
Seq int
Data []byte
}
func NewWebSocketManager(max int) *WebSocketManager {
return &WebSocketManager{
maxConn: max,
broadcast: make(chan Message, 100),
closeChan: make(chan *websocket.Conn),
heartbeat: time.NewTicker(30 * time.Second),
}
}
func (wm *WebSocketManager) Start() {
go wm.handleConnections()
go wm.handleBroadcast()
go wm.handleHeartbeat()
}
func (wm *WebSocketManager) handleConnections() {
for {
select {
case conn := <-wm.closeChan:
wm.activeConn.Delete(conn)
conn.Close()
}
}
}
func (wm *WebSocketManager) handleBroadcast() {
for msg := range wm.broadcast {
activeConns := make(map[*websocket.Conn]bool)
wm.activeConn.Range(func(key, _ interface{}) bool {
activeConns[key.(*websocket.Conn)] = true
return true
})
for conn := range activeConns {
if err := conn.WriteMessage(websocket.TextMessage, msg.Data); err != nil {
wm.closeChan <- conn
}
}
}
}
func (wm *WebSocketManager) handleHeartbeat() {
for {
select {
case <-wm.heartbeat.C:
activeConns := make(map[*websocket.Conn]bool)
wm.activeConn.Range(func(key, _ interface{}) bool {
activeConns[key.(*websocket.Conn)] = true
return true
})
for conn := range activeConns {
if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil {
wm.closeChan <- conn
continue
}
_, _, err := conn.ReadMessage()
if err != nil {
wm.closeChan <- conn
}
}
}
}
}
func (wm *WebSocketManager) OnConnect(conn *websocket.Conn) {
if wm.activeConn.Size() >= wm.maxConn {
conn.WriteMessage(websocket.TextMessage, []byte("连接数已达上限"))
conn.Close()
return
}
wm.activeConn.Store(conn, true)
wm.broadcast <- Message{Seq: wm.msgSeq, Data: []byte("欢迎加入直播课")}
wm.msgSeq++
}
func (wm *WebSocketManager) SendBroadcast(data []byte) {
msg := Message{Seq: wm.msgSeq, Data: data}
wm.msgSeq++
wm.broadcast <- msg
}
func (wm *WebSocketManager) CleanIdleConnections() {
time.AfterFunc(60*time.Second, func() {
activeConns := make(map[*websocket.Conn]bool)
wm.activeConn.Range(func(key, _ interface{}) bool {
activeConns[key.(*websocket.Conn)] = true
return true
})
for conn := range activeConns {
if time.Since(conn.LastWriteTime()) > 30*time.Second {
wm.closeChan <- conn
}
}
})
}
5) 【面试口播版答案】
面试官您好,针对好未来直播课的实时音视频传输需求,我考虑用Golang实现WebSocket连接管理。核心思路是构建一个连接管理器,通过goroutine管理每个WebSocket连接的生命周期,包括连接建立、消息广播和断开处理。具体来说,我会用sync.Map作为并发安全的活跃连接存储,消息通过有序channel广播,心跳检测每30秒发送ping,接收pong确认连接状态,超时则关闭连接。同时,设置最大连接数限制(比如1000个),超过时拒绝新连接;设计闲置连接清理机制,超时(比如60秒)未活跃的连接自动关闭,避免资源耗尽。这样既能满足实时音视频的实时性要求,又能保证连接的稳定性,应对网络波动等异常场景,比如客户端断开连接时,通过心跳超时检测及时移除,避免向已断开连接发送消息。
6) 【追问清单】
sync.Map或互斥锁保护activeConn map,避免并发删除时的竞态条件。activeConn检查),确保消息只发送给活跃客户端。7) 【常见坑/雷区】