-
Notifications
You must be signed in to change notification settings - Fork 93
Expand file tree
/
Copy pathdart_web_debug_service.dart
More file actions
172 lines (155 loc) · 6.12 KB
/
Copy pathdart_web_debug_service.dart
File metadata and controls
172 lines (155 loc) · 6.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Copyright (c) 2022, 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:dwds/data/build_result.dart';
import 'package:dwds/src/config/tool_configuration.dart';
import 'package:dwds/src/connections/app_connection.dart';
import 'package:dwds/src/connections/debug_connection.dart';
import 'package:dwds/src/events.dart';
import 'package:dwds/src/handlers/dev_handler.dart';
import 'package:dwds/src/handlers/injector.dart';
import 'package:dwds/src/handlers/socket_connections.dart';
import 'package:dwds/src/readers/asset_reader.dart';
import 'package:dwds/src/servers/devtools.dart';
import 'package:dwds/src/servers/extension_backend.dart';
import 'package:logging/logging.dart';
import 'package:shelf/shelf.dart';
import 'package:sse/server/sse_handler.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
typedef ConnectionProvider = Future<ChromeConnection> Function();
/// The Dart Web Debug Service.
class Dwds {
static final _logger = Logger('DWDS');
final Middleware middleware;
final Handler handler;
final DevTools? _devTools;
final DevHandler _devHandler;
final AssetReader _assetReader;
final bool _enableDebugging;
final bool _useDwdsWebSocketConnection;
Dwds._(
this.middleware,
this._devTools,
this._devHandler,
this._assetReader,
this._enableDebugging,
this._useDwdsWebSocketConnection,
) : handler = _devHandler.handler;
Stream<AppConnection> get connectedApps => _devHandler.connectedApps;
Stream<DwdsEvent> get events => eventStream;
StreamController<DebugConnection> get extensionDebugConnections =>
_devHandler.extensionDebugConnections;
Future<void> stop() async {
await _devTools?.close();
await _devHandler.close();
await _assetReader.close();
}
/// Creates a debug connection for the given app connection.
///
/// Returns a [DebugConnection] that wraps the appropriate debug services
/// based on the connection type (WebSocket or Chrome-based).
Future<DebugConnection> debugConnection(AppConnection appConnection) async {
if (!_enableDebugging) throw StateError('Debugging is not enabled.');
if (_useDwdsWebSocketConnection) {
return await _devHandler.createDebugConnectionForWebSocket(appConnection);
} else {
return await _devHandler.createDebugConnectionForChrome(appConnection);
}
}
static Future<Dwds> start({
required AssetReader assetReader,
required Stream<BuildResult> buildResults,
required ConnectionProvider chromeConnection,
required ToolConfiguration toolConfiguration,
bool useDwdsWebSocketConnection = false,
}) async {
globalToolConfiguration = toolConfiguration;
final debugSettings = toolConfiguration.debugSettings;
final appMetadata = toolConfiguration.appMetadata;
DevTools? devTools;
Future<String>? extensionUri;
ExtensionBackend? extensionBackend;
if (debugSettings.enableDebugExtension) {
final handler = debugSettings.useSseForDebugBackend
? SseSocketHandler(
SseHandler(
Uri.parse('/\$debug'),
// Proxy servers may actively kill long standing connections.
// Allow for clients to reconnect in a short window. Making the
// window too long may cause issues if the user closes a debug
// session and initiates a new one during the keepAlive window.
keepAlive: const Duration(seconds: 5),
),
)
: WebSocketSocketHandler();
extensionBackend = await ExtensionBackend.start(
handler,
appMetadata.hostname,
);
extensionUri = Future.value(
Uri(
scheme: debugSettings.useSseForDebugBackend ? 'http' : 'ws',
host: extensionBackend.hostname,
port: extensionBackend.port,
path: r'$debug',
).toString(),
);
final urlEncoder = debugSettings.urlEncoder;
if (urlEncoder != null) {
extensionUri = urlEncoder(await extensionUri);
}
}
// TODO(bkonyi): only allow for serving DevTools via DDS.
// ignore: deprecated_member_use_from_same_package
final devToolsLauncher = debugSettings.devToolsLauncher;
Uri? launchedDevToolsUri;
if (devToolsLauncher != null &&
// If DDS is configured to serve DevTools, use its instance.
!debugSettings.ddsConfiguration.serveDevTools) {
devTools = await devToolsLauncher(appMetadata.hostname);
launchedDevToolsUri = Uri(
scheme: 'http',
host: devTools.hostname,
port: devTools.port,
);
_logger.info('Serving DevTools at $launchedDevToolsUri\n');
}
final injected = DwdsInjector(extensionUri: extensionUri);
final devHandler = DevHandler(
chromeConnection,
buildResults,
devTools,
assetReader,
appMetadata.hostname,
extensionBackend,
debugSettings.urlEncoder,
debugSettings.useSseForDebugProxy,
debugSettings.useSseForInjectedClient,
debugSettings.expressionCompiler,
injected,
DartDevelopmentServiceConfiguration(
// This technically isn't correct, but DartDevelopmentServiceConfiguration.enable
// is true by default, so this won't break unmigrated tools.
// ignore: deprecated_member_use_from_same_package
enable: debugSettings.spawnDds && debugSettings.ddsConfiguration.enable,
// ignore: deprecated_member_use_from_same_package
port: debugSettings.ddsPort ?? debugSettings.ddsConfiguration.port,
devToolsServerAddress:
launchedDevToolsUri ??
debugSettings.ddsConfiguration.devToolsServerAddress,
serveDevTools: debugSettings.ddsConfiguration.serveDevTools,
),
debugSettings.launchDevToolsInNewWindow,
useWebSocketConnection: useDwdsWebSocketConnection,
);
return Dwds._(
injected.middleware,
devTools,
devHandler,
assetReader,
debugSettings.enableDebugging,
useDwdsWebSocketConnection,
);
}
}