Fix a race when close() called before remote class event delivered (dart-lang/web_socket_channel#348)
diff --git a/pkgs/web_socket_channel/lib/adapter_web_socket_channel.dart b/pkgs/web_socket_channel/lib/adapter_web_socket_channel.dart index 8415f27..d4df1b3 100644 --- a/pkgs/web_socket_channel/lib/adapter_web_socket_channel.dart +++ b/pkgs/web_socket_channel/lib/adapter_web_socket_channel.dart
@@ -79,7 +79,6 @@ } webSocketFuture.then((webSocket) { - var remoteClosed = false; webSocket.events.listen((event) { switch (event) { case TextDataReceived(text: final text): @@ -87,7 +86,6 @@ case BinaryDataReceived(data: final data): _controller.local.sink.add(data); case CloseReceived(code: final code, reason: final reason): - remoteClosed = true; _closeCode = code; _closeReason = reason; _controller.local.sink.close(); @@ -105,13 +103,15 @@ default: throw UnsupportedError('Cannot send ${obj.runtimeType}'); } - } on WebSocketConnectionClosed catch (_) { + } on WebSocketConnectionClosed { // There is nowhere to surface this error; `_controller.local.sink` // has already been closed. } - }, onDone: () { - if (!remoteClosed) { - webSocket.close(_localCloseCode, _localCloseReason); + }, onDone: () async { + try { + await webSocket.close(_localCloseCode, _localCloseReason); + } on WebSocketConnectionClosed { + // It is not an error to close an already-closed `WebSocketChannel`. } }); _protocol = webSocket.protocol;
diff --git a/pkgs/web_socket_channel/pubspec.yaml b/pkgs/web_socket_channel/pubspec.yaml index d198922..6b8ae39 100644 --- a/pkgs/web_socket_channel/pubspec.yaml +++ b/pkgs/web_socket_channel/pubspec.yaml
@@ -14,7 +14,7 @@ crypto: ^3.0.0 stream_channel: ^2.1.0 web: ^0.5.0 - web_socket: ^0.1.1 + web_socket: ^0.1.3 dev_dependencies: dart_flutter_team_lints: ^2.0.0