public async Task LaunchAndServe(ProcessStartInfo psi, HttpContext context, Func <string, Task <string> > extract_conn_url) { if (!context.WebSockets.IsWebSocketRequest) { context.Response.StatusCode = 400; return; } var tcs = new TaskCompletionSource <string>(); var proc = Process.Start(psi); try { proc.ErrorDataReceived += (sender, e) => { var str = e.Data; Console.WriteLine($"stderr: {str}"); if (tcs.Task.IsCompleted) { return; } var match = parseConnection.Match(str); if (match.Success) { tcs.TrySetResult(match.Groups[1].Captures[0].Value); } }; proc.OutputDataReceived += (sender, e) => { Console.WriteLine($"stdout: {e.Data}"); }; proc.BeginErrorReadLine(); proc.BeginOutputReadLine(); if (await Task.WhenAny(tcs.Task, Task.Delay(5000)) != tcs.Task) { Console.WriteLine("Didnt get the con string after 5s."); throw new Exception("node.js timedout"); } var line = await tcs.Task; var con_str = extract_conn_url != null ? await extract_conn_url(line) : line; Console.WriteLine($"launching proxy for {con_str}"); using var loggerFactory = LoggerFactory.Create( builder => builder.AddConsole().AddFilter(null, LogLevel.Information)); var proxy = new DebuggerProxy(loggerFactory, null); var browserUri = new Uri(con_str); var ideSocket = await context.WebSockets.AcceptWebSocketAsync(); await proxy.Run(browserUri, ideSocket); Console.WriteLine("Proxy done"); } catch (Exception e) { Console.WriteLine("got exception {0}", e); } finally { proc.CancelErrorRead(); proc.CancelOutputRead(); proc.Kill(); proc.WaitForExit(); proc.Close(); } }
public async Task LaunchAndServe(ProcessStartInfo psi, HttpContext context, Func <string, Task <string> > extract_conn_url, string test_id, string message_prefix, int get_con_url_timeout_ms = 20000) { if (!context.WebSockets.IsWebSocketRequest) { context.Response.StatusCode = 400; return; } var tcs = new TaskCompletionSource <string>(); var proc = Process.Start(psi); try { proc.ErrorDataReceived += (sender, e) => { var str = e.Data; Logger.LogTrace($"{message_prefix} browser-stderr: {str}"); if (tcs.Task.IsCompleted) { return; } if (!string.IsNullOrEmpty(str)) { var match = parseConnection.Match(str); if (match.Success) { tcs.TrySetResult(match.Groups[1].Captures[0].Value); } } }; proc.OutputDataReceived += (sender, e) => { Logger.LogTrace($"{message_prefix} browser-stdout: {e.Data}"); }; proc.BeginErrorReadLine(); proc.BeginOutputReadLine(); if (await Task.WhenAny(tcs.Task, Task.Delay(get_con_url_timeout_ms)) != tcs.Task) { Logger.LogError($"{message_prefix} Timed out after {get_con_url_timeout_ms/1000}s waiting for a connection string from {psi.FileName}"); return; } var line = await tcs.Task; var con_str = extract_conn_url != null ? await extract_conn_url(line) : line; Logger.LogInformation($"{message_prefix} launching proxy for {con_str}"); string logFilePath = Path.Combine(DebuggerTests.DebuggerTestBase.TestLogPath, $"{test_id}-proxy.log"); File.Delete(logFilePath); var proxyLoggerFactory = LoggerFactory.Create( builder => builder .AddFile(logFilePath, minimumLevel: LogLevel.Information) .AddFilter(null, LogLevel.Trace)); var proxy = new DebuggerProxy(proxyLoggerFactory, null, loggerId: test_id); var browserUri = new Uri(con_str); var ideSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false); await proxy.Run(browserUri, ideSocket).ConfigureAwait(false); } catch (Exception e) { Logger.LogError($"{message_prefix} got exception {e}"); } finally { proc.CancelErrorRead(); proc.CancelOutputRead(); proc.Kill(); proc.WaitForExit(); proc.Close(); } }