33// BSD-style license that can be found in the LICENSE file.
44
55import 'dart:async' ;
6- import 'dart:html ' ;
6+ import 'dart:js_interop ' ;
77import 'dart:typed_data' ;
88
99import 'package:async/async.dart' ;
1010import 'package:stream_channel/stream_channel.dart' ;
11+ import 'package:web/helpers.dart' ;
1112
1213import 'src/channel.dart' ;
1314import 'src/exception.dart' ;
15+ import 'src/web_helpers.dart' ;
1416
1517/// A [WebSocketChannel] that communicates using a `dart:html` [WebSocket] .
1618class HtmlWebSocketChannel extends StreamChannelMixin
@@ -73,8 +75,15 @@ class HtmlWebSocketChannel extends StreamChannelMixin
7375 /// [BinaryType.blob] , they're delivered as [Blob] s instead.
7476 HtmlWebSocketChannel .connect (Object url,
7577 {Iterable <String >? protocols, BinaryType ? binaryType})
76- : this (WebSocket (url.toString (), protocols)
77- ..binaryType = (binaryType ?? BinaryType .list).value);
78+ : this (
79+ WebSocket (
80+ url.toString (),
81+ (protocols? .toList () ?? const < String > [])
82+ .map ((e) => e.toJS)
83+ .toList ()
84+ .toJS,
85+ )..binaryType = (binaryType ?? BinaryType .list).value,
86+ );
7887
7988 /// Creates a channel wrapping [innerWebSocket] .
8089 HtmlWebSocketChannel (this .innerWebSocket) {
@@ -109,11 +118,7 @@ class HtmlWebSocketChannel extends StreamChannelMixin
109118 _controller.local.sink.close ();
110119 });
111120
112- innerWebSocket.onMessage.listen ((event) {
113- var data = event.data;
114- if (data is ByteBuffer ) data = data.asUint8List ();
115- _controller.local.sink.add (data);
116- });
121+ innerWebSocket.onMessage.listen (_innerListen);
117122
118123 // The socket API guarantees that only a single error event will be emitted,
119124 // and that once it is no other events will be emitted.
@@ -124,16 +129,29 @@ class HtmlWebSocketChannel extends StreamChannelMixin
124129 });
125130 }
126131
132+ void _innerListen (MessageEvent event) {
133+ final eventData = event.data;
134+ Object ? data;
135+ if (eventData.typeofEquals ('object' ) &&
136+ (eventData as JSObject ).instanceOfString ('ArrayBuffer' )) {
137+ data = (eventData as JSArrayBuffer ).toDart.asUint8List ();
138+ } else {
139+ data = event.data;
140+ }
141+ _controller.local.sink.add (data);
142+ }
143+
127144 /// Pipes user events to [innerWebSocket] .
128145 void _listen () {
129- _controller.local.stream.listen (innerWebSocket.send, onDone: () {
146+ _controller.local.stream.listen ((obj) => innerWebSocket.send (obj! .jsify ()! ),
147+ onDone: () {
130148 // On Chrome and possibly other browsers, `null` can't be passed as the
131149 // default here. The actual arity of the function call must be correct or
132150 // it will fail.
133151 if (_localCloseCode != null && _localCloseReason != null ) {
134- innerWebSocket.close (_localCloseCode, _localCloseReason);
152+ innerWebSocket.close (_localCloseCode! , _localCloseReason! );
135153 } else if (_localCloseCode != null ) {
136- innerWebSocket.close (_localCloseCode);
154+ innerWebSocket.close (_localCloseCode! );
137155 } else {
138156 innerWebSocket.close ();
139157 }
0 commit comments