|
7 | 7 | using System.Net.WebSockets; |
8 | 8 | using System.Threading; |
9 | 9 |
|
10 | | -namespace TechStacks; |
| 10 | +namespace MyApp; |
11 | 11 |
|
12 | 12 | public static class Proxy |
13 | 13 | { |
@@ -234,6 +234,9 @@ public static async Task HttpToNode(HttpContext context, HttpClient nextClient) |
234 | 234 | await response.Content.CopyToAsync(context.Response.Body, context.RequestAborted); |
235 | 235 | } |
236 | 236 |
|
| 237 | + /// <summary> |
| 238 | + /// Proxy 404s to Node.js (except for API/backend routes) must be registered before endpoints |
| 239 | + /// </summary> |
237 | 240 | public static void MapNotFoundToNode(this WebApplication app, HttpClient nextClient, string[]? ignorePaths=null) |
238 | 241 | { |
239 | 242 | app.Use(async (context, next) => |
@@ -295,28 +298,35 @@ static async Task PumpWebSocket( |
295 | 298 | WebSocket destination, |
296 | 299 | CancellationToken cancellationToken) |
297 | 300 | { |
298 | | - var buffer = new byte[8192]; |
299 | | - |
300 | | - while (source.State == WebSocketState.Open && |
301 | | - destination.State == WebSocketState.Open) |
| 301 | + try |
302 | 302 | { |
303 | | - var result = await source.ReceiveAsync( |
304 | | - new ArraySegment<byte>(buffer), cancellationToken); |
| 303 | + var buffer = new byte[8192]; |
305 | 304 |
|
306 | | - if (result.MessageType == WebSocketMessageType.Close) |
| 305 | + while (source.State == WebSocketState.Open && |
| 306 | + destination.State == WebSocketState.Open) |
307 | 307 | { |
308 | | - await destination.CloseAsync( |
309 | | - source.CloseStatus ?? WebSocketCloseStatus.NormalClosure, |
310 | | - source.CloseStatusDescription, |
| 308 | + var result = await source.ReceiveAsync( |
| 309 | + new ArraySegment<byte>(buffer), cancellationToken); |
| 310 | + |
| 311 | + if (result.MessageType == WebSocketMessageType.Close) |
| 312 | + { |
| 313 | + await destination.CloseAsync( |
| 314 | + source.CloseStatus ?? WebSocketCloseStatus.NormalClosure, |
| 315 | + source.CloseStatusDescription, |
| 316 | + cancellationToken); |
| 317 | + break; |
| 318 | + } |
| 319 | + |
| 320 | + await destination.SendAsync( |
| 321 | + new ArraySegment<byte>(buffer, 0, result.Count), |
| 322 | + result.MessageType, |
| 323 | + result.EndOfMessage, |
311 | 324 | cancellationToken); |
312 | | - break; |
313 | 325 | } |
314 | | - |
315 | | - await destination.SendAsync( |
316 | | - new ArraySegment<byte>(buffer, 0, result.Count), |
317 | | - result.MessageType, |
318 | | - result.EndOfMessage, |
319 | | - cancellationToken); |
| 326 | + } |
| 327 | + catch (Exception e) |
| 328 | + { |
| 329 | + Console.WriteLine($"WebSocket Proxy: {e.Message}"); |
320 | 330 | } |
321 | 331 | } |
322 | 332 |
|
@@ -354,7 +364,9 @@ public static IEndpointConventionBuilder MapNextHmr(this WebApplication app, Htt |
354 | 364 | } |
355 | 365 | else |
356 | 366 | { |
357 | | - await HttpToNode(context, nodeClient); |
| 367 | + // HMR endpoint expects WebSocket connections only |
| 368 | + context.Response.StatusCode = StatusCodes.Status400BadRequest; |
| 369 | + await context.Response.WriteAsync("WebSocket connection expected"); |
358 | 370 | } |
359 | 371 | }); |
360 | 372 | } |
|
0 commit comments