AdapterWebSocketChannel constructor

AdapterWebSocketChannel(
  1. FutureOr<WebSocket> webSocket
)

Implementation

AdapterWebSocketChannel(FutureOr<WebSocket> webSocket) {
  Future<WebSocket> webSocketFuture;
  if (webSocket is WebSocket) {
    webSocketFuture = Future.value(webSocket);
  } else {
    webSocketFuture = webSocket;
  }

  webSocketFuture.then((webSocket) {
    webSocket.events.listen((event) {
      switch (event) {
        case TextDataReceived(text: final text):
          _controller.local.sink.add(text);
        case BinaryDataReceived(data: final data):
          _controller.local.sink.add(data);
        case CloseReceived(code: final code, reason: final reason):
          _closeCode = code;
          _closeReason = reason;
          _controller.local.sink.close();
      }
    });
    _controller.local.stream.listen((obj) {
      try {
        switch (obj) {
          case final String s:
            webSocket.sendText(s);
          case final Uint8List b:
            webSocket.sendBytes(b);
          case final List<int> b:
            webSocket.sendBytes(Uint8List.fromList(b));
          default:
            throw UnsupportedError('Cannot send ${obj.runtimeType}');
        }
      } on WebSocketConnectionClosed {
        // There is nowhere to surface this error; `_controller.local.sink`
        // has already been closed.
      }
    }, onDone: () async {
      try {
        await webSocket.close(_localCloseCode, _localCloseReason);
      } on WebSocketConnectionClosed {
        // It is not an error to close an already-closed `WebSocketChannel`.
      }
    });
    _protocol = webSocket.protocol;
    _readyCompleter.complete();
  }, onError: (Object e) {
    Exception error;
    if (e is TimeoutException) {
      // Required for backwards compatibility with `IOWebSocketChannel`.
      error = e;
    } else {
      error = WebSocketChannelException.from(e);
    }
    _readyCompleter.completeError(error);
    _controller.local.sink.addError(error);
    _controller.local.sink.close();
  });
}