Stream 在Dart中创建圆形流

Stream 在Dart中创建圆形流,stream,dart,Stream,Dart,我尝试编写一个聊天应用程序来与计算机聊天。用户可以编写消息并获得计算机的响应。聊天记录可能如下所示: user: Hi computer: Hello user: What's your name? computer: Bot ... 我的基于循环流的设计灵感来自于。我得到了一个用户消息流,它被转换成一个计算机消息流,而计算机消息流又是用户消息流的输入: |----> user message stream ---->| |

我尝试编写一个聊天应用程序来与计算机聊天。用户可以编写消息并获得计算机的响应。聊天记录可能如下所示:

user: Hi
computer: Hello
user: What's your name?
computer: Bot
...
我的基于循环流的设计灵感来自于。我得到了一个用户消息流,它被转换成一个计算机消息流,而计算机消息流又是用户消息流的输入:

    |----> user message stream ---->|
    |                               |
transform                       transform
    |                               |
    |<-- computer message stream <--|
实际上,这个逻辑属于我的函数
user
,因为
cycle
不应该知道初始值。此外,我不喜欢打印初始值。它应该只触发用户输入流。因此,我改变了
循环
用户

void cycle(Transform aToB, Transform bToA) {
  var aProxy = new StreamController.broadcast();
  var b = aToB(aProxy.stream);
  var a = bToA(b);
  aProxy.addStream(a);
}

Stream<String> user(Stream<String> computerMessages) {
  computerMessages = computerMessages.asBroadcastStream();
  computerMessages.listen((message) => print('computer: $message'));
  var requestInput = new StreamController<String>.broadcast();
  requestInput.add('start'); // start with user
  requestInput.addStream(computerMessages); // continue on computer response
  return requestInput.stream.map((message) {
    stdout.write('user: ');
    return stdin.readLineSync();
  });
}
void循环(转换aToB,转换bToA){
var aProxy=new StreamController.broadcast();
var b=aToB(含氧气流);
var a=bToA(b);
a.添加流(a);
}
流用户(流计算机消息){
computerMessages=computerMessages.asBroadcastStream();
computerMessages.listen((message)=>print('computer:$message');
var requestInput=new StreamController.broadcast();
requestInput.add('start');//从用户开始
requestInput.addStream(computerMessages);//继续计算机响应
返回requestInput.stream.map((消息){
write('user:');
返回stdin.readLineSync();
});
}

但是有了这个更改,我的应用程序立即终止,stdout中没有消息。怎么了?

我找到了解决办法。在
用户
中创建普通而非广播
流控制器

Stream<String> user(Stream<String> computerMessages) {
  computerMessages = computerMessages.asBroadcastStream();
  computerMessages.listen((message) => print('computer: $message'));
  var requestInput = new StreamController<String>();
  requestInput.add('start'); // start with user
  requestInput.addStream(computerMessages); // continue on computer response
  return requestInput.stream.map((message) {
    stdout.write('user: ');
    return stdin.readLineSync();
  });
}
流式用户(流式计算机消息){
computerMessages=computerMessages.asBroadcastStream();
computerMessages.listen((message)=>print('computer:$message');
var requestInput=new StreamController();
requestInput.add('start');//从用户开始
requestInput.addStream(computerMessages);//继续计算机响应
返回requestInput.stream.map((消息){
write('user:');
返回stdin.readLineSync();
});
}

尽管我找到了解决方案,但遗憾的是,我无法真正解释广播
流控制器的问题所在
null
通过
requestInput.add(null)成功添加requestInput.addStream(computerMessages)完成,也不会将
计算机消息
的事件添加到
请求输入
。因此,
requestInput
关闭,应用程序终止。如果有人能提供进一步的解释,我将不胜感激。

我没有试图完全理解代码的作用。我怀疑您需要将
aProxy
a
b
(或至少其中一个)作为顶级变量。原始变量不起作用的原因是在执行
map
调用之前添加了
“start”
字符串。广播流不缓冲事件(它们的订阅在暂停时缓冲,但流本身不缓冲),因此,由于当时没有订阅者,事件被丢弃。
void cycle(Transform aToB, Transform bToA) {
  var aProxy = new StreamController.broadcast();
  var b = aToB(aProxy.stream);
  var a = bToA(b);
  aProxy.addStream(a);
}

Stream<String> user(Stream<String> computerMessages) {
  computerMessages = computerMessages.asBroadcastStream();
  computerMessages.listen((message) => print('computer: $message'));
  var requestInput = new StreamController<String>.broadcast();
  requestInput.add('start'); // start with user
  requestInput.addStream(computerMessages); // continue on computer response
  return requestInput.stream.map((message) {
    stdout.write('user: ');
    return stdin.readLineSync();
  });
}
Stream<String> user(Stream<String> computerMessages) {
  computerMessages = computerMessages.asBroadcastStream();
  computerMessages.listen((message) => print('computer: $message'));
  var requestInput = new StreamController<String>();
  requestInput.add('start'); // start with user
  requestInput.addStream(computerMessages); // continue on computer response
  return requestInput.stream.map((message) {
    stdout.write('user: ');
    return stdin.readLineSync();
  });
}