dart-lang / web_socket_channel

StreamChannel wrappers for WebSockets.
https://pub.dev/packages/web_socket_channel
BSD 3-Clause "New" or "Revised" License
412 stars 107 forks source link

Should the `ready` future fail if the socket gets closed while not resolved? #375

Open davidmartos96 opened 2 weeks ago

davidmartos96 commented 2 weeks ago

As the title suggests, would it make sense to throw when stablishing the connection and in the meantime some piece of code closes the socket?

On Node that is precisely what happens in the ws package.

Kind of related to this use case, it would be helpful to have a getter on the channel that says if it's closed or not.

Here is a simple demo for the close while connecting case on Dart and NodeJS:

import 'dart:async';

import 'package:web_socket_channel/web_socket_channel.dart';

Future<void> main() async {
  final wsUrl = Uri.parse('ws://localhost:9898');
  final channel = WebSocketChannel.connect(wsUrl);

  final readyFuture = channel.ready;

  unawaited(Future(() => channel.sink.close()));

  await readyFuture;

  channel.stream.listen((message) {
    channel.sink.add('received!');
  });
}
import { WebSocket } from "ws";

const sleepAsync = (ms: number) =>
  new Promise((resolve) => setTimeout(resolve, ms));

async function main() {
  const socket = new WebSocket("ws://localhost:9898");
  socket.binaryType = "nodebuffer";

  socket.addEventListener("open", () => {
    console.log("Connected to server");
  });
  socket.addEventListener("message", (m) => {
    console.log("Message:", m);
  });
  socket.addEventListener("error", (e) => {
    console.log("Error obtained:", e.message);
  });
  socket.addEventListener("close", () => {
    console.log("Closed");
  });
  socket.close();
  await sleepAsync(1000);
}

main();

Output on Node:

Error obtained: WebSocket was closed before the connection was established
Closed