Как мы все знаем, у 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..
Как сделать так, чтобы поток можно было слушать при каждом запуске, а затем транслировать на множество страниц?
Если вы напишете свой бэкэнд websocket, вы можете заставить его возвращать полный список каждый раз, когда он обновляется, тогда я могу написать вам решение для этого. Если он возвращает один элемент за другим, вам нужно создать локальный список, в который вы будете добавлять свои снимки, а затем использовать построитель списка
@Tree Привет, я использую веб-сокет для чата, так что серверы возвращаются один за другим, мне нужен прослушиваемый поток и трансляция на любую страницу, которая мне нужна, этот поток (идентифицируйте их с адресом отправителя), это что-то просто как приложение чата как телеграмма
Вы нашли решение?
@ stt106 Еще нет, websokcet получал данные много раз, каждый раз при обновлении пользовательского интерфейса ...


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();
}
Если та страница закрылась, как получить на другой странице? (если я создаю приложение для чата, сообщения должны приходить везде)
Вы пробовали вернуть ListView.builder внутри StreamBuilder?