go chat room

中柠檬 · · 1287 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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)
				}
			}
		}
	}
}

 


有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:中柠檬

查看原文:go chat room

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1287 次点击  ∙  1 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传