Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; | 7 const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; |
| 8 | 8 |
| 9 class _WebSocketMessageType { | 9 class _WebSocketMessageType { |
| 10 static const int NONE = 0; | 10 static const int NONE = 0; |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 | 426 |
| 427 | 427 |
| 428 class _WebSocketImpl extends Stream<Event> implements WebSocket { | 428 class _WebSocketImpl extends Stream<Event> implements WebSocket { |
| 429 final StreamController<Event> _controller = new StreamController<Event>(); | 429 final StreamController<Event> _controller = new StreamController<Event>(); |
| 430 | 430 |
| 431 final _WebSocketProtocolProcessor _processor = | 431 final _WebSocketProtocolProcessor _processor = |
| 432 new _WebSocketProtocolProcessor(); | 432 new _WebSocketProtocolProcessor(); |
| 433 | 433 |
| 434 final Socket _socket; | 434 final Socket _socket; |
| 435 int _readyState = WebSocket.CONNECTING; | 435 int _readyState = WebSocket.CONNECTING; |
| 436 bool _writeClosed = false; | |
| 436 | 437 |
| 437 static final HttpClient _httpClient = new HttpClient(); | 438 static final HttpClient _httpClient = new HttpClient(); |
| 438 | 439 |
| 439 static Future<WebSocket> connect(String url, [protocols]) { | 440 static Future<WebSocket> connect(String url, [protocols]) { |
| 440 Uri uri = Uri.parse(url); | 441 Uri uri = Uri.parse(url); |
| 441 if (uri.scheme != "ws" && uri.scheme != "wss") { | 442 if (uri.scheme != "ws" && uri.scheme != "wss") { |
| 442 throw new WebSocketException("Unsupported URL scheme '${uri.scheme}'"); | 443 throw new WebSocketException("Unsupported URL scheme '${uri.scheme}'"); |
| 443 } | 444 } |
| 444 if (uri.userInfo != "") { | 445 if (uri.userInfo != "") { |
| 445 throw new WebSocketException("Unsupported user info '${uri.userInfo}'"); | 446 throw new WebSocketException("Unsupported user info '${uri.userInfo}'"); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 if (_readyState == WebSocket.OPEN) { | 539 if (_readyState == WebSocket.OPEN) { |
| 539 _readyState = WebSocket.CLOSING; | 540 _readyState = WebSocket.CLOSING; |
| 540 if (code != WebSocketStatus.NO_STATUS_RECEIVED) { | 541 if (code != WebSocketStatus.NO_STATUS_RECEIVED) { |
| 541 _close(code); | 542 _close(code); |
| 542 } else { | 543 } else { |
| 543 _close(); | 544 _close(); |
| 544 clean = false; | 545 clean = false; |
| 545 } | 546 } |
| 546 _readyState = WebSocket.CLOSED; | 547 _readyState = WebSocket.CLOSED; |
| 547 } | 548 } |
| 549 if (_readyState == WebSocket.CLOSED) return; | |
| 548 _controller.add(new _WebSocketCloseEvent(clean, code, reason)); | 550 _controller.add(new _WebSocketCloseEvent(clean, code, reason)); |
| 549 _controller.close(); | 551 _controller.close(); |
| 550 }; | 552 }; |
| 551 | 553 |
| 552 _socket.listen( | 554 _socket.listen( |
| 553 (data) => _processor.update(data, 0, data.length), | 555 (data) => _processor.update(data, 0, data.length), |
| 554 onDone: () => _processor.closed(), | 556 onDone: () => _processor.closed(), |
| 555 onError: (error) => _controller.signalError(error)); | 557 onError: (error) => _controller.signalError(error)); |
| 558 | |
| 559 _socket.done | |
| 560 .catchError((error) { | |
| 561 if (_readyState == WebSocket.CLOSED) return; | |
| 562 _readyState = WebSocket.CLOSED; | |
| 563 _controller.signalError(error); | |
| 564 _controller.close(); | |
| 565 _processor.closed(); | |
|
Søren Gjesse
2013/02/28 17:15:24
As discussed offline there should probably be a _s
Anders Johnsen
2013/02/28 17:19:47
Done.
| |
| 566 }) | |
| 567 .whenComplete(() { | |
| 568 _writeClosed = true; | |
| 569 }); | |
| 556 } | 570 } |
| 557 | 571 |
| 558 StreamSubscription<Event> listen(void onData(Event event), | 572 StreamSubscription<Event> listen(void onData(Event event), |
| 559 {void onError(AsyncError error), | 573 {void onError(AsyncError error), |
| 560 void onDone(), | 574 void onDone(), |
| 561 bool unsubscribeOnError}) { | 575 bool unsubscribeOnError}) { |
| 562 return _controller.stream.listen(onData, | 576 return _controller.stream.listen(onData, |
| 563 onError: onError, | 577 onError: onError, |
| 564 onDone: onDone, | 578 onDone: onDone, |
| 565 unsubscribeOnError: unsubscribeOnError); | 579 unsubscribeOnError: unsubscribeOnError); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 624 opcode = _WebSocketOpcode.BINARY; | 638 opcode = _WebSocketOpcode.BINARY; |
| 625 data = message; | 639 data = message; |
| 626 } | 640 } |
| 627 } else { | 641 } else { |
| 628 opcode = _WebSocketOpcode.TEXT; | 642 opcode = _WebSocketOpcode.TEXT; |
| 629 } | 643 } |
| 630 _sendFrame(opcode, data); | 644 _sendFrame(opcode, data); |
| 631 } | 645 } |
| 632 | 646 |
| 633 void _sendFrame(int opcode, [List<int> data]) { | 647 void _sendFrame(int opcode, [List<int> data]) { |
| 648 if (_writeClosed) return; | |
| 634 bool mask = false; // Masking not implemented for server. | 649 bool mask = false; // Masking not implemented for server. |
| 635 int dataLength = data == null ? 0 : data.length; | 650 int dataLength = data == null ? 0 : data.length; |
| 636 // Determine the header size. | 651 // Determine the header size. |
| 637 int headerSize = (mask) ? 6 : 2; | 652 int headerSize = (mask) ? 6 : 2; |
| 638 if (dataLength > 65535) { | 653 if (dataLength > 65535) { |
| 639 headerSize += 8; | 654 headerSize += 8; |
| 640 } else if (dataLength > 125) { | 655 } else if (dataLength > 125) { |
| 641 headerSize += 2; | 656 headerSize += 2; |
| 642 } | 657 } |
| 643 List<int> header = new List<int>(headerSize); | 658 List<int> header = new List<int>(headerSize); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 | 691 |
| 677 class _WebSocketCloseEvent implements CloseEvent { | 692 class _WebSocketCloseEvent implements CloseEvent { |
| 678 _WebSocketCloseEvent(this._wasClean, this._code, this._reason); | 693 _WebSocketCloseEvent(this._wasClean, this._code, this._reason); |
| 679 bool get wasClean => _wasClean; | 694 bool get wasClean => _wasClean; |
| 680 int get code => _code; | 695 int get code => _code; |
| 681 String get reason => _reason; | 696 String get reason => _reason; |
| 682 bool _wasClean; | 697 bool _wasClean; |
| 683 int _code; | 698 int _code; |
| 684 String _reason; | 699 String _reason; |
| 685 } | 700 } |
| OLD | NEW |