package main import ( "bytes" "encoding/json" "errors" "fmt" "fyne.io/fyne/v2/data/binding" "io" "net/http" "sync" "time" ) const ( Register = "/api/register" SendMessage = "/api/sendMessage" PollMessages = "/api/pollMessages" GetUserKey = "/api/getUserKey" TryAuth = "/api/tryAuth" ) var storage struct { sync.RWMutex messages []Message data []string binding binding.ExternalStringList } type Request struct { User string Data string } type Response struct { Message string } type Message struct { User string Data string Timestamp string } func (msg *Message) toString() string { return fmt.Sprintf("%s: %s", msg.User, msg.Data) } func makeRequest(request Request, apiMethod string, user UserData) (*http.Response, error) { signedRequest, err := signRequest(request, user.ParsedUserKey) if err != nil { return nil, err } reader := bytes.NewReader([]byte(signedRequest)) return http.Post(user.ServerUrl+apiMethod, "application/json", reader) } func sendMessage(user UserData, message string) { // TODO(andrew): Добавить отображение ошибки в интерфейс _, _ = makeRequest(Request{ User: user.Username, Data: message, }, SendMessage, user) } func register(user UserData, serverKey string) (Response, error) { var resp Response httpResp, err := makeRequest(Request{ User: user.Username, Data: serverKey, }, Register, user) if err != nil { return resp, err } body, _ := io.ReadAll(httpResp.Body) _ = json.Unmarshal(body, &resp) if httpResp.StatusCode == http.StatusOK { return resp, nil } else { return resp, errors.New(resp.Message) } } func tryAuth(user UserData) (bool, error) { var resp Response httpResp, err := makeRequest(Request{ User: user.Username, Data: "auth", }, TryAuth, user) if err != nil { return false, err } body, _ := io.ReadAll(httpResp.Body) _ = json.Unmarshal(body, &resp) if httpResp.StatusCode == http.StatusOK { return true, nil } else { return false, errors.New(resp.Message) } } func pingServer(user UserData) error { _, err := http.Get(user.ServerUrl) return err } func runClient(user UserData) { var lastPoll int64 = 0 for { httpResp, _ := makeRequest(Request{ User: user.Username, Data: fmt.Sprint(lastPoll), }, PollMessages, user) lastPoll = time.Now().UnixNano() if httpResp.StatusCode == http.StatusOK { body, _ := io.ReadAll(httpResp.Body) var resp Response _ = json.Unmarshal(body, &resp) var messages []Message _ = json.Unmarshal([]byte(resp.Message), &messages) storage.Lock() for _, msg := range messages { fmt.Printf("Polled new message from %s: %s (%s)\n", msg.User, msg.Data, msg.Timestamp) _ = storage.binding.Append(msg.toString()) storage.messages = append(storage.messages, msg) } storage.Unlock() } else { fmt.Println(httpResp.StatusCode) ae, _ := io.ReadAll(httpResp.Body) fmt.Println(string(ae)) } time.Sleep(100 * time.Millisecond) } }