/**************************************************** *@function Write(serverAddr string) ***************************************************** *@brief 本地输入接口,绑定本地唯一发送端口 加开一个进程,用于发送心跳,维护在线状态 ***************************************************** *@access Public ***************************************************** *@param 无 ***************************************************** *@return 无 *****************************************************/ func (u *User) Write(groupCh chan string, logger *log.Logger) { runtime.GOMAXPROCS(runtime.NumCPU()) //开启进程,定时发送心跳,维护在线 go func(beatPort string, userName string) { HeartBeat(beatPort, userName) }(u.chatPort, u.name) //接收用户输入并发送 inputCh := make(chan string) go func(ch chan string) { buffer := make([]byte, 1024) for { fmt.Printf("<%s>:", u.name) count, err := os.Stdin.Read(buffer) if err != nil { fmt.Println(err) } str := strings.TrimSpace(strings.TrimSpace(string(buffer[:count]))) ch <- str } }(inputCh) var mess Message chatUdpAddr, _ := net.ResolveUDPAddr("udp", u.chatPort) chatConn, err := net.DialUDP("udp", nil, chatUdpAddr) for { //并发逻辑,收到group命令后,输入内容发送给client /******************************************************* 存在一个问题是,与服务器之间的通信时在default中, 发送完group之后进入default中,等待下一个输入 解决办法: ******************************************************/ select { case groupInfo := <-groupCh: { if groupInfo != "quit" { //收到回话要求 groupList := strings.Split(groupInfo, "/") remoteUdpAddr, _ := net.ResolveUDPAddr("udp", groupList[1]) remoteChatConn, err := net.DialUDP("udp", nil, remoteUdpAddr) if err != nil { logger.Panic(err) fmt.Println(err) } //fmt.Printf("chat with client:%s\n",groupList[2]) encoder := json.NewEncoder(remoteChatConn) quitFlag := false var mess Message for { if quitFlag { break } else { select { case str := <-inputCh: { if str == "quit" { quitFlag = true mess = Message{ Cmd: "quit", Sender: u.name, Data: "", Receiver: groupList[0], } } else { mess = Message{ Cmd: "chat", Sender: u.name, Data: str, Receiver: groupList[0], } } err := encoder.Encode(mess) if err != nil { fmt.Println(err) logger.Panic(err) } } case groupInfo := <-groupCh: { if groupInfo == "quit" { //退出会话,同时向服务器反馈 fmt.Printf("%s left the chatting\n", groupList[0]) quitFlag = true remoteChatConn.Close() mess = Message{ Cmd: "quit", Sender: u.name, Data: groupList[0], Receiver: "server", } encoder := json.NewEncoder(chatConn) err := encoder.Encode(mess) if err != nil { fmt.Println(err) logger.Panic(err) } } } } } } } } case str := <-inputCh: { fmt.Println(str) if err != nil { fmt.Println(err) logger.Panic(err) } sendFlag := false if str == "list" { mess = Message{ Cmd: str, Sender: u.name, Data: "", Receiver: "server", } sendFlag = true } else if str == "quit" { mess = Message{ Cmd: str, Sender: u.name, Data: "", Receiver: "server", } sendFlag = true } else { lists := strings.Split(str, " ") if lists[0] == "group" { if len(lists) == 2 { if lists[1] == u.name { //如果选着跟自己交谈,就没必要了吧 fmt.Println("you can talk to yourself without me") } else { mess = Message{ Cmd: lists[0], Sender: u.name, Data: strings.Join(lists[1:len(lists)], "/"), Receiver: "server", } sendFlag = true } } else { //暂时只有两人间的会话 fmt.Println("just support conversation between 2 clients") } } } if sendFlag { encoder := json.NewEncoder(chatConn) err := encoder.Encode(mess) if err != nil { fmt.Println(err) logger.Panic(err) } } } } } }