Collider 就是 WebRTC 的信令服务器,负责转发 SDP、ICE Candidate 和管理房间用户状态,但不处理实际音视频流。


👉 collider 不是生产级服务器,不安全、不稳定、不高并发。

👉 Google 官方也说了:仅供 demo,不推荐用于正式环境。

collidermain

main.go

// tls:布尔值,默认 true,表示是否启用 TLS(HTTPS)。
var tls = flag.Bool("tls", true, "whether TLS is used")

// port:整数值,默认 443,表示服务监听的端口。
var port = flag.Int("port", 443, "The TCP port that the server listens on")

// room-server:字符串,默认 "https://appr.tc",表示 房间服务器 的 URL。
var roomSrv = flag.String("room-server", "https://appr.tc", "The origin of the room server")

// 解析命令行传入的参数
flag.Parse()

// 打印
log.Printf("Starting collider: tls = %t, port = %d, room-server=%s", *tls, *port, *roomSrv)

// 创建一个 Collider 实例
c := collider.NewCollider(*roomSrv)

// 启动服务
c.Run(*port, *tls)

collider

collider.go

方法名 参数 说明
NewCollider(rs string) rs:房间服务器 URL 创建 Collider 实例,初始化 roomTabledashboard
Run(p int, useTls bool) p:端口号,useTls:是否启用 TLS 启动 HTTP/HTTPS + WebSocket 服务,阻塞主线程。
httpStatusHandler(w http.ResponseWriter, r *http.Request) HTTP 请求/响应对象 HTTP GET /status,返回服务状态 JSON(房间数、客户端数等)。
httpHandler(w http.ResponseWriter, r *http.Request) HTTP 请求/响应对象 HTTP POST/DELETE /ROOMID/CLIENTID,用于发送消息或删除客户端记录。
wsHandler(ws *websocket.Conn) WebSocket 连接对象 WebSocket 消息处理,包括:register 注册客户端,send 发送消息。
httpError(msg string, w http.ResponseWriter) 错误消息,HTTP 响应对象 处理 HTTP 错误,返回 500 并记录到 dashboard。
wsError(msg string, ws *websocket.Conn) 错误消息,WebSocket 连接对象 处理 WebSocket 错误,发送错误消息给客户端并记录到 dashboard。

dashboard.go

方法名 参数 返回值 作用说明
newDashboard() *dashboard 创建并初始化一个新的 dashboard 实例,记录 startTime
(db *dashboard) getReport(rs *roomTable) rs *roomTable statusReport 获取当前服务状态报告,包括:服务运行时长、当前打开的 WebSocket 数量、累计 WebSocket 数量、WebSocket 错误数、HTTP 错误数。使用锁保证线程安全。
(db *dashboard) incrWs() WebSocket 新连接建立时调用,累计 totalWs 增加 1。线程安全。
(db *dashboard) onWsErr(err error) err error WebSocket 发生错误时调用,累计 wsErrs 增加 1。线程安全。
(db *dashboard) onHttpErr(err error) err error HTTP 请求发生错误时调用,累计 httpErrs 增加 1。线程安全。

roomTable.go

方法名 参数 返回值 作用说明
(rt *roomTable) room(id string) id:房间 ID *room 获取指定房间,如果房间不存在则创建一个新的房间(线程安全)。
(rt *roomTable) roomLocked(id string) id:房间 ID *room room 类似,但假设调用方已经持有锁,不再重复加锁。
(rt *roomTable) remove(rid string, cid string) rid 房间 ID,cid 客户端 ID 删除指定客户端,如果房间为空则删除房间(线程安全)。
(rt *roomTable) removeLocked(rid string, cid string) 同上 remove 类似,但假设锁已持有。
(rt *roomTable) send(rid string, srcID string, msg string) rid 房间 ID,srcID 发送者 ID,msg 消息内容 error 转发消息到指定房间,如果房间不存在则创建,调用房间的 send 方法。
(rt *roomTable) register(rid string, cid string, rwc io.ReadWriteCloser) rid 房间 ID,cid 客户端 ID,rwc WebSocket 连接 error 将客户端注册到指定房间,如果房间不存在则创建。
(rt *roomTable) deregister(rid string, cid string) rid 房间 ID,cid 客户端 ID 注销客户端的 WebSocket 注册,但保留客户端对象,等待超时后自动移除,以便用户可无缝重连。
(rt *roomTable) removeIfUnregistered(rid string, c *client) rid 房间 ID,客户端对象 超时检查函数,如果客户端在超时时间内未注册,则移除该客户端。
(rt *roomTable) wsCount() int 返回当前所有房间中活跃 WebSocket 连接总数。

room.go

方法名 参数 返回值 作用说明
(rm *room) client(clientID string) 客户端 ID *client, error 获取房间内指定客户端,如果不存在且房间未满则创建新客户端;设置注册超时定时器,超时未注册则由父 roomTable 删除。
(rm *room) register(clientID string, rwc io.ReadWriteCloser) 客户端 ID,WebSocket 连接对象 error 将客户端绑定到 WebSocket 连接;注册后如果房间有其他客户端,则发送队列消息给新客户端。
(rm *room) send(srcClientID string, msg string) 发送方客户端 ID,消息内容 error 将消息发送给房间内另一客户端;如果另一客户端未加入,则将消息入队等待。
(rm *room) remove(clientID string) 客户端 ID 移除指定客户端,关闭连接;向房间服务器发送 BYE 请求;从 clients map 删除客户端。
(rm *room) empty() bool 判断房间是否为空(没有客户端)。
(rm *room) wsCount() int 统计房间内已注册的 WebSocket 客户端数量,用于全局统计。

client.go

方法 作用
newClient 创建 client
setTimer 设置重连计时器(会停止旧 timer)
register 注册 WebSocket 连接
deregister 清理 WebSocket 连接
registered 是否已注册 WebSocket
enqueue 当前 client 出消息(发给别人)但对方不在线 → 缓存消息
sendQueued 把队列消息发送给对方(在对方连接时调用)
send 对外发送消息(如果对方在线就直接发,否则缓存)

messages.go

方法名 参数 作用说明
sendServerMsg(w io.Writer, msg string) w: WebSocket writer、msg: 要发送的消息内容 构造 wsServerMsg{Msg: msg} 并发送给客户端(JSON 格式)
sendServerErr(w io.Writer, errMsg string) w: WebSocket writer、errMsg: 错误消息 构造 wsServerMsg{Error: errMsg} 并发送给客户端(JSON 格式)
send(w io.Writer, data interface{}) w: writer(通常是 websocket.Conn)data: 任意结构体 将结构体序列化成 JSON 写入 WebSocket;底层通用发送函数