go 及时通信-用户消息广播
作者:互联网
package main import ( "fmt" "io" "net" "sync" ) //构件server type Server struct { Ip string Port int //在线用户列表 OnlineMap map[string]*User MapLock sync.RWMutex //消息 Message chan string } //提供一个对外的接口 func NewServer(ip string, port int) *Server { server := &Server{ Ip: ip, Port: port, OnlineMap: make(map[string]*User), Message: make(chan string), } return server } //发送消息 func (this *Server) BroadCast(user *User, msg string) { sendMsg := "[" + user.Addr + "]" + ":" + msg this.Message <- sendMsg } func (this *Server) Handler(conn net.Conn) { // fmt.Println("链接成功") user := NewUser(conn) //用户上线 this.MapLock.Lock() this.OnlineMap[user.Addr] = user this.MapLock.Unlock() //发送消息 this.BroadCast(user, "shangxianle") //接收客户端消息并发送 go func() { buf := make([]byte, 5000) for { //读取输入 n, err := conn.Read(buf) if n == 0 { //用户下线 this.BroadCast(user, "xianxianle") return } if err != nil && err != io.EOF { fmt.Println("conn read err:", err) return } msg := string(buf) this.BroadCast(user, msg) } }() //阻塞 select {} } //监听channel func (this *Server) ListMessager() { for { msg := <-this.Message //发送每个用户channel this.MapLock.Lock() for _, cli := range this.OnlineMap { cli.C <- msg } this.MapLock.Unlock() } } //启动 func (this *Server) start() { //监听客户端 listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", this.Ip, this.Port)) if err != nil { fmt.Println("listener err:", err) return } //关闭 defer listener.Close() go this.ListMessager() for { //连接 conn, err := listener.Accept() if err != nil { fmt.Println("conn err:", err) continue } //启动go handler操作 go this.Handler(conn) } }
标签:string,int,用户,Server,广播,User,go,Message,server 来源: https://www.cnblogs.com/alway-learn/p/16091939.html