ws 项目
项目概览
main 函数
func main() {
flag.Parse()
hub := newHub()
go hub.run()
http.HandleFunc("/", serveHome)
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
serveWs(hub, w, r)
})
err := http.ListenAndServe(*addr, nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
分析:
newHub() 返回一个 Hub结构.包含3个 channel,1个 map。这个map很特殊,当key用于存放 chan *Client。如果遍历,获得的是 Client。而 Client.send 是另一个 channel。
func newHub() *Hub {
return &Hub{
broadcast: make(chan []byte),
register: make(chan *Client),
unregister: make(chan *Client),
clients: make(map[*Client]bool),
}
}
hub.run() 使用基于 select的多路复用,分别获取 3 个 channel的值。进行各自的操作。
func (h *Hub) run() {
for {
select {
case client := <-h.register:
h.clients[client] = true
case client := <-h.unregister:
if _, ok := h.clients[client]; ok {//判断是否存在
delete(h.clients, client)
close(client.send)
}
case message := <-h.broadcast:
for client := range h.clients {//遍历 key,即 Client
select {
case client.send <- message://传递 message
default:
close(client.send)
delete(h.clients, client)
}
}
}
}
}
有疑问加站长微信联系(非本文作者)