package main import ( "fmt" "io" "net" "sync" ) type Server struct { Ip string Port int OnlineMap map[string]*User // 在线用户列表 mapLock sync.RWMutex // OnlineMap读写锁 Message chan string // 全部用户的消息管道 } // 创建一个server的接口 func NewServer(ip string, port int) *Server { server := &Server{ Ip: ip, Port: port, OnlineMap: make(map[string]*User), Message: make(chan string), } return server } // server类的成员方法:监听Message广播消息channel的goroutine, 一旦有消息就发送给全部的在线User func (server *Server) ListenMessage() { for { msg := <-server.Message // 将msg发送给全部的在线User server.mapLock.Lock() for _, cli := range server.OnlineMap { cli.C <- msg } server.mapLock.Unlock() } } // server类的成员方法:向所有在线客户端发送广播 func (server *Server) BroadCast(user *User, msg string) { sendMsg := "[" + user.Addr + "]" + user.Name + ":" + msg server.Message <- sendMsg } // server类的成员方法:处理客户端连接 func (server *Server) Handler(conn net.Conn) { user := NewUser(conn) // 当前连接的业务 fmt.Println(user.Name, "客户端连接建立成功") // 用户上线, 将用户加入到OnlineMap中 server.mapLock.Lock() server.OnlineMap[user.Name] = user server.mapLock.Unlock() // 广播当前用户的上线消息 server.BroadCast(user, "已上线") // 接收客户端发送的消息 go func() { buf := make([]byte, 4096) for { n, err := conn.Read(buf) if n == 0 { server.BroadCast(user, "下线了") return } if err != nil && err != io.EOF { fmt.Println("Conn Read err:", err) return } // 提取用户的消息并去除"\n" msg := string(buf[:n-1]) // 将得到的消息进行广播 server.BroadCast(user, msg) } }() // 当前handler阻塞 select {} } // Server类的成员方法:启动服务器的接口 func (server *Server) Start() { // socket listen listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", server.Ip, server.Port)) if err != nil { fmt.Println("net.Listen err: ", err) } // close listen socket defer listener.Close() // 启动监听Message的goroutine go server.ListenMessage() // 死循环实现监听 for { // accept conn, err := listener.Accept() if err != nil { fmt.Println("listener accept err:", err) continue } // do handler go server.Handler(conn) } }