package main import ( "encoding/json" "log" "net" "sync" ) func handleConnection(conn net.Conn) { defer conn.Close() // 1 мегабайт var maxBodySize uint32 = 1048576 maxAuthAttempts := 5 authAttempts := 0 authenticated := false buf := make([]byte, 4096) for { if authAttempts >= maxAuthAttempts { resp, _ := json.Marshal(Response{ Status: FAILURE, Data: "Превышено количество неавторизованных запросов", }) _ = sendMessage(conn, resp) break } _, err := conn.Read(buf) if err != nil { break } size := fromBytes(buf[:4]) if size > maxBodySize { resp, _ := json.Marshal(Response{ Status: FAILURE, Data: "Превышен максимальный размер запроса", }) _ = sendMessage(conn, resp) break } rawMessage := buf[4 : size+4] message := parseMessage(rawMessage) if message.Type == AUTHENTICATE { // TODO(andrew): Добавить процесс аутентификации if true { authenticated = true resp, _ := json.Marshal(Response{ Status: SUCCESS, Data: "Аутентификация прошла успешно", }) _ = sendMessage(conn, resp) } else { resp, _ := json.Marshal(Response{ Status: FAILURE, Data: "При аутентификации произошла ошибка", }) _ = sendMessage(conn, resp) } continue } if !authenticated { resp, _ := json.Marshal(Response{ Status: FAILURE, Data: "Для работы с сервером необходима аутентификация", }) err = sendMessage(conn, resp) if err != nil { break } authAttempts += 1 continue } if message.Data == "exit" { break } resp, _ := json.Marshal(Response{ Status: SUCCESS, Data: "some data", }) err = sendMessage(conn, resp) if err != nil { break } } } func reader(c chan Message) { const maxMessages uint64 = 1024 var count uint64 = 0 for { data := <-c received.Lock() if count >= maxMessages { received.data = []Message{data} received.messageShift += maxMessages } else { received.data = append(received.data, data) count += 1 } received.Unlock() } } func handleSender(conn net.Conn) { received.Lock() lastIndex := received.messageShift received.Unlock() for { var message Message received.Lock() idx := lastIndex - received.messageShift if idx <= uint64(len(received.data)) { message = received.data[idx] } received.Lock() resp, _ := json.Marshal(Response{ Status: SUCCESS, Data: message.serialize(), }) _ = sendMessage(conn, resp) } } var received struct { sync.Mutex data []Message messageShift uint64 } func main() { var wg sync.WaitGroup c := make(chan Message) go reader(c) sock, err := net.Listen("tcp", "localhost:8080") handleError(err) defer sock.Close() wg.Add(1) go func(sock net.Listener) { for { conn, err := sock.Accept() if err == nil { go handleConnection(conn) } else { break } } wg.Done() }(sock) senderSock, err := net.Listen("tcp", "localhost:8081") handleError(err) defer senderSock.Close() wg.Add(1) go func(sock net.Listener) { for { conn, err := sock.Accept() if err == nil { go handleSender(conn) } else { break } } wg.Done() }(senderSock) wg.Wait() } func handleError(err error) { if err != nil { log.Fatal(err) } }