【问题标题】:How to create a streaming API for flutter to subscribe to?如何创建流 API 以供 Flutter 订阅?
【发布时间】:2022-01-09 17:37:57
【问题描述】:

我正在尝试从我在 Flutter 中内置的快速 API 获取消息。

问题是,为了获取我的消息,我构建了一个流构建器,因为我希望消息列表能够根据新消息进行更新。为此,创建一个 Steam 方法,每 x 秒检查一次 API。

  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 一起使用。但我不知道它是如何工作的,甚至不知道要搜索什么。

如果您有任何提示,我该如何实现?

【问题讨论】:

    标签: flutter api express stream


    【解决方案1】:

    您可以使用 websockets 来实现这一点,这需要在您的节点应用程序和 Flutter 应用程序上进行一些配置。

    我建议使用Flutter socket.io clientnode socket.io server

    请注意,flutter客户端的稳定版本与node server的当前版本不同步。您可以使用 Flutter 客户端的 beta 版本 2 或服务器的旧版本。

    我上次设置时选择了后者。客户端的Version 1.01 绝对可以与节点服务器version 2.4.1 一起使用。

    这是一个有状态小部件的基本示例,但如果您想使用StreamBuilder,客户端 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。

    【讨论】:

      猜你喜欢
      • 2020-12-03
      • 1970-01-01
      • 1970-01-01
      • 2020-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多