package main import ( "encoding/json" "fmt" "fyne.io/fyne/v2/data/binding" "log" "net" "sync" ) var storage struct { sync.RWMutex messages []Request stringData []string data binding.ExternalStringList } type UserData struct { Username string } type Client struct { senderConn net.Listener receiverConn net.Listener } func readResponse(conn net.Conn) (Response, error) { var response Response var err error buf := make([]byte, 4096) _, err = conn.Read(buf) if err != nil { return response, err } size := fromBytes(buf[:4]) rawResponse := buf[4 : size+4] return parseResponse(rawResponse) } func sender(conn net.Conn, wg *sync.WaitGroup, user UserData, c chan string) { var err error authMsg, _ := json.Marshal(Request{ Type: AUTHENTICATE, Data: AUTHENTICATE, User: user.Username, }) _ = sendMessage(conn, authMsg) for { line := <-c channelLock.Unlock() request, _ := json.Marshal(Request{ Type: MESSAGE, Data: line, User: user.Username, }) err = sendMessage(conn, request) if err != nil { fmt.Printf("Error in sender: %s", err) break } response, _ := readResponse(conn) _ = fmt.Sprintf("%s", response) } exitMsg, _ := json.Marshal(Request{ Type: EXIT, Data: EXIT, User: user.Username, }) _ = sendMessage(conn, exitMsg) fmt.Println("Closed connection") wg.Done() } func receiver(conn net.Conn, wg *sync.WaitGroup, user UserData) { var err error req := Request{ Type: AUTHENTICATE, Data: AUTHENTICATE, User: user.Username, } err = sendMessage(conn, []byte(req.serialize())) if err != nil { fmt.Println(err) return } _, err = readResponse(conn) if err != nil { return } for { response, err := readResponse(conn) if err != nil { break } if response.Status == PING { req := Request{ Type: PING, Data: SUCCESS, User: user.Username, } _ = sendMessage(conn, []byte(req.serialize())) continue } message, err := parseRequest([]byte(response.Data)) if err == nil { storage.Lock() //storage.messages = append(storage.messages, message) _ = storage.data.Append(message.toString()) storage.Unlock() } else { fmt.Println(err) } req := Request{ Type: MESSAGE, Data: SUCCESS, User: user.Username, } _ = sendMessage(conn, []byte(req.serialize())) } wg.Done() } func runClient(user UserData, c chan string) { var wg sync.WaitGroup senderConn, err := net.Dial("tcp", "localhost:8080") handleError(err) defer senderConn.Close() wg.Add(1) receiverConn, err := net.Dial("tcp", "localhost:8081") handleError(err) defer receiverConn.Close() wg.Add(1) go sender(senderConn, &wg, user, c) go receiver(receiverConn, &wg, user) wg.Wait() } func handleError(err error) { if err != nil { log.Fatal(err) } }