@@ -27,6 +27,9 @@ import '../utilities/shared.dart';
2727import 'chrome_proxy_service.dart' ;
2828import 'expression_compiler.dart' ;
2929
30+ bool _acceptNewConnections = true ;
31+ int _clientsConnected = 0 ;
32+
3033void Function (WebSocketChannel , String ) _createNewConnectionHandler (
3134 ChromeProxyService chromeProxyService,
3235 ServiceExtensionRegistry serviceExtensionRegistry, {
@@ -51,9 +54,18 @@ void Function(WebSocketChannel, String) _createNewConnectionHandler(
5154 if (onRequest != null ) onRequest (request);
5255 return request;
5356 });
54-
57+ ++ _clientsConnected;
5558 VmServerConnection (inputStream, responseController.sink,
56- serviceExtensionRegistry, chromeProxyService);
59+ serviceExtensionRegistry, chromeProxyService)
60+ .done
61+ .whenComplete (() async {
62+ -- _clientsConnected;
63+ if (! _acceptNewConnections && _clientsConnected == 0 ) {
64+ // DDS has disconnected so we can allow for clients to connect directly
65+ // to DWDS.
66+ _acceptNewConnections = true ;
67+ }
68+ });
5769 };
5870}
5971
@@ -80,16 +92,27 @@ Future<void> _handleSseConnections(
8092 if (onRequest != null ) onRequest (request);
8193 return request;
8294 });
95+ ++ _clientsConnected;
8396 var vmServerConnection = VmServerConnection (inputStream,
8497 responseController.sink, serviceExtensionRegistry, chromeProxyService);
85- unawaited (vmServerConnection.done.whenComplete (sub.cancel));
98+ unawaited (vmServerConnection.done.whenComplete (() {
99+ -- _clientsConnected;
100+ if (! _acceptNewConnections && _clientsConnected == 0 ) {
101+ // DDS has disconnected so we can allow for clients to connect directly
102+ // to DWDS.
103+ _acceptNewConnections = true ;
104+ }
105+ return sub.cancel ();
106+ }));
86107 }
87108}
88109
89110/// A Dart Web Debug Service.
90111///
91112/// Creates a [ChromeProxyService] from an existing Chrome instance.
92113class DebugService {
114+ static String _ddsUri;
115+
93116 final VmServiceInterface chromeProxyService;
94117 final String hostname;
95118 final ServiceExtensionRegistry serviceExtensionRegistry;
@@ -124,6 +147,15 @@ class DebugService {
124147 : Uri (scheme: 'ws' , host: hostname, port: port, path: '$_authToken ' )
125148 .toString ();
126149
150+ static bool yieldControlToDDS (String uri) {
151+ if (_clientsConnected > 1 ) {
152+ return false ;
153+ }
154+ _ddsUri = uri;
155+ _acceptNewConnections = false ;
156+ return true ;
157+ }
158+
127159 static Future <DebugService > start (
128160 String hostname,
129161 RemoteDebugger remoteDebugger,
@@ -163,6 +195,13 @@ class DebugService {
163195 chromeProxyService, serviceExtensionRegistry,
164196 onRequest: onRequest, onResponse: onResponse));
165197 handler = (shelf.Request request) {
198+ if (! _acceptNewConnections) {
199+ return shelf.Response .forbidden (
200+ 'Cannot connect directly to the VM service as a Dart Development '
201+ 'Service (DDS) instance has taken control and can be found at '
202+ '$_ddsUri .' ,
203+ );
204+ }
166205 if (request.url.pathSegments.first != authToken) {
167206 return shelf.Response .forbidden ('Incorrect auth token' );
168207 }
0 commit comments