最近在实现兼容WebRTC的信令服务器,所以重新把Collider的源代码看了一遍。 Collider的代码是用Golang完成的,Golang和C语言类似,只需要把Golang语言了解一遍就能看懂代码。 目录结构体图:
主要的功能实现都在Collider.go这里实现的,从目录结构上来看,信令服务器主要有两个类:Client和Room,从字面意义来看就是客户和房间的概念。
Collider的主入口函数:
// Run starts the collider server and blocks the thread until the program exits.
func (c *Collider) Run(p int, useTls bool) {
http.Handle("/ws", websocket.Handler(c.wsHandler))
http.HandleFunc("/status", c.httpStatusHandler)
http.HandleFunc("/", c.httpHandler)
主要的处理函数为 c.wsHandler 和 c.httpHandler,前面的接收websocket的命令,后面一个是接收Http的命令。
首先是c.wsHandler这个函数:
func (c *Collider) wsHandler(ws *websocket.Conn) {
var rid, cid string
registered := false
var msg wsClientMsg
loop:
for {
err := ws.SetReadDeadline(time.Now().Add(time.Duration(wsReadTimeoutSec) * time.Second))
//这里我删除了一些代码,让博文紧凑些
err = websocket.JSON.Receive(ws, &msg)
//这里我删除了一些代码,让博文紧凑些
switch msg.Cmd {
case "register":
//这里我删除了一些代码,让博文紧凑些
break
case "send":
//这里我删除了一些代码,让博文紧凑些
c.roomTable.send(rid, cid, msg.Msg)
break
default:
c.wsError("Invalid message: unexpected 'cmd'", ws)
break
}
}
// This should be unnecessary but just be safe.
ws.Close()
}
从代码我们看出,主要是实现了用户注册和给房间内其他用户发送实时消息的功能,具体的命令格式都是Json组包的,自己可以抓个包查看一下。我的抓包:
另一个是处理HTTP的POST请求的,可以给指定房间内用户发送消息或者删除指定用户。
// httpHandler is a HTTP handler that handles GET/POST/DELETE requests.
// POST request to path "/$ROOMID/$CLIENTID" is used to send a message to the other client of the room.
func (c *Collider) httpHandler(w http.ResponseWriter, r *http.Request) {
//这里我删除了一些代码,让博文紧凑些
p := strings.Split(r.URL.Path, "/")
if len(p) != 3 {
c.httpError("Invalid path: "+html.EscapeString(r.URL.Path), w)
return
}
rid, cid := p[1], p[2]
switch r.Method {
case "POST":
body, err := ioutil.ReadAll(r.Body)
//这里我删除了一些代码,让博文紧凑些
if err := c.roomTable.send(rid, cid, m); err != nil {
c.httpError("Failed to send the message: "+err.Error(), w)
return
}
case "DELETE":
c.roomTable.remove(rid, cid)
default:
return
}
io.WriteString(w, "OK\n")
}
这两个函数基本上解决了常用的功能,可以完成一对一的呼叫和发送消息。