首页 > 解决方案 > 错误状态:StreamSink 已关闭

问题描述

我是 Dart 的新手,并尝试编写一些测试 Web 服务器。
在这里看不到任何问题,只是查看了文档,它就像一样。
如果有人知道如何解决这个问题,将非常感谢。

主要的

import 'dart:io';
import 'modules/TestModule.dart';

Future main() async {
  var server = await HttpServer.bind(
    InternetAddress.loopbackIPv4,
    1337,
  );

  print('Listening on localhost:${server.port}');

  await for (HttpRequest request in server) { 
    switch (request.uri.path) {
      case "/test":
        await testHandler(request);
      break;
      default:
    }
  }
}

测试模块

import 'dart:io';
Future<void> testHandler(HttpRequest req) async {
  await req.response
  ..write("hello")
  ..close();
}

日志

Bad state: StreamSink is closed
#0      _StreamSinkImpl.add (dart:_http/http_impl.dart:599:7)
#1      _HttpOutboundMessage.add (dart:_http/http_impl.dart:820:11)
#2      _IOSinkImpl.write (dart:_http/http_impl.dart:734:5)
#3      _HttpOutboundMessage.write (dart:_http/http_impl.dart:828:11)
#4      testHandler (file:///root/dart_prog/modules/TestModule.dart:3:5)
<asynchronous suspension>
#5      main (file:///root/dart_prog/main.dart:15:15)
<asynchronous suspension>
#6      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
#7      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

发生在

await req.response
  ..write("hello")
  ..close();

尝试加载页面时。

标签: dart

解决方案


我无法重现您的问题,但以下代码存在问题:

  await req.response
  ..write("hello")
  ..close();

这不会等待Future返回的 fromclose()而是尝试等待req.response不是Future.

所以你想要的是以下内容:

Future<void> testHandler(HttpRequest req) async {
  await (req.response
    ..write("hello"))
    .close();
}

但是您还有另一个问题,即您假设close()将刷新缓冲区,但事实并非如此:

注意:对 IOSink 的写入可能会被缓冲,并且可能不会通过调用 close() 来刷新。要刷新所有缓冲的写入,请在调用 close() 之前调用 flush()。

https://api.dart.dev/stable/2.8.4/dart-io/IOSink/close.html

所以你需要等待flush()。所以最终的方法应该是这样的:

Future<void> testHandler(HttpRequest req) async {
  final response = req.response;
  response.write("hello");
  await response.flush();
  return response.close();
}

由于我们返回一个Future(因为 out 方法是async),我们可以只返回Futurefrom close()

但由于我无法重现您的问题,我不知道这是否能解决您的问题。但是随着我的更改,代码会更正确。:)


推荐阅读