Как создать потоковый API для подписки на flutter?

#flutter #api #express #stream

#flutter #API #экспресс #поток

Вопрос:

Я пытаюсь получить сообщение от API, который я встроил в express в Flutter.

Дело в том, что для получения моих сообщений мне пришлось создать streambuilder, потому что я хочу, чтобы список сообщений обновлялся при появлении новых сообщений. Для достижения этой цели создайте метод steam, который проверяет API каждые x секунд.

   Stream<List<Message>> streamMessage() async* {
    final storage = FlutterSecureStorage();
    var json = (await storage.read(key: 'user'))!;
    User user = User.fromJson(jsonDecode(json));
    jwt = user.jwt;

    yield* Stream.periodic(const Duration(seconds: 3), (_) async {
      http.Response response = await http.get(
          Uri.parse("https://myapi.com/messages"),
          headers: {
            'Authorization': 'Bearer $jwt',
          });

      List<Message> messages = [];
      if (response.statusCode == 200) {
        var list = List.from(jsonDecode(response.body)).reversed;
        messages = list.map((e) => Message.fromJson(e)).toList();
      } else {
        log("Error : ${response.statusCode} -- ${response.reasonPhrase}");
      }
      return messages;
    }).asyncMap(
      (value) async => await value,
    );
  }
 

Это работает, но у него много проблем.

  • обновление происходит не так быстро, как я хочу
  • это много запросов ни за что
  • API может быть легко перегружен
  • Этот способ больше похож на обходной путь, чем на реальную функцию

Я хотел бы создать механизм в своем бэкэнде, который больше походил бы на подписку на реальный поток. Как это работает с Firebase. Но я понятия не имею, как это работает или даже что искать.

Если у вас есть какие-либо подсказки, как я могу этого добиться?

Ответ №1:

Вы могли бы достичь этого с помощью websockets, для чего потребуется некоторая настройка вашего приложения node и вашего приложения Flutter.

Я бы предложил использовать сокет Flutter.клиент ввода-вывода и сокет узла.сервер ввода-вывода.

Обратите внимание, что стабильная версия клиента flutter не соответствует текущей версии сервера узла. Вы можете использовать бета-версию 2 клиента flutter или более старую версию сервера.

В прошлый раз, когда я это настраивал, я выбрал последнее. Version 1.01 клиент определенно работает с узловым сервером version 2.4.1 .

Вот простой пример с виджетом с отслеживанием состояния, но если вы хотите использовать StreamBuilder , на странице client pub.dev есть пример. Его можно привязать к любому решению для управления состоянием.

 class SocketExample extends StatefulWidget {
  const SocketExample({Key? key}) : super(key: key);

  @override
  _SocketExampleState createState() => _SocketExampleState();
}

class _SocketExampleState extends State<SocketExample> {
  static const _sockerURL = 'your node app url';

  static const _socketEvent = 'event_1';

  final _socket = IO.io(sockerURL, <String, dynamic>{
    "transports": ["websocket"],
    "autoConnect": false,
  });

  @override
  void initState() {
    super.initState();
    _socket.connect();
    _socket.onConnect((data) {
      log('Connected ${_socket.connected}');
    });
    _socket.on(socketEvent, (message) {
      // whatever needs to happen when you get an event from the server
      // put it here
    });
  }

 @override
  void dispose() {
    _socket.disconnect();
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return ...
  }
}
 

И базовая настройка на стороне узла будет выглядеть примерно так

 const server = http.createServer(app);
const io = require("socket.io")(server);

const socketEvent = "event_1"; // this string needs to correspond to the event in your flutter app

io.on("connection", (socket) => {
  socket.on(socketEvent, (msg) => {
    io.emit(socketEvent, msg);

    console.log("message: "   msg);
  });
});
 

Затем в зависимости от GET / POST и т. Д… вам нужно в узле, с которым вы отправляете сообщение для Flutter

  io.emit(socketEvent, whatever the payload to your Flutter app is goes here);

 

Это практически все, что вам нужно сделать, чтобы получать обновления во Flutter в режиме реального времени из приложения узла без ручного обновления или проверки API с любым интервалом.