Flutter, как слушать ответ веб-сокета?

Как мы все знаем, у flutter есть пример использования websocket, но он просто получает ответ websocket в виде потока и примерно так:

new StreamBuilder(
  stream: widget.channel.stream,
  builder: (context, snapshot) {
    return new Text(snapshot.hasData ? '${snapshot.data}' : '');
  },
);

Мне нужна асинхронная функция, которая получает каждый ответ веб-сокета и добавляет результат в список, чтобы можно было обновить список.

Как в любом случае получить ответ веб-сокета в виде текста или json?

Обновлять: Я знаю, что сейчас есть такой метод, как stream.listen:

widget.channel.stream.listen((data) {
  print("!!!!new msg: $data");
  var dataJson = json.decode(data);
  print(dataJson["content"]);
  // do something after received data
  setState(() {
    _allAnimateMessages.insert(0, newMsg);
  });
  newMsg.animationController.forward();
});

Это может работать на странице, но при повторном входе на эту страницу возникла ошибка Bad state: Stream has already been listened to.. Как сделать так, чтобы поток можно было слушать при каждом запуске, а затем транслировать на множество страниц?

Вы пробовали вернуть ListView.builder внутри StreamBuilder?

Tree 23.05.2018 05:59

Если вы напишете свой бэкэнд websocket, вы можете заставить его возвращать полный список каждый раз, когда он обновляется, тогда я могу написать вам решение для этого. Если он возвращает один элемент за другим, вам нужно создать локальный список, в который вы будете добавлять свои снимки, а затем использовать построитель списка

Tree 23.05.2018 06:03

@Tree Привет, я использую веб-сокет для чата, так что серверы возвращаются один за другим, мне нужен прослушиваемый поток и трансляция на любую страницу, которая мне нужна, этот поток (идентифицируйте их с адресом отправителя), это что-то просто как приложение чата как телеграмма

Nicholas Jela 23.05.2018 06:29

Вы нашли решение?

stt106 28.11.2018 12:04

@ stt106 Еще нет, websokcet получал данные много раз, каждый раз при обновлении пользовательского интерфейса ...

Nicholas Jela 08.12.2018 16:42
Альтернативные WebSockets для netty/java: удвоение пропускной способности небольших сообщений
Альтернативные WebSockets для netty/java: удвоение пропускной способности небольших сообщений
Этот пост - краткая презентация netty-websocket-http1 - альтернативной netty/java реализации RFC6455 - протокола WebSocket.
Очень простая установка Websocket с помощью Deno без каких-либо пакетов
Очень простая установка Websocket с помощью Deno без каких-либо пакетов
Здесь мы рассмотрим, как можно использовать Websocket в Deno и развернуть его в Deno deploy. Мы будем слушать Websocket, а также отправлять сообщения.
4
5
5 947
2

Ответы 2

What I am want is an async function which receives every websocket response and append the result to a list, so that the listview can be updated.

Вам нужно управлять этим самостоятельно в своем государственном классе.

final list = List<Message>();

@override
Widget build(BuildContext context) {
  return new StreamBuilder(
    stream: myStream,
    builder: (context, snapshot) {
      list.add(/* extract message from snapshot */);
      /* build a widget with your list */
    },
  );
}

when enter that page again, there was an error says Bad state: Stream has already been listened to.. How to make the stream can be listened at every begaining, and then boradcast to many pages?

Dart имеет два вида потоков, однократную подписку и широковещательные потоки. См. Дополнительную информацию о различия и о том, как создавать потоки. Рекомендации здесь во многом будут зависеть от вашего приложения.

Тем не менее, обычно apis, которые возвращают поток по умолчанию для одиночной подписки, а затем имеют альтернативу asBroadcastStream().

Если это не вариант, вы можете создать промежуточный StreamController, который прослушивает ваш поток с одной подпиской и возвращает широковещательный поток, который должна прослушивать остальная часть вашего приложения.

Оба эти варианта описаны в приведенной выше ссылке о создании потоков.

Убедитесь, что вы закрываете соединение WebSocket, когда покидаете текущий виджет. Внутри класса State вашего виджета у вас должен быть метод dispose(), который выглядит следующим образом:

@override
void dispose() {
  widget.channel.sink.close();
  super.dispose();
}

Если та страница закрылась, как получить на другой странице? (если я создаю приложение для чата, сообщения должны приходить везде)

Nicholas Jela 08.12.2018 16:43

Другие вопросы по теме