Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions RemoteViewer.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
<Project Path="tests/RemoteViewer.Server.Tests/RemoteViewer.Server.Tests.csproj" />
<Project Path="tests/RemoteViewer.Shared.Tests/RemoteViewer.Shared.Tests.csproj" />
<Project Path="tests/RemoteViewer.IntegrationTests/RemoteViewer.IntegrationTests.csproj" />
<Project Path="tests/RemoteViewer.TestFixtures/RemoteViewer.TestFixtures.csproj" />
</Folder>
</Solution>
2 changes: 1 addition & 1 deletion src/RemoteViewer.Client/RemoteViewer.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
<ProjectReference Include="..\RemoteViewer.Shared\RemoteViewer.Shared.csproj" />
</ItemGroup>


<ItemGroup>
<PackageReference Include="Avalonia" Version="11.3.10" />
<PackageReference Include="Material.Icons.Avalonia" Version="2.4.1" />
Expand Down Expand Up @@ -54,4 +53,5 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

</Project>
6 changes: 5 additions & 1 deletion src/RemoteViewer.Client/Services/HubClient/Connection.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using RemoteViewer.Client.Common;
using RemoteViewer.Client.Services.FileTransfer;
Expand Down Expand Up @@ -463,6 +463,10 @@ async void IConnectionImpl.OnMessageReceived(string senderClientId, string messa
{
var message = ProtocolSerializer.Deserialize<FrameMessage>(data);
((IViewerServiceImpl)this.ViewerService!).HandleFrame(message.DisplayId, message.FrameNumber, message.Codec, message.Regions);

if (this.Owner.Options.SuppressAutoFrameAck is false)
await this.Owner.SendAckFrameAsync(this.ConnectionId);

break;
}

Expand Down
52 changes: 36 additions & 16 deletions src/RemoteViewer.Client/Services/HubClient/ConnectionHubClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Concurrent;
using System.Collections.Concurrent;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
Expand All @@ -23,13 +23,15 @@ public ConnectionHubClient(
{
this._logger = logger;
this._serviceProvider = serviceProvider;
this.Options = options.Value;

this._connection = new HubConnectionBuilder()
.WithUrl($"{options.Value.BaseUrl}/connection", httpOptions =>
.WithUrl($"{this.Options.BaseUrl}/connection", httpOptions =>
{
httpOptions.Headers.Add("X-Client-Version", ThisAssembly.AssemblyInformationalVersion);
httpOptions.Headers.Add("X-Display-Name", this.DisplayName);
})

.WithAutomaticReconnect()
.AddMessagePackProtocol(Witness.GeneratedTypeShapeProvider)
.Build();
Expand Down Expand Up @@ -174,6 +176,8 @@ private void CloseAllConnections()
this._connections.Clear();
}

public ConnectionHubClientOptions Options { get; }

public string? ClientId { get; private set; }
public string? Username { get; private set; }
public string? Password { get; private set; }
Expand Down Expand Up @@ -260,9 +264,9 @@ public async Task ConnectToHub()

return error;
}
catch (Exception ex) when (!this.IsConnected)
catch (Exception ex)
{
this._logger.LogWarning(ex, "Failed to connect to device - hub disconnected");
this._logger.LogWarning(ex, "Failed to connect to device");
return null;
}
}
Expand All @@ -278,9 +282,9 @@ public async Task GenerateNewPassword()
await this._connection.InvokeAsync("GenerateNewPassword");
this._logger.LogInformation("New password generated");
}
catch (Exception ex) when (!this.IsConnected)
catch (Exception ex)
{
this._logger.LogWarning(ex, "Failed to generate new password - hub disconnected");
this._logger.LogWarning(ex, "Failed to generate new password");
}
}

Expand All @@ -297,9 +301,9 @@ public async Task SetDisplayName(string displayName)
await this._connection.InvokeAsync("SetDisplayName", displayName);
this._logger.LogInformation("Display name set successfully");
}
catch (Exception ex) when (!this.IsConnected)
catch (Exception ex)
{
this._logger.LogWarning(ex, "Failed to set display name - hub disconnected");
this._logger.LogWarning(ex, "Failed to set display name");
}
}

Expand All @@ -321,9 +325,9 @@ internal async Task SendMessageAsync(string connectionId, string messageType, Re
await this._connection.SendAsync("SendMessage", connectionId, messageType, data, destination, targetClientIds);
this._logger.LogDebug("Message sent successfully");
}
catch (Exception ex) when (!this.IsConnected)
catch (Exception ex)
{
this._logger.LogWarning(ex, "Failed to send message - hub disconnected");
this._logger.LogWarning(ex, "Failed to send message");
}
}

Expand All @@ -338,9 +342,9 @@ internal async Task DisconnectAsync(string connectionId)
await this._connection.InvokeAsync("Disconnect", connectionId);
this._logger.LogInformation("Disconnected from connection: {ConnectionId}", connectionId);
}
catch (Exception ex) when (!this.IsConnected)
catch (Exception ex)
{
this._logger.LogWarning(ex, "Failed to disconnect - hub disconnected");
this._logger.LogWarning(ex, "Failed to disconnect");
}
}

Expand All @@ -354,9 +358,9 @@ internal async Task SetConnectionPropertiesAsync(string connectionId, Connection
this._logger.LogDebug("Setting connection properties - ConnectionId: {ConnectionId}", connectionId);
await this._connection.InvokeAsync("SetConnectionProperties", connectionId, properties);
}
catch (Exception ex) when (!this.IsConnected)
catch (Exception ex)
{
this._logger.LogWarning(ex, "Failed to set connection properties - hub disconnected");
this._logger.LogWarning(ex, "Failed to set connection properties");
}
}

Expand All @@ -370,12 +374,28 @@ internal async Task SetConnectionPropertiesAsync(string connectionId, Connection
this._logger.LogDebug("Generating IPC auth token for connection: {ConnectionId}", connectionId);
return await this._connection.InvokeAsync<string?>("GenerateIpcAuthToken", connectionId);
}
catch (Exception ex) when (!this.IsConnected)
catch (Exception ex)
{
this._logger.LogWarning(ex, "Failed to generate IPC auth token - hub disconnected");
this._logger.LogWarning(ex, "Failed to generate IPC auth token");
return null;
}
}

internal async Task SendAckFrameAsync(string connectionId)
{
if (!this.IsConnected || this.IsReconnecting)
return;

try
{
await this._connection.SendAsync("AckFrame", connectionId);
}
catch (Exception ex)
{
this._logger.LogWarning(ex, "Failed to send frame ack");
}
}

}

#region EventArgs Classes
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Http.Connections;
namespace RemoteViewer.Client.Services.HubClient;

namespace RemoteViewer.Client.Services.HubClient;

public class ConnectionHubClientOptions
{
Expand All @@ -9,4 +8,6 @@ public class ConnectionHubClientOptions
#else
public string BaseUrl { get; set; } = "https://rdp.xemio.net";
#endif

public bool SuppressAutoFrameAck { get; set; }
}
6 changes: 6 additions & 0 deletions src/RemoteViewer.Server/Hubs/ConnectionHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ public async Task SendMessage(string connectionId, string messageType, byte[] da
await clientsService.SendMessage(this.Context.ConnectionId, connectionId, messageType, data, destination, targetClientIds);
}

public Task AckFrame(string connectionId)
{
return clientsService.AckFrame(this.Context.ConnectionId, connectionId);
}


public async Task SetConnectionProperties(string connectionId, ConnectionProperties properties)
{
await clientsService.SetConnectionProperties(this.Context.ConnectionId, connectionId, properties);
Expand Down
10 changes: 8 additions & 2 deletions src/RemoteViewer.Server/Orleans/Grains/ClientGrain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public sealed partial class ClientGrain(ILogger<ClientGrain> logger, IHubContext

private string _displayName = string.Empty;

private IClientSendGrain? _sendGrain;

private IConnectionGrain? _presenterConnectionGrain;
private readonly List<IConnectionGrain> _viewerConnectionGrains = [];

Expand Down Expand Up @@ -67,6 +69,8 @@ public async Task Initialize(string? displayName)
this.LogUsernameCollision(attempts);
}

this._sendGrain = this.GrainFactory.GetGrain<IClientSendGrain>(this.GetPrimaryKeyString());

this.LogClientInitialized(this._clientId, this._usernameGrain.GetPrimaryKeyString());

await hubContext.Clients
Expand All @@ -93,6 +97,7 @@ public async Task Deactivate()
await connection.Internal_RemoveClient(this.AsReference<IClientGrain>());
}

await this._sendGrain.Disconnect();
await this._usernameGrain.ReleaseAsync(this.GetPrimaryKeyString());

this.DeactivateOnIdle();
Expand Down Expand Up @@ -208,14 +213,15 @@ private static string FormatUsername(string username)
}
return sb.ToString();
}
[MemberNotNull(nameof(_clientId), nameof(_usernameGrain), nameof(_password))]
[MemberNotNull(nameof(_clientId), nameof(_usernameGrain), nameof(_sendGrain), nameof(_password))]
private void EnsureInitialized()
{
if (this._clientId is null || this._usernameGrain is null || this._password is null)
if (this._clientId is null || this._usernameGrain is null || this._sendGrain is null || this._password is null)
{
throw new InvalidOperationException(
$"ClientGrain not initialized: clientId={(this._clientId is null ? "null" : "set")}, " +
$"usernameGrain={(this._usernameGrain is null ? "null" : "set")}, " +
$"sendGrain={(this._sendGrain is null ? "null" : "set")}, " +
$"password={(this._password is null ? "null" : "set")}");
}
}
Expand Down
Loading