go實現多聊天併發 服務端

package mainimport (   "fmt"   "net"   "time")type Client struct {   ch chan string //用戶發送數據的管道   name string //用戶名    addr string//網絡地址} var message = make(chan string) //用來保存用戶的消息//定義一個map 值爲在線的用戶var onlineClientMap map[string]Client//func main() {    listener,err := net.Listen("tcp","127.0.0.1:8000")    if err !=nil{      fmt.Println(err)    }    defer listener.Close()    go Manager()    //主協程,循環阻塞用戶鏈接   for{      conn, err := listener.Accept()      if err!=nil{         fmt.Println(err)         continue      }      go handleConn(conn)    }}func makeMsg(client Client,msg string)(buff string){      buff ="["+client.addr+"]"+client.name+":"+msg+"\n"      return}func handleConn(conn net.Conn){   cliAddr:= conn.RemoteAddr().String()   defer conn.Close()   client :=Client{      make(chan string),           cliAddr,            cliAddr,   }   onlineClientMap[cliAddr] = client   //給當前客戶端發送信息   go writeMsgToClient(client,conn)   //廣播某個在線   message<-"I am here\n"   message<- makeMsg(client,"login")   //是否主動退出   isQuit:=make(chan bool)   hasData:= make(chan bool)   //新開一個協程接收用戶發過來的數據   go func() {      buff:= make([]byte,2048)      for{         n,err :=conn.Read(buff)         fmt.Println(n)         if err!=nil{            fmt.Println(nil)         }         if n==0{            fmt.Println("斷開鏈接")            isQuit<-true            return         }         msg := string(buff[:n-1])         if len(msg)==3&& msg =="who"{            for _,tmp := range onlineClientMap{               msg = tmp.addr+":"+tmp.name+"\n"               conn.Write([]byte(msg))            }         }else{            message<-makeMsg(client,msg)         }         hasData<-true        }   }()   for{      select {      case <-isQuit:         delete(onlineClientMap,cliAddr)//當前用戶從map移除         message<-makeMsg(client,"login out")//廣播退出         return      case <-hasData:      case <-time.After(60*time.Second):         delete(onlineClientMap,cliAddr)//當前用戶從map移除         message<-makeMsg(client,"time out")//廣播退出         return      }         }}func Manager()  {   onlineClientMap = make(map[string]Client)//給map分配空間   for{         msg := <-message      for _ ,client :=range onlineClientMap{         client.ch<-msg      }   }}func writeMsgToClient(client Client,conn net.Conn)  {   for  msg:= range client.ch{         conn.Write([]byte(msg))      }}
相關文章
相關標籤/搜索