Skip to content

Commit

Permalink
Connecting DTD and DTD_impl together.
Browse files Browse the repository at this point in the history
This change adds the happy path for DTD_impl and DTD being able to:
- register streams
- register serviceMethods
- postEvents to streams
- call serviceMethods

Change-Id: I73865071745ef19a4493f86714e0855930243dd5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/341700
Reviewed-by: Ben Konyi <[email protected]>
Reviewed-by: Kenzie Davisson <[email protected]>
Commit-Queue: Dan Chevalier <[email protected]>
  • Loading branch information
Dan Chevalier authored and Commit Queue committed Dec 19, 2023
1 parent 08e3d3e commit e58efcb
Show file tree
Hide file tree
Showing 17 changed files with 821 additions and 68 deletions.
13 changes: 11 additions & 2 deletions pkg/dds/lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ class DartDevelopmentServiceClient {
return await _clientPeer.sendRequest(method, parameters);
}

/// Registers handlers for JSON RPC methods which need to be intercepted by
/// DDS as well as fallback request forwarder.
/// Registers handlers for JSON RPC method endpoints.
void _registerJsonRpcMethods() {
_clientPeer.registerMethod('streamListen', (parameters) async {
final streamId = parameters['streamId'].asString;
Expand All @@ -107,12 +106,22 @@ class DartDevelopmentServiceClient {
return RPCResponses.success;
});

/// jrpc endpoint for cancelling a stream.
///
/// Parameters:
/// 'streamId': the stream to be cancelled.
_clientPeer.registerMethod('streamCancel', (parameters) async {
final streamId = parameters['streamId'].asString;
await dds.streamManager.streamCancel(this, streamId);
return RPCResponses.success;
});

/// jrpc endpoint for posting an event to a stream.
///
/// Parameters:
/// 'eventKind': the kind of event being sent.
/// 'data': the data being sent over the stream.
/// 'stream: the stream that is being posted to.
_clientPeer.registerMethod('postEvent', (parameters) async {
final eventKind = parameters['eventKind'].asString;
final eventData = parameters['eventData'].asMap;
Expand Down
1 change: 1 addition & 0 deletions pkg/dtd/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ linter:
rules:
- avoid_void_async
- unawaited_futures
- require_trailing_commas
3 changes: 3 additions & 0 deletions pkg/dtd/example/dtd_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import 'package:dtd/dtd.dart';

void main() {
// TODO(@danchevalier) make simple testing services for ide's to know that
// things are working.

// TODO(@danchevalier): make this example meaningful
DartToolingDaemon.connect(Uri.parse('wss://127.0.0.1:12345'));
}
68 changes: 68 additions & 0 deletions pkg/dtd/example/dtd_service_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) 2023, 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.

import 'dart:async';

import 'package:dtd/dtd.dart';

//Extension side
class Bar extends DTDResponse {
late String baz;
late int bazCount;
late String bazDescription;

// ignore: use_super_parameters
Bar.fromDTDResponse(DTDResponse response) : super.fromDTDResponse(response) {
baz = result['baz'] as String;
bazCount = result['bazCount'] as int;
bazDescription = result['bazDescription'] as String;
}

@override
String toString() {
return 'Bar(baz:$baz, bazCount:$bazCount, bazDescription:$bazDescription)';
}
}

extension FooServiceExtension on DTDConnection {
Future<Bar> barExtension() async {
final result = await call(
'Foo',
'bar',
params: {
'baz': 'the baz',
'bazCount': 1,
'bazDescription': 'there is one baz',
},
);
return Bar.fromDTDResponse(result);
}
}

void main(List<String> args) async {
final url = args[0]; // pass the url as a param to the example
final fooService = await DartToolingDaemon.connect(Uri.parse('ws://$url'));
final client = await DartToolingDaemon.connect(Uri.parse('ws://$url'));

await fooService.registerService(
'Foo',
'bar',
(params) async {
final baz = params['baz'].value;
final bazCount = params['bazCount'].value;
final bazDescription = params['bazDescription'].value;
final result = {
'type': 'Bar',
'baz': baz,
'bazCount': bazCount,
'bazDescription': bazDescription,
};
return result;
},
);
final response = await client.barExtension();
final bar = Bar.fromDTDResponse(response);

print('Got a bar response: $bar');
}
28 changes: 28 additions & 0 deletions pkg/dtd/example/dtd_stream_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:dtd/dtd.dart';

void main(List<String> args) async {
final url = args[0]; // pass the url as a param to the example
final clientA = await DartToolingDaemon.connect(Uri.parse('ws://$url'));
final clientB = await DartToolingDaemon.connect(Uri.parse('ws://$url'));

clientA.onEvent('Foo').listen((event) {
print('A Received $event from Foo Stream');
});
clientB.onEvent('Foo').listen((event) {
print('B Received $event from Foo Stream');
});

await clientA.streamListen('Foo');
await clientB.streamListen('Foo');

clientA.postEvent('Foo', 'kind1', {'event': 1});

clientB.postEvent('Foo', 'kind2', {'event': 2});

// delayed so the Daemon connection is still up by the time the events come
// back.
await Future<void>.delayed(const Duration(seconds: 10));

await clientA.close();
await clientB.close();
}
6 changes: 4 additions & 2 deletions pkg/dtd/lib/src/dart_tooling_daemon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';

import 'package:web_socket_channel/web_socket_channel.dart';

import 'dtd_connection.dart';

// TODO(@danchevalier) make sure that there is html documentation just like the
// analysis server.

abstract class DartToolingDaemon {
// TODO(@danchevalier)
// TODO(@danchevalier) Dart Docs
static Future<DTDConnection> connect(Uri uri) async {
final channel = WebSocketChannel.connect(uri);
return DTDConnection(channel);
Expand Down
Loading

0 comments on commit e58efcb

Please sign in to comment.