func run() error { engine := qml.NewEngine() component, err := engine.LoadFile("chat.qml") if err != nil { fmt.Println("no file to load for ui") fmt.Println(err.Error()) os.Exit(0) } context := engine.Context() context.SetVar("ctrl", &ctrl) win := component.CreateWindow(nil) win.Show() //show window ctrl.Root = win.Root() go ctrl.StartControlLoop() ctrl.UpdatedTextToUI <- "Hello " + peer.MyName + ".\nFor private messages, type the message followed by * and the name of the receiver.\n To leave the conversation type disconnect" go peer.RunServer(ctrl.UpdatedTextToUI, ctrl.UpdateUserList) if os.Args[1] != utils.GetMyIP() { go peer.IntroduceMyself(os.Args[1]) } //connect to the first peer win.Wait() closing := peer.Message{"DISCONNECT", peer.MyName, utils.GetMyIP(), "", make([]string, 0), make([]string, 0)} closing.Send() return nil }
// IntroduceMyself introduces peer to the chat func IntroduceMyself(IP string) { log.Println("introduceMyself") conn := createConnection(IP) enc := json.NewEncoder(conn) intromessage := Message{"CONNECT", MyName, utils.GetMyIP(), "", make([]string, 0), make([]string, 0)} // log.Println("sending message: ", intromessage) err := enc.Encode(intromessage) if err != nil { log.Printf("Could not encode msg : %s", err) } go receive(conn) }
// connects with everyone in the chat. // The Message passed in contains a list of users and ips func connectToPeers(msg Message) { for index, ip := range msg.IPs { conn := createConnection(ip) mutex.Lock() usersIPsMap[msg.Usernames[index]] = ip usersConnectionsMap[msg.Usernames[index]] = conn mutex.Unlock() } users, _ := utils.GetFromMap(usersIPsMap) updateUserListChan <- users addMessage := Message{"ADD", MyName, utils.GetMyIP(), "", make([]string, 0), make([]string, 0)} addMessage.Send() }
// handle a connection with a new peer func handleConnect(msg Message, conn net.Conn) bool { log.Println("handleConnect") Users, IPs := utils.GetFromMap(usersIPsMap) Users = append(Users, MyName) //add my name to the list IPs = append(IPs, utils.GetMyIP()) //add my ip to the list response := Message{"LIST", "", "", "", Users, IPs} if _, usernameTaken := usersIPsMap[msg.Username]; usernameTaken { response.MSG = "Username already taken, choose another one that is not in the list" response.Send() return false } mutex.Lock() usersIPsMap[msg.Username] = msg.IP usersConnectionsMap[msg.Username] = conn mutex.Unlock() log.Println(usersConnectionsMap) response.SendPrivToUser(msg.Username, updateTextChan) return true }