最近在实现兼容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 wsClientMsgloop: 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")}
这两个函数基本上解决了常用的功能,可以完成一对一的呼叫和发送消息。