| 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 channel; | 5 library channel; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 import 'dart:io'; | 9 import 'dart:io'; |
| 10 | 10 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 | 56 |
| 57 /** | 57 /** |
| 58 * Send the given [notification] to the client. | 58 * Send the given [notification] to the client. |
| 59 */ | 59 */ |
| 60 void sendNotification(Notification notification); | 60 void sendNotification(Notification notification); |
| 61 | 61 |
| 62 /** | 62 /** |
| 63 * Send the given [response] to the client. | 63 * Send the given [response] to the client. |
| 64 */ | 64 */ |
| 65 void sendResponse(Response response); | 65 void sendResponse(Response response); |
| 66 |
| 67 /** |
| 68 * Close the communication channel. |
| 69 */ |
| 70 void close(); |
| 66 } | 71 } |
| 67 | 72 |
| 68 /** | 73 /** |
| 69 * Instances of the class [WebSocketClientChannel] implement a | 74 * Instances of the class [WebSocketClientChannel] implement a |
| 70 * [ClientCommunicationChannel] that uses a [WebSocket] to communicate with | 75 * [ClientCommunicationChannel] that uses a [WebSocket] to communicate with |
| 71 * servers. | 76 * servers. |
| 72 */ | 77 */ |
| 73 class WebSocketClientChannel implements ClientCommunicationChannel { | 78 class WebSocketClientChannel implements ClientCommunicationChannel { |
| 74 /** | 79 /** |
| 75 * The socket being wrapped. | 80 * The socket being wrapped. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 return; | 165 return; |
| 161 } | 166 } |
| 162 onRequest(request); | 167 onRequest(request); |
| 163 } else if (data is List<int>) { | 168 } else if (data is List<int>) { |
| 164 // TODO(brianwilkerson) Implement a more efficient protocol. | 169 // TODO(brianwilkerson) Implement a more efficient protocol. |
| 165 sendResponse(new Response.invalidRequestFormat()); | 170 sendResponse(new Response.invalidRequestFormat()); |
| 166 } else { | 171 } else { |
| 167 sendResponse(new Response.invalidRequestFormat()); | 172 sendResponse(new Response.invalidRequestFormat()); |
| 168 } | 173 } |
| 169 } | 174 } |
| 175 |
| 176 @override |
| 177 void close() { |
| 178 socket.close(WebSocketStatus.NORMAL_CLOSURE); |
| 179 } |
| 170 } | 180 } |
| 171 | 181 |
| 172 /** | 182 /** |
| 173 * Instances of the class [ByteStreamClientChannel] implement a | 183 * Instances of the class [ByteStreamClientChannel] implement a |
| 174 * [ClientCommunicationChannel] that uses a stream and a sink (typically, | 184 * [ClientCommunicationChannel] that uses a stream and a sink (typically, |
| 175 * standard input and standard output) to communicate with servers. | 185 * standard input and standard output) to communicate with servers. |
| 176 */ | 186 */ |
| 177 class ByteStreamClientChannel implements ClientCommunicationChannel { | 187 class ByteStreamClientChannel implements ClientCommunicationChannel { |
| 178 final Stream input; | 188 final Stream input; |
| 179 final IOSink output; | 189 final IOSink output; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 Future get closed { | 245 Future get closed { |
| 236 return _closed.future; | 246 return _closed.future; |
| 237 } | 247 } |
| 238 | 248 |
| 239 @override | 249 @override |
| 240 void listen(void onRequest(Request request), {Function onError, void | 250 void listen(void onRequest(Request request), {Function onError, void |
| 241 onDone()}) { | 251 onDone()}) { |
| 242 input.transform((new Utf8Codec()).decoder).transform(new LineSplitter() | 252 input.transform((new Utf8Codec()).decoder).transform(new LineSplitter() |
| 243 ).listen((String data) => _readRequest(data, onRequest), onError: onErro
r, | 253 ).listen((String data) => _readRequest(data, onRequest), onError: onErro
r, |
| 244 onDone: () { | 254 onDone: () { |
| 245 _closed.complete(); | 255 close(); |
| 246 onDone(); | 256 onDone(); |
| 247 }); | 257 }); |
| 248 } | 258 } |
| 249 | 259 |
| 250 @override | 260 @override |
| 251 void sendNotification(Notification notification) { | 261 void sendNotification(Notification notification) { |
| 262 // Don't send any further notifications after the communication channel is |
| 263 // closed. |
| 264 if (_closed.isCompleted) { |
| 265 return; |
| 266 } |
| 252 output.writeln(JSON.encode(notification.toJson())); | 267 output.writeln(JSON.encode(notification.toJson())); |
| 253 } | 268 } |
| 254 | 269 |
| 255 @override | 270 @override |
| 256 void sendResponse(Response response) { | 271 void sendResponse(Response response) { |
| 272 // Don't send any further responses after the communication channel is |
| 273 // closed. |
| 274 if (_closed.isCompleted) { |
| 275 return; |
| 276 } |
| 257 output.writeln(JSON.encode(response.toJson())); | 277 output.writeln(JSON.encode(response.toJson())); |
| 258 } | 278 } |
| 259 | 279 |
| 260 /** | 280 /** |
| 261 * Read a request from the given [data] and use the given function to handle | 281 * Read a request from the given [data] and use the given function to handle |
| 262 * the request. | 282 * the request. |
| 263 */ | 283 */ |
| 264 void _readRequest(Object data, void onRequest(Request request)) { | 284 void _readRequest(Object data, void onRequest(Request request)) { |
| 285 // Ignore any further requests after the communication channel is closed. |
| 286 if (_closed.isCompleted) { |
| 287 return; |
| 288 } |
| 265 // Parse the string as a JSON descriptor and process the resulting | 289 // Parse the string as a JSON descriptor and process the resulting |
| 266 // structure as a request. | 290 // structure as a request. |
| 267 Request request = new Request.fromString(data); | 291 Request request = new Request.fromString(data); |
| 268 if (request == null) { | 292 if (request == null) { |
| 269 sendResponse(new Response.invalidRequestFormat()); | 293 sendResponse(new Response.invalidRequestFormat()); |
| 270 return; | 294 return; |
| 271 } | 295 } |
| 272 onRequest(request); | 296 onRequest(request); |
| 273 } | 297 } |
| 298 |
| 299 @override |
| 300 void close() { |
| 301 if (!_closed.isCompleted) { |
| 302 _closed.complete(); |
| 303 } |
| 304 } |
| 274 } | 305 } |
| 275 | 306 |
| 276 /** | 307 /** |
| 277 * Instances of the class [JsonStreamDecoder] convert JSON strings to JSON | 308 * Instances of the class [JsonStreamDecoder] convert JSON strings to JSON |
| 278 * maps. | 309 * maps. |
| 279 */ | 310 */ |
| 280 class JsonStreamDecoder extends Converter<String, Map> { | 311 class JsonStreamDecoder extends Converter<String, Map> { |
| 281 @override | 312 @override |
| 282 Map convert(String text) => JSON.decode(text); | 313 Map convert(String text) => JSON.decode(text); |
| 283 | 314 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 } | 377 } |
| 347 } | 378 } |
| 348 } | 379 } |
| 349 | 380 |
| 350 @override | 381 @override |
| 351 void close() { | 382 void close() { |
| 352 closed = true; | 383 closed = true; |
| 353 sink.close(); | 384 sink.close(); |
| 354 } | 385 } |
| 355 } | 386 } |
| OLD | NEW |