OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 // Matches _WebSocketOpcode. | 9 // Matches _WebSocketOpcode. |
10 class _WebSocketMessageType { | 10 class _WebSocketMessageType { |
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 } | 734 } |
735 | 735 |
736 void closeSocket() { | 736 void closeSocket() { |
737 _closed = true; | 737 _closed = true; |
738 _cancel(); | 738 _cancel(); |
739 close(); | 739 close(); |
740 } | 740 } |
741 } | 741 } |
742 | 742 |
743 | 743 |
744 class _WebSocketImpl extends Stream implements WebSocket { | 744 class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { |
| 745 // Use default Map so we keep order. |
| 746 static Map<int, _WebSocketImpl> _webSockets = new Map<int, _WebSocketImpl>(); |
| 747 |
745 final String protocol; | 748 final String protocol; |
746 | 749 |
747 StreamController _controller; | 750 StreamController _controller; |
748 StreamSubscription _subscription; | 751 StreamSubscription _subscription; |
749 StreamSink _sink; | 752 StreamSink _sink; |
750 | 753 |
751 final Socket _socket; | 754 final Socket _socket; |
752 final bool _serverSide; | 755 final bool _serverSide; |
753 int _readyState = WebSocket.CONNECTING; | 756 int _readyState = WebSocket.CONNECTING; |
754 bool _writeClosed = false; | 757 bool _writeClosed = false; |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 _closeCode = transformer.closeCode; | 888 _closeCode = transformer.closeCode; |
886 _closeReason = transformer.closeReason; | 889 _closeReason = transformer.closeReason; |
887 _controller.close(); | 890 _controller.close(); |
888 }, | 891 }, |
889 cancelOnError: true); | 892 cancelOnError: true); |
890 _subscription.pause(); | 893 _subscription.pause(); |
891 _controller = new StreamController(sync: true, | 894 _controller = new StreamController(sync: true, |
892 onListen: _subscription.resume, | 895 onListen: _subscription.resume, |
893 onPause: _subscription.pause, | 896 onPause: _subscription.pause, |
894 onResume: _subscription.resume); | 897 onResume: _subscription.resume); |
| 898 |
| 899 _webSockets[_serviceId] = this; |
895 } | 900 } |
896 | 901 |
897 StreamSubscription listen(void onData(message), | 902 StreamSubscription listen(void onData(message), |
898 {Function onError, | 903 {Function onError, |
899 void onDone(), | 904 void onDone(), |
900 bool cancelOnError}) { | 905 bool cancelOnError}) { |
901 return _controller.stream.listen(onData, | 906 return _controller.stream.listen(onData, |
902 onError: onError, | 907 onError: onError, |
903 onDone: onDone, | 908 onDone: onDone, |
904 cancelOnError: cancelOnError); | 909 cancelOnError: cancelOnError); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
944 _outCloseReason = reason; | 949 _outCloseReason = reason; |
945 } | 950 } |
946 if (_closeTimer == null && !_controller.isClosed) { | 951 if (_closeTimer == null && !_controller.isClosed) { |
947 // When closing the web-socket, we no longer accept data. | 952 // When closing the web-socket, we no longer accept data. |
948 _closeTimer = new Timer(const Duration(seconds: 5), () { | 953 _closeTimer = new Timer(const Duration(seconds: 5), () { |
949 // Reuse code and reason from the local close. | 954 // Reuse code and reason from the local close. |
950 _closeCode = _outCloseCode; | 955 _closeCode = _outCloseCode; |
951 _closeReason = _outCloseReason; | 956 _closeReason = _outCloseReason; |
952 _subscription.cancel(); | 957 _subscription.cancel(); |
953 _controller.close(); | 958 _controller.close(); |
| 959 _webSockets.remove(_serviceId); |
954 }); | 960 }); |
955 } | 961 } |
956 return _sink.close(); | 962 return _sink.close(); |
957 } | 963 } |
958 | 964 |
959 void _close([int code, String reason]) { | 965 void _close([int code, String reason]) { |
960 if (_writeClosed) return; | 966 if (_writeClosed) return; |
961 if (_outCloseCode == null) { | 967 if (_outCloseCode == null) { |
962 _outCloseCode = code; | 968 _outCloseCode = code; |
963 _outCloseReason = reason; | 969 _outCloseReason = reason; |
964 } | 970 } |
965 _writeClosed = true; | 971 _writeClosed = true; |
966 _consumer.closeSocket(); | 972 _consumer.closeSocket(); |
| 973 _webSockets.remove(_serviceId); |
| 974 } |
| 975 |
| 976 String get _serviceTypePath => 'io/websockets'; |
| 977 String get _serviceTypeName => 'WebSocket'; |
| 978 |
| 979 Map _toJSON(bool ref) { |
| 980 var name = '${_socket.address.host}:${_socket.port}'; |
| 981 var r = { |
| 982 'id': _servicePath, |
| 983 'type': _serviceType(ref), |
| 984 'name': name, |
| 985 'user_name': name, |
| 986 }; |
| 987 if (ref) { |
| 988 return r; |
| 989 } |
| 990 try { |
| 991 r['socket'] = _socket._toJSON(true); |
| 992 } catch (_) { |
| 993 r['socket'] = { |
| 994 'id': _servicePath, |
| 995 'type': '@Socket', |
| 996 'name': 'UserSocket', |
| 997 'user_name': 'UserSocket', |
| 998 }; |
| 999 } |
| 1000 return r; |
967 } | 1001 } |
968 | 1002 |
969 static bool _isReservedStatusCode(int code) { | 1003 static bool _isReservedStatusCode(int code) { |
970 return code != null && | 1004 return code != null && |
971 (code < WebSocketStatus.NORMAL_CLOSURE || | 1005 (code < WebSocketStatus.NORMAL_CLOSURE || |
972 code == WebSocketStatus.RESERVED_1004 || | 1006 code == WebSocketStatus.RESERVED_1004 || |
973 code == WebSocketStatus.NO_STATUS_RECEIVED || | 1007 code == WebSocketStatus.NO_STATUS_RECEIVED || |
974 code == WebSocketStatus.ABNORMAL_CLOSURE || | 1008 code == WebSocketStatus.ABNORMAL_CLOSURE || |
975 (code > WebSocketStatus.INTERNAL_SERVER_ERROR && | 1009 (code > WebSocketStatus.INTERNAL_SERVER_ERROR && |
976 code < WebSocketStatus.RESERVED_1015) || | 1010 code < WebSocketStatus.RESERVED_1015) || |
977 (code >= WebSocketStatus.RESERVED_1015 && | 1011 (code >= WebSocketStatus.RESERVED_1015 && |
978 code < 3000)); | 1012 code < 3000)); |
979 } | 1013 } |
980 } | 1014 } |
OLD | NEW |