| 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:convert'; | 7 import 'dart:convert'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 | 9 |
| 10 import 'package:analysis_server/src/protocol.dart'; | 10 import 'package:analysis_server/src/protocol.dart'; |
| 11 | 11 |
| 12 /** | 12 /** |
| 13 * The abstract class [CommunicationChannel] defines the behavior of objects | 13 * The abstract class [ClientCommunicationChannel] defines the behavior of |
| 14 * that allow an [AnalysisServer] to receive [Request]s and to return both | 14 * objects that allows an object to send [Request]s to [AnalysisServer] and to |
| 15 * [Response]s and [Notification]s. | 15 * receive both [Response]s and [Notification]s. |
| 16 */ | 16 */ |
| 17 abstract class CommunicationChannel { | 17 abstract class ClientCommunicationChannel { |
| 18 /** |
| 19 * Listen to the channel for responses and notifications. |
| 20 * If a response is received, invoke the [onResponse] function. |
| 21 * If a notification is received, invoke the [onNotification] function. |
| 22 * If an error is encountered while trying to read from |
| 23 * the socket, invoke the [onError] function. If the socket is closed by the |
| 24 * client, invoke the [onDone] function. |
| 25 */ |
| 26 void listen(void onResponse(Response response), |
| 27 void onNotification(Notification notification), |
| 28 {void onError(), void onDone()}); |
| 29 |
| 30 /** |
| 31 * Send the given [request] to the server. |
| 32 */ |
| 33 void sendRequest(Request request); |
| 34 } |
| 35 |
| 36 /** |
| 37 * The abstract class [ServerCommunicationChannel] defines the behavior of |
| 38 * objects that allow an [AnalysisServer] to receive [Request]s and to return |
| 39 * both [Response]s and [Notification]s. |
| 40 */ |
| 41 abstract class ServerCommunicationChannel { |
| 18 /** | 42 /** |
| 19 * Listen to the channel for requests. If a request is received, invoke the | 43 * Listen to the channel for requests. If a request is received, invoke the |
| 20 * [onRequest] function. If an error is encountered while trying to read from | 44 * [onRequest] function. If an error is encountered while trying to read from |
| 21 * the socket, invoke the [onError] function. If the socket is closed by the | 45 * the socket, invoke the [onError] function. If the socket is closed by the |
| 22 * client, invoke the [onDone] function. | 46 * client, invoke the [onDone] function. |
| 23 */ | 47 */ |
| 24 void listen(void onRequest(Request request), {void onError(), void onDone()}); | 48 void listen(void onRequest(Request request), {void onError(), void onDone()}); |
| 25 | 49 |
| 26 /** | 50 /** |
| 27 * Send the given [notification] to the client. | 51 * Send the given [notification] to the client. |
| 28 */ | 52 */ |
| 29 void sendNotification(Notification notification); | 53 void sendNotification(Notification notification); |
| 30 | 54 |
| 31 /** | 55 /** |
| 32 * Send the given [request] to the server. | |
| 33 */ | |
| 34 void sendRequest(Request request); | |
| 35 | |
| 36 /** | |
| 37 * Send the given [response] to the client. | 56 * Send the given [response] to the client. |
| 38 */ | 57 */ |
| 39 void sendResponse(Response response); | 58 void sendResponse(Response response); |
| 40 } | 59 } |
| 41 | 60 |
| 42 /** | 61 /** |
| 43 * Instances of the class [WebSocketChannel] implement a [CommunicationChannel] | 62 * Instances of the class [WebSocketClientChannel] implement a |
| 44 * that uses a [WebSocket] to communicate with clients. | 63 * [ClientCommunicationChannel] that uses a [WebSocket] to communicate with |
| 64 * servers. |
| 45 */ | 65 */ |
| 46 class WebSocketChannel implements CommunicationChannel { | 66 class WebSocketClientChannel implements ClientCommunicationChannel { |
| 47 /** | 67 /** |
| 48 * The socket being wrapped. | 68 * The socket being wrapped. |
| 49 */ | 69 */ |
| 70 final WebSocket socket; |
| 71 |
| 72 final JsonEncoder jsonEncoder = const JsonEncoder(null); |
| 73 |
| 74 final JsonDecoder jsonDecoder = const JsonDecoder(null); |
| 75 |
| 76 /** |
| 77 * Initialize a newly create [WebSocket] wrapper to wrap the given [socket]. |
| 78 */ |
| 79 WebSocketClientChannel(this.socket); |
| 80 |
| 81 @override |
| 82 void listen(void onResponse(Response response), |
| 83 void onNotification(Notification notification), |
| 84 {void onError(), void onDone()}) { |
| 85 socket.listen((data) => _read(data, onResponse, onNotification), |
| 86 onError: onError, onDone: onDone); |
| 87 } |
| 88 |
| 89 @override |
| 90 void sendRequest(Request request) { |
| 91 socket.add(jsonEncoder.convert(request.toJson())); |
| 92 } |
| 93 |
| 94 /** |
| 95 * Read a request from the given [data] and use the given function to handle |
| 96 * the request. |
| 97 */ |
| 98 void _read(Object data, |
| 99 void onResponse(Response response), |
| 100 void onNotification(Notification notification)) { |
| 101 if (data is String) { |
| 102 // Parse the string as a JSON descriptor |
| 103 var json; |
| 104 try { |
| 105 json = jsonDecoder.convert(data); |
| 106 if (json is! Map) { |
| 107 return; |
| 108 } |
| 109 } catch (error) { |
| 110 return; |
| 111 } |
| 112 // Process the resulting structure as a response or notification. |
| 113 if (json[Notification.EVENT] != null) { |
| 114 Notification notification = new Notification.fromJson(json); |
| 115 if (notification != null) { |
| 116 onNotification(notification); |
| 117 } |
| 118 } else { |
| 119 Response response = new Response.fromJson(json); |
| 120 if (response != null) { |
| 121 onResponse(response); |
| 122 } |
| 123 } |
| 124 } |
| 125 } |
| 126 } |
| 127 |
| 128 /** |
| 129 * Instances of the class [WebSocketServerChannel] implement a |
| 130 * [ServerCommunicationChannel] that uses a [WebSocket] to communicate with |
| 131 * clients. |
| 132 */ |
| 133 class WebSocketServerChannel implements ServerCommunicationChannel { |
| 134 /** |
| 135 * The socket being wrapped. |
| 136 */ |
| 50 final WebSocket socket; | 137 final WebSocket socket; |
| 51 | 138 |
| 52 final JsonEncoder jsonEncoder = const JsonEncoder(null); | 139 final JsonEncoder jsonEncoder = const JsonEncoder(null); |
| 53 | 140 |
| 54 /** | 141 /** |
| 55 * Initialize a newly create [WebSocket] wrapper to wrap the given [socket]. | 142 * Initialize a newly create [WebSocket] wrapper to wrap the given [socket]. |
| 56 */ | 143 */ |
| 57 WebSocketChannel(this.socket); | 144 WebSocketServerChannel(this.socket); |
| 58 | 145 |
| 59 @override | 146 @override |
| 60 void listen(void onRequest(Request request), {void onError(), void onDone()})
{ | 147 void listen(void onRequest(Request request), {void onError(), void onDone()})
{ |
| 61 socket.listen((data) => | 148 socket.listen((data) => _readRequest(data, onRequest), onError: onError, |
| 62 _readRequest(data, onRequest), onError: onError, onDone: onDone); | 149 onDone: onDone); |
| 63 } | 150 } |
| 64 | 151 |
| 65 @override | 152 @override |
| 66 void sendNotification(Notification notification) { | 153 void sendNotification(Notification notification) { |
| 67 socket.add(jsonEncoder.convert(notification.toJson())); | 154 socket.add(jsonEncoder.convert(notification.toJson())); |
| 68 } | 155 } |
| 69 | 156 |
| 70 @override | 157 @override |
| 71 void sendRequest(Request request) { | |
| 72 socket.add(jsonEncoder.convert(request.toJson())); | |
| 73 } | |
| 74 | |
| 75 @override | |
| 76 void sendResponse(Response response) { | 158 void sendResponse(Response response) { |
| 77 socket.add(jsonEncoder.convert(response.toJson())); | 159 socket.add(jsonEncoder.convert(response.toJson())); |
| 78 } | 160 } |
| 79 | 161 |
| 80 /** | 162 /** |
| 81 * Read a request from the given [data] and use the given function to handle | 163 * Read a request from the given [data] and use the given function to handle |
| 82 * the request. | 164 * the request. |
| 83 */ | 165 */ |
| 84 void _readRequest(Object data, void onRequest(Request request)) { | 166 void _readRequest(Object data, void onRequest(Request request)) { |
| 85 if (data is List<int>) { | 167 if (data is List<int>) { |
| 86 sendResponse(new Response.invalidRequestFormat()); | 168 sendResponse(new Response.invalidRequestFormat()); |
| 87 return; | 169 return; |
| 88 } | 170 } |
| 89 if (data is String) { | 171 if (data is String) { |
| 90 // Parse the string as a JSON descriptor and process the resulting | 172 // Parse the string as a JSON descriptor and process the resulting |
| 91 // structure as a request. | 173 // structure as a request. |
| 92 Request request = new Request.fromString(data); | 174 Request request = new Request.fromString(data); |
| 93 if (request == null) { | 175 if (request == null) { |
| 94 sendResponse(new Response.invalidRequestFormat()); | 176 sendResponse(new Response.invalidRequestFormat()); |
| 95 return; | 177 return; |
| 96 } | 178 } |
| 97 onRequest(request); | 179 onRequest(request); |
| 98 } | 180 } |
| 99 } | 181 } |
| 100 } | 182 } |
| OLD | NEW |