如何异步与服务器通话?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何异步与服务器通话?相关的知识,希望对你有一定的参考价值。

我正在尝试在Dart中实现协议。基本上,我需要执行以下操作的多种方法:

  1. 向服务器发送消息
  2. 等待回复
  3. 使用该响应进行操作

它提出了两个问题:

  • 如何使所有方法都侦听同一套接字流? ((我一直在考虑暂停和恢复共享的StreamSubscription,但我认为这不起作用...)
  • 如何确定每种方法都将读取正确的响应,而不是另一种? (如果在服务器应答之前发送了多个请求)

欢迎任何建议;)

答案

具有进行实际通信的一项服务(即SocketService)。当某人想通过套接字发送消息时,它可以调用消息。然后公开其他用户可以订阅以侦听消息的流对象。

class SocketService {
  SocketService _instance;
  SocketService._();
  factory SocketService() {
    if (_instance == null) _instance = SocketService._();
    return _instance;
  }

  final _streamController = StreamController.broadcast();
  Stream get stream => _streamController.stream;

  Future init() async {
    // TODO: Initialize the socket connection
    // TODO: Setup incoming messages to get routed to _onMessage
  }

  void _onMessage(dynamic message) {
    _streamController.add(message);
  }

  StreamSubscription listen(void Function(dynamic) onMessage) {
    return stream.listen(onMessage);
  }

  void sendMessage(dynamic message) {
    // TODO: Send the message across the socket connection
  }

  void close() {
    // TODO: Close the socket connection
    _streamController.close();
  }
}

其他地方:

// Listen for incoming messages
var subscription = SocketService().subscribe((msg) {
  print(msg);
});

// Send a message
SocketService().sendMessage('This is a message');

特定于套接字的东西会有所不同,具体取决于您用来处理连接本身的软件包。上面将该服务类实现为过于简单的单例,以使您无法理解,但您可以自己使用所需的任何模式来实现此概念。

在子订阅服务器端,您还可以利用流转换来过滤除您实际感兴趣的消息以外的任何消息:

// Filter stream messages so only messages 
// that are string objects get printed
var subscription = SocketService().stream.where((msg) => msg is String).listen(msg) {
  print(msg);
});

传递给where方法的筛选谓词可以实现您想要的任何条件。

FYI:如果要在流和流操纵方面做很多事情,我强烈建议您使用rxdart软件包。与使用原始流相比,它使使用流更容易,更直观。

以上是关于如何异步与服务器通话?的主要内容,如果未能解决你的问题,请参考以下文章

导航抽屉异步任务

如何在CEF JS与browser进程间异步通信

使用 python 3.6 异步的 UDP 代理服务器

当片段视图加载是异步任务的一部分时,如何在片段加载之前显示进度条?

当活动中的异步任务完成时如何在片段中重新加载ui?

将同步代码包装成异步调用