HtmlWebSocketChannel constructor

HtmlWebSocketChannel(
  1. Object webSocket
)

Creates a channel wrapping webSocket.

The parameter webSocket should be either a dart:html WebSocket instance or a package:web WebSocket instance.

Implementation

HtmlWebSocketChannel(Object /*WebSocket*/ webSocket)
    : innerWebSocket = webSocket as WebSocket {
  _readyCompleter = Completer();
  if (innerWebSocket.readyState == WebSocket.OPEN) {
    _readyCompleter.complete();
    _listen();
  } else {
    if (innerWebSocket.readyState == WebSocket.CLOSING ||
        innerWebSocket.readyState == WebSocket.CLOSED) {
      _readyCompleter.completeError(WebSocketChannelException(
          'WebSocket state error: ${innerWebSocket.readyState}'));
    }
    // The socket API guarantees that only a single open event will be
    // emitted.
    innerWebSocket.onOpen.first.then((_) {
      _readyCompleter.complete();
      _listen();
    });
  }

  // The socket API guarantees that only a single error event will be emitted,
  // and that once it is no open or message events will be emitted.
  innerWebSocket.onError.first.then((_) {
    // Unfortunately, the underlying WebSocket API doesn't expose any
    // specific information about the error itself.
    final error = WebSocketChannelException('WebSocket connection failed.');
    if (!_readyCompleter.isCompleted) {
      _readyCompleter.completeError(error);
    }
    _controller.local.sink.addError(error);
    _controller.local.sink.close();
  });

  innerWebSocket.onMessage.listen(_innerListen);

  // The socket API guarantees that only a single error event will be emitted,
  // and that once it is no other events will be emitted.
  innerWebSocket.onClose.first.then((event) {
    _closeCode = event.code;
    _closeReason = event.reason;
    _controller.local.sink.close();
  });
}