Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(592)

Unified Diff: lib/io.dart

Issue 1756613002: Add an IO implementation of WebSocketChannel. (Closed) Base URL: git@github.com:dart-lang/web_socket_channel.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « README.md ('k') | lib/src/channel.dart » ('j') | test/io_test.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/io.dart
diff --git a/lib/io.dart b/lib/io.dart
new file mode 100644
index 0000000000000000000000000000000000000000..4c06c07a0d29ec68d081b36928672c77b8d77d30
--- /dev/null
+++ b/lib/io.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:async/async.dart';
+import 'package:stream_channel/stream_channel.dart';
+
+import 'src/channel.dart';
+import 'src/exception.dart';
+import 'src/sink_completer.dart';
+
+/// A [WebSocketChannel] that communicates using a `dart:io` [WebSocket].
+class IOWebSocketChannel extends StreamChannelMixin
+ implements WebSocketChannel {
+ /// The underlying `dart:io` [WebSocket].
+ ///
+ /// If the channel was constructed with [IOWebSocketChannel.connect], this is
+ /// `null` until the [WebSocket.connect] future completes.
+ WebSocket _webSocket;
+
+ Duration get pingInterval =>
+ _webSocket == null ? _pingInterval : _webSocket.pingInterval;
+
+ set pingInterval(Duration value) {
+ if (_webSocket == null) {
+ _pingInterval = value;
+ } else {
+ _webSocket.pingInterval = value;
+ }
+ }
+
+ /// The ping interval set by the user.
+ ///
+ /// This is stored independently of [_webSocket] so that the user can set it
+ /// prior to [_webSocket] getting a value.
+ Duration _pingInterval;
+
+ String get protocol => _webSocket?.protocol;
kevmoo 2016/03/01 23:24:46 document that these can be null if not connected?
nweiz 2016/03/02 00:10:20 That's documented in the superclass.
+ int get closeCode => _webSocket?.closeCode;
+ String get closeReason => _webSocket?.closeReason;
+
+ final Stream stream;
+ final WebSocketSink sink;
+
+ // TODO(nweiz): Add a compression parameter after the initial release.
+
+ /// Creates a new WebSocket connection.
+ ///
+ /// Connects to [url] using [WebSocket.connect] and returns a channel that can
+ /// be used to communicate over the resulting socket. The [url] may be either
+ /// a [String] or a [Uri]; otherwise, the parameters are the same as
+ /// [WebSocket.connect].
+ ///
+ /// If there's an error connecting, the channel's stream emits a
+ /// [WebSocketChannelException] wrapping that error and then closes.
+ factory IOWebSocketChannel.connect(url, {Iterable<String> protocols,
+ Map<String, dynamic> headers}) {
+ var channel;
+ var sinkCompleter = new WebSocketSinkCompleter();
+ var stream = StreamCompleter.fromFuture(
+ WebSocket.connect(url.toString(), headers: headers).then((webSocket) {
+ channel._setWebSocket(webSocket);
+ sinkCompleter.setDestinationSink(new _IOWebSocketSink(webSocket));
+ return webSocket;
+ }).catchError((error) => throw new WebSocketChannelException.from(error)));
+
+ channel = new IOWebSocketChannel._withoutSocket(stream, sinkCompleter.sink);
+ return channel;
+ }
+
+ /// Creates a channel wrapping [socket].
+ IOWebSocketChannel(WebSocket socket)
+ : _webSocket = socket,
+ stream = socket.handleError((error) =>
+ throw new WebSocketChannelException.from(error)),
+ sink = new _IOWebSocketSink(socket);
+
+ /// Creates a channel without a socket.
+ ///
+ /// This is used with [connect] to synchronously provide a channel that later
+ /// has a socket added.
+ IOWebSocketChannel._withoutSocket(Stream stream, this.sink)
+ : _webSocket = null,
+ stream = stream.handleError((error) =>
+ throw new WebSocketChannelException.from(error));
+
+ /// Sets the underlying web socket.
+ ///
+ /// This is called by [connect] once the [WebSocket.connect] future has
+ /// completed.
+ void _setWebSocket(WebSocket webSocket) {
+ assert(_webSocket == null);
+
+ _webSocket = webSocket;
+ if (_pingInterval != null) _webSocket.pingInterval = pingInterval;
+ }
+}
+
+/// A [WebSocketSink] that forwards [close] calls to a `dart:io` [WebSocket].
+class _IOWebSocketSink extends DelegatingStreamSink implements WebSocketSink {
+ /// The underlying socket.
+ final WebSocket _webSocket;
+
+ _IOWebSocketSink(WebSocket webSocket)
+ : super(webSocket),
+ _webSocket = webSocket;
+
+ Future close([int closeCode, String closeReason]) =>
+ _webSocket.close(closeCode, closeReason);
+}
« no previous file with comments | « README.md ('k') | lib/src/channel.dart » ('j') | test/io_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698