package main import ( "bufio" "encoding/json" "fmt" "log" "net" "os" "sync" ) var storage struct { sync.Mutex messages []Message } func parseBuffer(previous []byte, new []byte) ([]Response, []byte) { buf := append(previous, new...) bufSize := uint32(len(buf)) var responses []Response var idx uint32 = 0 for { if idx+4 >= bufSize { break } size := fromBytes(buf[idx : idx+4]) if size == 0 { return responses, make([]byte, 0) } if idx+4+size >= bufSize { break } else { resp, err := parseResponse(buf[idx+4 : idx+4+size]) if err == nil { responses = append(responses, resp) } idx += 4 + size } } return responses, buf[idx:] } 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 main() { var wg sync.WaitGroup conn, err := net.Dial("tcp", "localhost:8080") handleError(err) defer conn.Close() wg.Add(1) go func(conn net.Conn) { authMsg, _ := json.Marshal(Message{ Type: AUTHENTICATE, Data: "auth", User: "andrew", }) _ = sendMessage(conn, authMsg) reader := bufio.NewReader(os.Stdin) for i := 0; i < 1000; i += 1 { //fmt.Printf("Sending %d request\n", i) line, _, _ := reader.ReadLine() request, _ := json.Marshal(Message{ Type: MESSAGE, //Data: fmt.Sprintf("Hello, %d", i), Data: string(line), User: "andrew", }) err = sendMessage(conn, request) if err != nil { break } response, _ := readResponse(conn) _ = fmt.Sprintf("%s", response) } exitMsg, _ := json.Marshal(Message{ Type: MESSAGE, Data: "exit", User: "andrew", }) _ = sendMessage(conn, exitMsg) fmt.Println("Closed connection") wg.Done() }(conn) receiver, err := net.Dial("tcp", "localhost:8081") handleError(err) defer receiver.Close() wg.Add(1) go func(conn net.Conn) { req := Message{ Type: AUTHENTICATE, Data: AUTHENTICATE, User: "andrew", } 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 } message, err := parseMessage([]byte(response.Data)) if err == nil { storage.Lock() storage.messages = append(storage.messages, message) fmt.Printf("Got message: \"%s\"\n", message.Data) storage.Unlock() } else { fmt.Println(err) } req := Message{ Type: MESSAGE, Data: SUCCESS, User: "andrew", } _ = sendMessage(conn, []byte(req.serialize())) } wg.Done() }(receiver) wg.Wait() } func handleError(err error) { if err != nil { log.Fatal(err) } }