Sdk: WebSocket can send and receive messages despite being closed

Created on 20 Jan 2016  路  3Comments  路  Source: dart-lang/sdk

If a WebSocket client's connection is closed by the server after its subscription has been canceled, it's still able to send messages. I haven't read the spec or examined the protocol-level interactions in detail, but this seems wrong.

What's more, Dart's WebSocket server will also receive this message鈥攄espite having called both WebSocket.close() and HttpServer.close(). This is clearly wrong, since the documentation of WebSocket.close() says that it "closes the WebSocket connection".

Here's a reproduction:

import 'dart:async';
import 'dart:io';

main() async {
  var server = await HttpServer.bind('localhost', 0);
  server.transform(new WebSocketTransformer()).listen((socket) {
    socket.listen((msg) {
      print("got $msg");

      // As soon as the server's socket receives a message, close the server and
      // the socket. Once these complete there should be no server-side sockets
      // open at all.
      socket.close().then((_) => print("socket closed"));
      server.close().then((_) => print("server closed"));
    });
  });

  var ws = await WebSocket.connect('ws://localhost:${server.port}');

  // Create and cancel a subscription.
  ws.listen(null).cancel();

  // Send a message to the server that will cause it to close the WebSocket
  // connection.
  ws.add("foo");

  // Give the server time to shut down.
  await new Future.delayed(new Duration(seconds: 1));

  // Try to send another message.
  ws.add("bar");
}

I reproduced this as of 77101d63e3c661957b7829dd96d6b4324da0e768.

I'd expect the socket to continue listening to the server behind-the-scenes even after the subscription is cancelled, so that it can determine when the connection is closed.

P2 area-library library-io type-bug

Most helpful comment

I can confirm. Moreover, WebSocket.readyState always returns WebSocket.OPEN. https://github.com/dart-lang/sdk/issues/32876

All 3 comments

I can confirm. Moreover, WebSocket.readyState always returns WebSocket.OPEN. https://github.com/dart-lang/sdk/issues/32876

I can confirm as well. I have just stumbled upon it while testing how my Android Flutter app behaves after turning on and off the airplane mode. The socket becomes unusable with no indication of the problem. As mentioned, even the readyState is OPEN.

Actually, my case described above seems to be resolved by reacting to ws.done. I can re-establish the connection then after an offline period.

Was this page helpful?
0 / 5 - 0 ratings