рабочий вариант, но скороть 10 МБит
This commit is contained in:
@@ -125,9 +125,9 @@ through Docker context `test-ubuntu` / SSH alias `docker-test`.
|
||||
|
||||
## Structured Messaging
|
||||
|
||||
- Backend HTTP errors are parsed as structured envelopes instead of legacy raw strings.
|
||||
- Backend HTTP errors are parsed as structured envelopes instead of compat raw strings.
|
||||
- WebSocket envelopes may now include `event` alongside the existing `type` and `payload`.
|
||||
- `BackendApiClient` preserves compatibility with legacy `"error": "..."` responses, but prefers the structured form when available.
|
||||
- `BackendApiClient` preserves compatibility with compat `"error": "..."` responses, but prefers the structured form when available.
|
||||
- `SessionWindowViewModel` resolves websocket event messages by `message_key` first and only then falls back to `fallback_message`.
|
||||
- Runtime smoke now proves both paths against the live backend: `message_key` resolution for invalid-login errors and fallback rendering for websocket state events whose keys are intentionally not present in client resources.
|
||||
|
||||
|
||||
+10
-10
@@ -619,7 +619,7 @@ public sealed class SessionWindowViewModel : ObservableObject
|
||||
Trace.WriteLine($"[{DateTimeOffset.Now:O}] [T{Environment.CurrentManagedThreadId}] SessionWindowViewModel.DisposeAsync completed: {SessionId}");
|
||||
}
|
||||
|
||||
private async Task ConnectGatewayAsync(AttachTokenDto attachToken, CancellationToken cancellationToken, bool forceBackendGatewayFallback = false)
|
||||
private async Task ConnectGatewayAsync(AttachTokenDto attachToken, CancellationToken cancellationToken, bool forceCompatGatewayFallback = false)
|
||||
{
|
||||
if (_isDisposed || _isUserClosing)
|
||||
{
|
||||
@@ -636,7 +636,7 @@ public sealed class SessionWindowViewModel : ObservableObject
|
||||
});
|
||||
_connection = await _sessionGatewayClient.ConnectAsync(
|
||||
attachToken.Token,
|
||||
forceBackendGatewayFallback ? null : _dataPlane,
|
||||
forceCompatGatewayFallback ? null : _dataPlane,
|
||||
HandleEnvelopeAsync,
|
||||
HandleConnectionClosedAsync,
|
||||
cancellationToken);
|
||||
@@ -655,7 +655,7 @@ public sealed class SessionWindowViewModel : ObservableObject
|
||||
{
|
||||
ConnectionStatus = Strings.Get("status.session.connection.connected");
|
||||
AddEventCore(Strings.Get("events.session.gateway_connected"));
|
||||
Trace.WriteLine($"[{DateTimeOffset.Now:O}] [T{Environment.CurrentManagedThreadId}] data_plane.transport session_window_connected session={SessionId} transport={_connection.TransportKind} force_backend_gateway_fallback={forceBackendGatewayFallback}");
|
||||
Trace.WriteLine($"[{DateTimeOffset.Now:O}] [T{Environment.CurrentManagedThreadId}] data_plane.transport session_window_connected session={SessionId} transport={_connection.TransportKind} force_compat_gateway_fallback={forceCompatGatewayFallback}");
|
||||
if (_attachToken?.Token == attachToken.Token)
|
||||
{
|
||||
_attachToken = null;
|
||||
@@ -878,8 +878,8 @@ public sealed class SessionWindowViewModel : ObservableObject
|
||||
}
|
||||
|
||||
string? closedTransportKind = _connection?.TransportKind;
|
||||
bool shouldTryBackendFallback = closedTransportKind == DirectWorkerWssTransportKind;
|
||||
Trace.WriteLine($"[{DateTimeOffset.Now:O}] [T{Environment.CurrentManagedThreadId}] data_plane.transport closed session={SessionId} transport={closedTransportKind ?? "<unknown>"} fallback_candidate={shouldTryBackendFallback}");
|
||||
bool shouldTryCompatFallback = closedTransportKind == DirectWorkerWssTransportKind;
|
||||
Trace.WriteLine($"[{DateTimeOffset.Now:O}] [T{Environment.CurrentManagedThreadId}] data_plane.transport closed session={SessionId} transport={closedTransportKind ?? "<unknown>"} fallback_candidate={shouldTryCompatFallback}");
|
||||
|
||||
await RunOnUiAsync(() =>
|
||||
{
|
||||
@@ -953,7 +953,7 @@ public sealed class SessionWindowViewModel : ObservableObject
|
||||
|
||||
if (refreshedSession?.State == "active")
|
||||
{
|
||||
await ReconnectAfterTransportCloseAsync(forceBackendGatewayFallback: shouldTryBackendFallback || closedTransportKind == "backend_gateway", closedTransportKind);
|
||||
await ReconnectAfterTransportCloseAsync(forceCompatGatewayFallback: shouldTryCompatFallback || closedTransportKind == "backend_gateway", closedTransportKind);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1016,7 +1016,7 @@ public sealed class SessionWindowViewModel : ObservableObject
|
||||
return lastSeenSession;
|
||||
}
|
||||
|
||||
private async Task ReconnectAfterTransportCloseAsync(bool forceBackendGatewayFallback, string? closedTransportKind)
|
||||
private async Task ReconnectAfterTransportCloseAsync(bool forceCompatGatewayFallback, string? closedTransportKind)
|
||||
{
|
||||
if (_isDisposed || _isUserClosing ||
|
||||
_authenticationService.CurrentUserId is null ||
|
||||
@@ -1027,7 +1027,7 @@ public sealed class SessionWindowViewModel : ObservableObject
|
||||
|
||||
try
|
||||
{
|
||||
Trace.WriteLine($"[{DateTimeOffset.Now:O}] [T{Environment.CurrentManagedThreadId}] data_plane.transport reconnect_start session={SessionId} from={closedTransportKind ?? "<unknown>"} force_backend_gateway_fallback={forceBackendGatewayFallback}");
|
||||
Trace.WriteLine($"[{DateTimeOffset.Now:O}] [T{Environment.CurrentManagedThreadId}] data_plane.transport reconnect_start session={SessionId} from={closedTransportKind ?? "<unknown>"} force_compat_gateway_fallback={forceCompatGatewayFallback}");
|
||||
SessionControlResultDto result = await _sessionService.AttachSessionAsync(
|
||||
_session.ID,
|
||||
_authenticationService.CurrentUserId,
|
||||
@@ -1063,8 +1063,8 @@ public sealed class SessionWindowViewModel : ObservableObject
|
||||
return;
|
||||
}
|
||||
|
||||
await ConnectGatewayAsync(_attachToken, _lifetimeCancellation.Token, forceBackendGatewayFallback);
|
||||
Trace.WriteLine($"[{DateTimeOffset.Now:O}] [T{Environment.CurrentManagedThreadId}] data_plane.transport reconnect_success session={SessionId} force_backend_gateway_fallback={forceBackendGatewayFallback}");
|
||||
await ConnectGatewayAsync(_attachToken, _lifetimeCancellation.Token, forceCompatGatewayFallback);
|
||||
Trace.WriteLine($"[{DateTimeOffset.Now:O}] [T{Environment.CurrentManagedThreadId}] data_plane.transport reconnect_success session={SessionId} force_compat_gateway_fallback={forceCompatGatewayFallback}");
|
||||
}
|
||||
catch (OperationCanceledException) when (_lifetimeCancellation.IsCancellationRequested || _isDisposed || _isUserClosing)
|
||||
{
|
||||
|
||||
@@ -232,7 +232,7 @@ public sealed class BackendApiClient : IBackendAuthClient, IBackendOrganizationC
|
||||
{
|
||||
return new LocalizedMessageDto
|
||||
{
|
||||
Code = "common.legacy_error",
|
||||
Code = "common.compat_error",
|
||||
MessageKey = "errors.common.unexpected",
|
||||
FallbackMessage = errorElement.GetString() ?? "Request failed."
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ public sealed class SessionGatewayClient(BackendEndpointOptions options) : ISess
|
||||
private const string DirectRuntimeTransportJsonV1 = "json_v1";
|
||||
private const string DirectRenderTransportMetadataKey = "render_transport";
|
||||
private const string DirectRenderTransportBinaryV1 = "binary_v1";
|
||||
private const string BinaryRenderLegacyMessageType = "session.frame";
|
||||
private const string BinaryRenderPreviousMessageType = "session.frame";
|
||||
private const string BinaryRenderFullMessageType = "render.frame.full";
|
||||
private const string BinaryRenderRegionMessageType = "render.frame.region";
|
||||
private const string DirectTLSTrustModeMetadataKey = "tls_trust_mode";
|
||||
@@ -857,7 +857,7 @@ public sealed class SessionGatewayClient(BackendEndpointOptions options) : ISess
|
||||
|
||||
private static bool IsSupportedBinaryRenderMessageType(string? messageType)
|
||||
{
|
||||
return string.Equals(messageType, BinaryRenderLegacyMessageType, StringComparison.OrdinalIgnoreCase) ||
|
||||
return string.Equals(messageType, BinaryRenderPreviousMessageType, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(messageType, BinaryRenderFullMessageType, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(messageType, BinaryRenderRegionMessageType, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user