| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library json_rpc_2.server; | 5 library json_rpc_2.server; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 import 'dart:convert'; | 9 import 'dart:convert'; |
| 10 | 10 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 | 31 |
| 32 /// The methods registered for this server. | 32 /// The methods registered for this server. |
| 33 final _methods = new Map<String, Function>(); | 33 final _methods = new Map<String, Function>(); |
| 34 | 34 |
| 35 /// The fallback methods for this server. | 35 /// The fallback methods for this server. |
| 36 /// | 36 /// |
| 37 /// These are tried in order until one of them doesn't throw a | 37 /// These are tried in order until one of them doesn't throw a |
| 38 /// [RpcException.methodNotFound] exception. | 38 /// [RpcException.methodNotFound] exception. |
| 39 final _fallbacks = new Queue<Function>(); | 39 final _fallbacks = new Queue<Function>(); |
| 40 | 40 |
| 41 /// Returns a [Future] that completes when the connection is closed. |
| 42 /// |
| 43 /// This is the same future that's returned by [listen]. |
| 44 Future get done => _streams.done; |
| 45 |
| 41 /// Creates a [Server] that reads requests from [requests] and writes | 46 /// Creates a [Server] that reads requests from [requests] and writes |
| 42 /// responses to [responses]. | 47 /// responses to [responses]. |
| 43 /// | 48 /// |
| 44 /// If [requests] is a [StreamSink] as well as a [Stream] (for example, a | 49 /// If [requests] is a [StreamSink] as well as a [Stream] (for example, a |
| 45 /// `WebSocket`), [responses] may be omitted. | 50 /// `WebSocket`), [responses] may be omitted. |
| 46 /// | 51 /// |
| 47 /// Note that the server won't begin listening to [requests] until | 52 /// Note that the server won't begin listening to [requests] until |
| 48 /// [Server.listen] is called. | 53 /// [Server.listen] is called. |
| 49 Server(Stream<String> requests, [StreamSink<String> responses]) { | 54 Server(Stream<String> requests, [StreamSink<String> responses]) { |
| 50 _streams = new TwoWayStream("Server", requests, "requests", | 55 _streams = new TwoWayStream("Server", requests, "requests", |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 if (request is! List) return _handleSingleRequest(request); | 133 if (request is! List) return _handleSingleRequest(request); |
| 129 if (request.isEmpty) { | 134 if (request.isEmpty) { |
| 130 return new RpcException(error_code.INVALID_REQUEST, 'A batch must ' | 135 return new RpcException(error_code.INVALID_REQUEST, 'A batch must ' |
| 131 'contain at least one request.').serialize(request); | 136 'contain at least one request.').serialize(request); |
| 132 } | 137 } |
| 133 | 138 |
| 134 return Future.wait(request.map(_handleSingleRequest)).then((results) { | 139 return Future.wait(request.map(_handleSingleRequest)).then((results) { |
| 135 var nonNull = results.where((result) => result != null); | 140 var nonNull = results.where((result) => result != null); |
| 136 return nonNull.isEmpty ? null : nonNull.toList(); | 141 return nonNull.isEmpty ? null : nonNull.toList(); |
| 137 }); | 142 }); |
| 138 }).then(_streams.add); | 143 }).then((response) { |
| 144 if (response != null) _streams.add(response); |
| 145 }); |
| 139 } | 146 } |
| 140 | 147 |
| 141 /// Handles an individual parsed request. | 148 /// Handles an individual parsed request. |
| 142 Future _handleSingleRequest(request) { | 149 Future _handleSingleRequest(request) { |
| 143 return syncFuture(() { | 150 return syncFuture(() { |
| 144 _validateRequest(request); | 151 _validateRequest(request); |
| 145 | 152 |
| 146 var name = request['method']; | 153 var name = request['method']; |
| 147 var method = _methods[name]; | 154 var method = _methods[name]; |
| 148 if (method == null) method = _tryFallbacks; | 155 if (method == null) method = _tryFallbacks; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 return syncFuture(() => iterator.current(params)).catchError((error) { | 244 return syncFuture(() => iterator.current(params)).catchError((error) { |
| 238 if (error is! RpcException) throw error; | 245 if (error is! RpcException) throw error; |
| 239 if (error.code != error_code.METHOD_NOT_FOUND) throw error; | 246 if (error.code != error_code.METHOD_NOT_FOUND) throw error; |
| 240 return _tryNext(); | 247 return _tryNext(); |
| 241 }); | 248 }); |
| 242 } | 249 } |
| 243 | 250 |
| 244 return _tryNext(); | 251 return _tryNext(); |
| 245 } | 252 } |
| 246 } | 253 } |
| OLD | NEW |