rpcWebSocketChannel function

WebSocketChannel rpcWebSocketChannel(
  1. WebSocket socket
)

A WebSocketChannel over a dart:io socket that its caller keeps and may close itself — a server that upgraded it and closes every socket on stop.

Closed out from under a channel while a frame is on its way, the socket refuses the write with Bad state: StreamSink is closed, thrown in the zone the channel was built in, where nothing can catch it: in the root zone it ends the isolate (see RpcWebSocketChannel). This builds the channel in a zone of its own where that one error is dropped, since the socket it was for is gone and there is nowhere left to deliver it. Every other error the channel throws goes on to the zone this was called in, as it would have.

final socket = await WebSocketTransformer.upgrade(request);
final transport = RpcWebSocketResponderTransport(rpcWebSocketChannel(socket));
// ...later, on stop: safe even with calls in flight.
await socket.close();

A channel the library builds (RpcWebSocketCallerTransport.connect, rpcWebSocketConnections) never hands its socket out, so it needs none of this.

Implementation

WebSocketChannel rpcWebSocketChannel(WebSocket socket) {
  final caller = Zone.current;
  late final WebSocketChannel channel;
  runZonedGuarded(() => channel = IOWebSocketChannel(socket), (error, stack) {
    if (_writeToAClosedSocket(error)) return;
    caller.handleUncaughtError(error, stack);
  });
  return channel;
}