Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗goSpWsEx 264 of 280 menu
◀ ▶

Обмен сообщениями WebSocket в Go

После перевода запроса обмен идет кадрами. Для обычного текста берут тип текстового сообщения из пакета библиотеки и срез байтов с английской фразой. Отправка и прием возвращают ошибку сети или протокола, их проверяют так же, как при записи в TCP.

Прием возвращает тип кадра, байты и ошибку. Для учебного эха достаточно прочитать один кадр, собрать ответ из префикса и текста клиента и отправить обратно до закрытия канала.

Сервер отвечает префиксом "echo: ", клиент шлет "hello" и печатает ответ:

package main import ( "fmt" "log" "net/http" "time" "github.com/gorilla/websocket" ) func echoServer() { upgrader := websocket.Upgrader{} http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println(err) return } defer conn.Close() _, msg, err := conn.ReadMessage() if err != nil { log.Println(err) return } out := append([]byte("echo: "), msg...) err = conn.WriteMessage(websocket.TextMessage, out) if err != nil { log.Println(err) } }) log.Fatal(http.ListenAndServe("127.0.0.1:8080", nil)) } func main() { go echoServer() time.Sleep(20 * time.Millisecond) url := "ws://127.0.0.1:8080/ws" conn, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { log.Fatal(err) } defer conn.Close() err = conn.WriteMessage(websocket.TextMessage, []byte("hello")) if err != nil { log.Fatal(err) } _, reply, err := conn.ReadMessage() if err != nil { log.Fatal(err) } fmt.Println(string(reply)) }

На экране клиента "echo: hello". Сервер прочитал текст, собрал ответ и отправил его в том же соединении.

Клиент может сначала отправить другое слово, порядок шагов тот же:

package main import ( "fmt" "log" "net/http" "time" "github.com/gorilla/websocket" ) func echoServer() { upgrader := websocket.Upgrader{} http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println(err) return } defer conn.Close() _, msg, err := conn.ReadMessage() if err != nil { return } out := append([]byte("echo: "), msg...) _ = conn.WriteMessage(websocket.TextMessage, out) }) log.Fatal(http.ListenAndServe("127.0.0.1:8080", nil)) } func main() { go echoServer() time.Sleep(20 * time.Millisecond) conn, _, err := websocket.DefaultDialer.Dial("ws://127.0.0.1:8080/ws", nil) if err != nil { log.Fatal(err) } defer conn.Close() _ = conn.WriteMessage(websocket.TextMessage, []byte("ping")) _, reply, err := conn.ReadMessage() if err != nil { log.Fatal(err) } fmt.Println(string(reply)) }

Дано сообщение клиента:

line := "ask"

На сервере после чтения текстового кадра отправьте клиенту строку "reply: ask", если в байтах было ровно line.

Дан путь:

path := "/ws"

Клиент отправляет "go" на ws://127.0.0.1:8080 с этим путем; сервер возвращает "echo: go". Опишите порядок чтения и отправки на стороне сервера.

Скажите, почему для английской фразы удобно передавать []byte("hello"), а не один символ типа rune.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить