blob: 9def4b42296cf081d52a44e3f6989a81120ae000 [file] [log] [blame]
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library channel;
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'protocol.dart';
/**
* The abstract class [CommunicationChannel] defines the behavior of objects
* that allow an [AnalysisServer] to receive [Request]s and to return both
* [Response]s and [Notification]s.
*/
abstract class CommunicationChannel {
/**
* Listen to the channel for requests. If a request is received, invoke the
* [onRequest] function. If an error is encountered while trying to read from
* the socket, invoke the [onError] function. If the socket is closed by the
* client, invoke the [onDone] function.
*/
void listen(void onRequest(Request request), {void onError(), void onDone()});
/**
* Send the given [notification] to the client.
*/
void sendNotification(Notification notification);
/**
* Send the given [response] to the client.
*/
void sendResponse(Response response);
}
/**
* Instances of the class [WebSocketChannel] implement a [CommunicationChannel]
* that uses a [WebSocket] to communicate with clients.
*/
class WebSocketChannel implements CommunicationChannel {
/**
* The socket being wrapped.
*/
final WebSocket socket;
/**
* Initialize a newly create [WebSocket] wrapper to wrap the given [socket].
*/
WebSocketChannel(this.socket);
@override
void listen(void onRequest(Request request), {void onError(), void onDone()}) {
socket.listen((data) => _readRequest(data, onRequest), onError: onError, onDone: onDone);
}
@override
void sendNotification(Notification notification) {
JsonEncoder encoder = const JsonEncoder(null);
socket.add(encoder.convert(notification.toJson()));
}
@override
void sendResponse(Response response) {
JsonEncoder encoder = const JsonEncoder(null);
socket.add(encoder.convert(response.toJson()));
}
/**
* Read a request from the given [data] and use the given function to handle
* the request.
*/
void _readRequest(Object data, void onRequest(Request request)) {
if (data is List<int>) {
sendResponse(new Response.invalidRequestFormat());
return;
}
if (data is String) {
// Parse the string as a JSON descriptor and process the resulting
// structure as a request.
Request request = new Request.fromString(data);
if (request == null) {
sendResponse(new Response.invalidRequestFormat());
return;
}
onRequest(request);
}
}
}