Example #1
0
/****************************************************
*@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)
					}
				}
			}
		}
	}
}