OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 import 'dart:async'; | |
6 import 'dart:io'; | |
7 | |
8 import 'package:async/async.dart'; | |
9 import 'package:stream_channel/stream_channel.dart'; | |
10 | |
11 import 'src/channel.dart'; | |
12 import 'src/exception.dart'; | |
13 import 'src/sink_completer.dart'; | |
14 | |
15 /// A [WebSocketChannel] that communicates using a `dart:io` [WebSocket]. | |
16 class IOWebSocketChannel extends StreamChannelMixin | |
17 implements WebSocketChannel { | |
18 /// The underlying `dart:io` [WebSocket]. | |
19 /// | |
20 /// If the channel was constructed with [IOWebSocketChannel.connect], this is | |
21 /// `null` until the [WebSocket.connect] future completes. | |
22 WebSocket _webSocket; | |
23 | |
24 Duration get pingInterval => | |
25 _webSocket == null ? _pingInterval : _webSocket.pingInterval; | |
26 | |
27 set pingInterval(Duration value) { | |
28 if (_webSocket == null) { | |
29 _pingInterval = value; | |
30 } else { | |
31 _webSocket.pingInterval = value; | |
32 } | |
33 } | |
34 | |
35 /// The ping interval set by the user. | |
36 /// | |
37 /// This is stored independently of [_webSocket] so that the user can set it | |
38 /// prior to [_webSocket] getting a value. | |
39 Duration _pingInterval; | |
40 | |
41 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.
| |
42 int get closeCode => _webSocket?.closeCode; | |
43 String get closeReason => _webSocket?.closeReason; | |
44 | |
45 final Stream stream; | |
46 final WebSocketSink sink; | |
47 | |
48 // TODO(nweiz): Add a compression parameter after the initial release. | |
49 | |
50 /// Creates a new WebSocket connection. | |
51 /// | |
52 /// Connects to [url] using [WebSocket.connect] and returns a channel that can | |
53 /// be used to communicate over the resulting socket. The [url] may be either | |
54 /// a [String] or a [Uri]; otherwise, the parameters are the same as | |
55 /// [WebSocket.connect]. | |
56 /// | |
57 /// If there's an error connecting, the channel's stream emits a | |
58 /// [WebSocketChannelException] wrapping that error and then closes. | |
59 factory IOWebSocketChannel.connect(url, {Iterable<String> protocols, | |
60 Map<String, dynamic> headers}) { | |
61 var channel; | |
62 var sinkCompleter = new WebSocketSinkCompleter(); | |
63 var stream = StreamCompleter.fromFuture( | |
64 WebSocket.connect(url.toString(), headers: headers).then((webSocket) { | |
65 channel._setWebSocket(webSocket); | |
66 sinkCompleter.setDestinationSink(new _IOWebSocketSink(webSocket)); | |
67 return webSocket; | |
68 }).catchError((error) => throw new WebSocketChannelException.from(error))); | |
69 | |
70 channel = new IOWebSocketChannel._withoutSocket(stream, sinkCompleter.sink); | |
71 return channel; | |
72 } | |
73 | |
74 /// Creates a channel wrapping [socket]. | |
75 IOWebSocketChannel(WebSocket socket) | |
76 : _webSocket = socket, | |
77 stream = socket.handleError((error) => | |
78 throw new WebSocketChannelException.from(error)), | |
79 sink = new _IOWebSocketSink(socket); | |
80 | |
81 /// Creates a channel without a socket. | |
82 /// | |
83 /// This is used with [connect] to synchronously provide a channel that later | |
84 /// has a socket added. | |
85 IOWebSocketChannel._withoutSocket(Stream stream, this.sink) | |
86 : _webSocket = null, | |
87 stream = stream.handleError((error) => | |
88 throw new WebSocketChannelException.from(error)); | |
89 | |
90 /// Sets the underlying web socket. | |
91 /// | |
92 /// This is called by [connect] once the [WebSocket.connect] future has | |
93 /// completed. | |
94 void _setWebSocket(WebSocket webSocket) { | |
95 assert(_webSocket == null); | |
96 | |
97 _webSocket = webSocket; | |
98 if (_pingInterval != null) _webSocket.pingInterval = pingInterval; | |
99 } | |
100 } | |
101 | |
102 /// A [WebSocketSink] that forwards [close] calls to a `dart:io` [WebSocket]. | |
103 class _IOWebSocketSink extends DelegatingStreamSink implements WebSocketSink { | |
104 /// The underlying socket. | |
105 final WebSocket _webSocket; | |
106 | |
107 _IOWebSocketSink(WebSocket webSocket) | |
108 : super(webSocket), | |
109 _webSocket = webSocket; | |
110 | |
111 Future close([int closeCode, String closeReason]) => | |
112 _webSocket.close(closeCode, closeReason); | |
113 } | |
OLD | NEW |