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
}
Другие вопросы по тегам