Golang bufio из-за разрыва веб-сокета после первого чтения
Я пытаюсь передать текст JSON из веб-сокета. Однако после первоначального чтения я заметил, что поток, кажется, прерывается/отключается. Это с сервера Pleroma (думаю: Mastodon). Я использую библиотеку веб-сокетов Golang по умолчанию.
package main
import (
"bufio"
"fmt"
"log"
"golang.org/x/net/websocket"
)
func main() {
origin := "https://poa.st/"
url := "wss://poa.st/api/v1/streaming/?stream=public"
ws, err := websocket.Dial(url, "", origin)
if err != nil {
log.Fatal(err)
}
s := bufio.NewScanner(ws)
for s.Scan() {
line := s.Text()
fmt.Println(line)
}
}
После начального текстового ответа JSON цикл for прерывается. Я ожидаю, что он будет отправлять новое сообщение каждые несколько секунд.
Что может быть причиной этого? Я готов перейти на библиотеку веб-сокетов Gorilla, если смогу использовать ее с
Спасибо!
1 ответ
Хотя соединение x/net/websocket имеет метод Read с той же сигнатурой, что и метод Read в io.Reader, соединение не работает как io.Reader. Соединение не будет работать так, как вы ожидаете, при обертывании с помощью bufio.Scanner.
Конечная точка poa.st отправляет поток сообщений, каждое из которых представляет собой документ JSON. Используйте следующий код для чтения сообщений с помощью пакета Gorilla :
url := "wss://poa.st/api/v1/streaming/?stream=public"
ws, _, err := websocket.DefaultDialer.Dial(url, nil)
if err != nil {
log.Fatal(err)
}
defer ws.Close()
for {
_, p, err := ws.ReadMessage()
if err != nil {
log.Fatal(err)
}
// p is a []byte containing the JSON document.
fmt.Printf("%s\n", p)
}
В пакете Gorilla есть вспомогательный метод для декодирования сообщений JSON. Вот пример использования этого метода.
url := "wss://poa.st/api/v1/streaming/?stream=public"
ws, _, err := websocket.DefaultDialer.Dial(url, nil)
if err != nil {
log.Fatal(err)
}
defer ws.Close()
for {
// The JSON documents are objects containing two fields,
// the event type and the payload. The payload is a JSON
// document itself.
var e struct {
Event string
Payload string
}
err := ws.ReadJSON(&e)
if err != nil {
log.Fatal(err)
}
// TODO: decode e.Payload based on e.Event
}