Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
bitbound committed Apr 11, 2021
2 parents 7677c32 + 298fad4 commit b6774e5
Show file tree
Hide file tree
Showing 33 changed files with 487 additions and 267 deletions.
4 changes: 2 additions & 2 deletions Agent/Agent.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.5" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.5" />
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.1.3" />
<PackageReference Include="Microsoft.WSMan.Management" Version="7.1.3" />
<PackageReference Include="Microsoft.WSMan.Runtime" Version="7.1.3" />
Expand Down
6 changes: 2 additions & 4 deletions Desktop.Core/Desktop.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,13 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.5" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.5" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="5.0.0" />
<PackageReference Include="Microsoft.MixedReality.WebRTC" Version="2.0.2" />
<PackageReference Include="SkiaSharp" Version="2.80.2" />
<PackageReference Include="SkiaSharp.Views.Desktop.Common" Version="2.80.2" />
<PackageReference Include="System.Drawing.Common" Version="5.0.2" />
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
</ItemGroup>
Expand Down
3 changes: 2 additions & 1 deletion Desktop.Core/Interfaces/IFileTransferService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Remotely.Desktop.Core.Services;
using Remotely.Desktop.Core.ViewModels;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Remotely.Desktop.Core.Interfaces
Expand All @@ -11,6 +12,6 @@ public interface IFileTransferService

Task ReceiveFile(byte[] buffer, string fileName, string messageId, bool endOfFile, bool startOfFile);
void OpenFileTransferWindow(Viewer viewer);
Task UploadFile(FileUpload file, Viewer viewer, Action<double> progressUpdateCallback);
Task UploadFile(FileUpload file, Viewer viewer, CancellationToken cancelToken, Action<double> progressUpdateCallback);
}
}
36 changes: 15 additions & 21 deletions Desktop.Core/Services/DtoMessageHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Remotely.Desktop.Core.Services
{
public interface IDtoMessageHandler
{
Task ParseMessage(Services.Viewer viewer, byte[] message);
Task ParseMessage(Viewer viewer, byte[] message);
}
public class DtoMessageHandler : IDtoMessageHandler
{
Expand All @@ -31,7 +31,7 @@ public DtoMessageHandler(IKeyboardMouseInput keyboardMouseInput,
private IClipboardService ClipboardService { get; }
private IFileTransferService FileTransferService { get; }
private IKeyboardMouseInput KeyboardMouseInput { get; }
public async Task ParseMessage(Services.Viewer viewer, byte[] message)
public async Task ParseMessage(Viewer viewer, byte[] message)
{
try
{
Expand Down Expand Up @@ -154,25 +154,19 @@ await FileTransferService.ReceiveFile(dto.Buffer,
dto.StartOfFile);
}

private async Task GetWindowsSessions(Services.Viewer viewer)
private async Task GetWindowsSessions(Viewer viewer)
{
await viewer.SendWindowsSessions();
}

private void HandleFrameReceived(Services.Viewer viewer)
private void HandleFrameReceived(Viewer viewer)
{
for (int i = 0; i < 5; i++)
while (viewer.PendingSentFrames.Count > 0 &&
!viewer.IsStalled &&
viewer.IsConnected)
{
if (viewer.PendingSentFrames.TryDequeue(out var frame))
if (viewer.PendingSentFrames.TryDequeue(out _))
{
var roundtrip = (DateTimeOffset.Now - frame.Timestamp).TotalSeconds;
var bps = frame.FrameSize / (roundtrip / 2);

if (bps > viewer.PeakBytesPerSecond)
{
viewer.PeakBytesPerSecond = bps;
Debug.WriteLine($"Peak Mbps: {bps / 1024 / 1024 * 8}");
}
break;
}
}
Expand All @@ -198,19 +192,19 @@ private void KeyUp(byte[] message)
KeyboardMouseInput.SendKeyUp(dto.Key);
}

private void MouseDown(byte[] message, Services.Viewer viewer)
private void MouseDown(byte[] message, Viewer viewer)
{
var dto = MessagePackSerializer.Deserialize<MouseDownDto>(message);
KeyboardMouseInput.SendMouseButtonAction(dto.Button, ButtonAction.Down, dto.PercentX, dto.PercentY, viewer);
}

private void MouseMove(byte[] message, Services.Viewer viewer)
private void MouseMove(byte[] message, Viewer viewer)
{
var dto = MessagePackSerializer.Deserialize<MouseMoveDto>(message);
KeyboardMouseInput.SendMouseMove(dto.PercentX, dto.PercentY, viewer);
}

private void MouseUp(byte[] message, Services.Viewer viewer)
private void MouseUp(byte[] message, Viewer viewer)
{
var dto = MessagePackSerializer.Deserialize<MouseUpDto>(message);
KeyboardMouseInput.SendMouseButtonAction(dto.Button, ButtonAction.Up, dto.PercentX, dto.PercentY, viewer);
Expand All @@ -222,12 +216,12 @@ private void MouseWheel(byte[] message)
KeyboardMouseInput.SendMouseWheel(-(int)dto.DeltaY);
}

private void OpenFileTransferWindow(Services.Viewer viewer)
private void OpenFileTransferWindow(Viewer viewer)
{
FileTransferService.OpenFileTransferWindow(viewer);
}

private void SelectScreen(byte[] message, Services.Viewer viewer)
private void SelectScreen(byte[] message, Viewer viewer)
{
var dto = MessagePackSerializer.Deserialize<SelectScreenDto>(message);
viewer.Capturer.SetSelectedScreen(dto.DisplayName);
Expand All @@ -238,7 +232,7 @@ private void SetKeyStatesUp()
KeyboardMouseInput.SetKeyStatesUp();
}

private void Tap(byte[] message, Services.Viewer viewer)
private void Tap(byte[] message, Viewer viewer)
{
var dto = MessagePackSerializer.Deserialize<TapDto>(message);
KeyboardMouseInput.SendMouseButtonAction(0, ButtonAction.Down, dto.PercentX, dto.PercentY, viewer);
Expand All @@ -257,7 +251,7 @@ private void ToggleBlockInput(byte[] message)
KeyboardMouseInput.ToggleBlockInput(dto.ToggleOn);
}

private void ToggleWebRtcVideo(byte[] message, Services.Viewer viewer)
private void ToggleWebRtcVideo(byte[] message, Viewer viewer)
{
var dto = MessagePackSerializer.Deserialize<ToggleWebRtcVideoDto>(message);
viewer.ToggleWebRtcVideo(dto.ToggleOn);
Expand Down
28 changes: 14 additions & 14 deletions Desktop.Core/Services/ScreenCaster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using SkiaSharp;

namespace Remotely.Desktop.Core.Services
{
Expand Down Expand Up @@ -55,6 +54,8 @@ public async Task BeginScreenCasting(ScreenCastRequest screenCastRequest)
viewer.Name = screenCastRequest.RequesterName;
viewer.ViewerConnectionID = screenCastRequest.ViewerID;

var screenBounds = viewer.Capturer.CurrentScreenBounds;

Logger.Write($"Starting screen cast. Requester: {viewer.Name}. " +
$"Viewer ID: {viewer.ViewerConnectionID}. App Mode: {_conductor.Mode}");

Expand All @@ -78,8 +79,7 @@ await viewer.SendScreenData(
viewer.Capturer.SelectedScreen,
viewer.Capturer.GetDisplayNames().ToArray());

await viewer.SendScreenSize(viewer.Capturer.CurrentScreenBounds.Width,
viewer.Capturer.CurrentScreenBounds.Height);
await viewer.SendScreenSize(screenBounds.Width, screenBounds.Height);

await viewer.SendCursorChange(_cursorIconWatcher.GetCurrentCursor());

Expand All @@ -96,11 +96,11 @@ await viewer.SendScreenSize(viewer.Capturer.CurrentScreenBounds.Width,
{
await viewer.SendScreenCapture(new CaptureFrame()
{
EncodedImageBytes = ImageUtils.EncodeWithSkia(initialFrame, SKEncodedImageFormat.Webp, _maxQuality),
Left = viewer.Capturer.CurrentScreenBounds.Left,
Top = viewer.Capturer.CurrentScreenBounds.Top,
Width = viewer.Capturer.CurrentScreenBounds.Width,
Height = viewer.Capturer.CurrentScreenBounds.Height
EncodedImageBytes = ImageUtils.EncodeJpeg(initialFrame, _maxQuality),
Left = screenBounds.Left,
Top = screenBounds.Top,
Width = screenBounds.Width,
Height = screenBounds.Height
});
}
}
Expand Down Expand Up @@ -172,23 +172,23 @@ await viewer.SendScreenCapture(new CaptureFrame()
if (viewer.Capturer.CaptureFullscreen)
{
// Recalculate Bps.
viewer.PeakBytesPerSecond = 0;
encodedImageBytes = ImageUtils.EncodeWithSkia(clone, SKEncodedImageFormat.Jpeg, _maxQuality);
viewer.AverageBytesPerSecond = 0;
encodedImageBytes = ImageUtils.EncodeJpeg(clone, _maxQuality);
}
else
{
if (viewer.PeakBytesPerSecond > 0)
if (viewer.AverageBytesPerSecond > 0)
{
var expectedSize = clone.Height * clone.Width * 4 * .1;
var timeToSend = expectedSize / viewer.PeakBytesPerSecond;
var timeToSend = expectedSize / viewer.AverageBytesPerSecond;
currentQuality = Math.Max(_minQuality, Math.Min(_maxQuality, (int)(.1 / timeToSend * _maxQuality)));
if (currentQuality < _maxQuality - 10)
{
refreshNeeded = true;
Debug.WriteLine($"Quality Reduced: {currentQuality}");
}
Debug.WriteLine($"Current Quality: {currentQuality}");
}
encodedImageBytes = ImageUtils.EncodeWithSkia(clone, SKEncodedImageFormat.Jpeg, currentQuality);
encodedImageBytes = ImageUtils.EncodeJpeg(clone, currentQuality);
}

viewer.Capturer.CaptureFullscreen = false;
Expand Down
49 changes: 36 additions & 13 deletions Desktop.Core/Services/Viewer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;

namespace Remotely.Desktop.Core.Services
{
public class Viewer : IDisposable
{
private long _bytesSent;
private TimeSpan _timeSpentSending = TimeSpan.Zero;

public Viewer(ICasterSocket casterSocket,
IScreenCapturer screenCapturer,
IClipboardService clipboardService,
Expand Down Expand Up @@ -64,7 +69,7 @@ public bool IsUsingWebRtcVideo

public string Name { get; set; }

public double PeakBytesPerSecond { get; set; }
public double AverageBytesPerSecond { get; set; }
public ConcurrentQueue<SentFrame> PendingSentFrames { get; } = new();

public WebRtcSession RtcSession { get; set; }
Expand Down Expand Up @@ -150,7 +155,7 @@ await SendToViewer(() => RtcSession.SendDto(dto),
() => CasterSocket.SendDtoToViewer(dto, ViewerConnectionID));
}

public async Task SendFile(FileUpload fileUpload, Action<double> progressUpdateCallback)
public async Task SendFile(FileUpload fileUpload, CancellationToken cancelToken, Action<double> progressUpdateCallback)
{
try
{
Expand All @@ -163,13 +168,18 @@ public async Task SendFile(FileUpload fileUpload, Action<double> progressUpdateC
StartOfFile = true
};

await SendToViewer(() => RtcSession.SendDto(fileDto),
() => CasterSocket.SendDtoToViewer(fileDto, ViewerConnectionID));
await SendToViewer(async () => await RtcSession.SendDto(fileDto),
async () => await CasterSocket.SendDtoToViewer(fileDto, ViewerConnectionID));

using var fs = File.OpenRead(fileUpload.FilePath);
using var br = new BinaryReader(fs);
while (fs.Position < fs.Length)
{
if (cancelToken.IsCancellationRequested)
{
return;
}

fileDto = new FileDto()
{
Buffer = br.ReadBytes(50_000),
Expand All @@ -178,8 +188,8 @@ await SendToViewer(() => RtcSession.SendDto(fileDto),
};

await SendToViewer(
() => RtcSession.SendDto(fileDto),
() => CasterSocket.SendDtoToViewer(fileDto, ViewerConnectionID));
async () => await RtcSession.SendDto(fileDto),
async () => await CasterSocket.SendDtoToViewer(fileDto, ViewerConnectionID));

progressUpdateCallback((double)fs.Position / fs.Length);
}
Expand All @@ -192,8 +202,8 @@ await SendToViewer(
StartOfFile = false
};

await SendToViewer(() => RtcSession.SendDto(fileDto),
() => CasterSocket.SendDtoToViewer(fileDto, ViewerConnectionID));
await SendToViewer(async () => await RtcSession.SendDto(fileDto),
async () => await CasterSocket.SendDtoToViewer(fileDto, ViewerConnectionID));

progressUpdateCallback(1);
}
Expand All @@ -219,6 +229,8 @@ public async Task SendScreenCapture(CaptureFrame screenFrame)
var width = screenFrame.Width;
var height = screenFrame.Height;

var sw = Stopwatch.StartNew();

for (var i = 0; i < screenFrame.EncodedImageBytes.Length; i += 50_000)
{
var dto = new CaptureFrameDto()
Expand All @@ -231,8 +243,8 @@ public async Task SendScreenCapture(CaptureFrame screenFrame)
ImageBytes = screenFrame.EncodedImageBytes.Skip(i).Take(50_000).ToArray()
};

await SendToViewer(() => RtcSession.SendDto(dto),
() => CasterSocket.SendDtoToViewer(dto, ViewerConnectionID));
await SendToViewer(async () => await RtcSession.SendDto(dto),
async () => await CasterSocket.SendDtoToViewer(dto, ViewerConnectionID));
}

var endOfFrameDto = new CaptureFrameDto()
Expand All @@ -244,8 +256,19 @@ await SendToViewer(() => RtcSession.SendDto(dto),
EndOfFrame = true
};

await SendToViewer(() => RtcSession.SendDto(endOfFrameDto),
() => CasterSocket.SendDtoToViewer(endOfFrameDto, ViewerConnectionID));
await SendToViewer(
async () => await RtcSession.SendDto(endOfFrameDto),
async () => await CasterSocket.SendDtoToViewer(endOfFrameDto, ViewerConnectionID));

sw.Stop();

_bytesSent += screenFrame.EncodedImageBytes.Length;
_timeSpentSending += sw.Elapsed;


AverageBytesPerSecond = _bytesSent / _timeSpentSending.TotalSeconds;

Debug.WriteLine($"Mbps: {AverageBytesPerSecond / 1024 / 1024 * 8}");
}

public async Task SendScreenData(string selectedScreen, string[] displayNames)
Expand Down Expand Up @@ -280,7 +303,7 @@ public void ThrottleIfNeeded()
{
TaskHelper.DelayUntil(() =>
!PendingSentFrames.TryPeek(out var result) || DateTimeOffset.Now - result.Timestamp < TimeSpan.FromSeconds(1),
TimeSpan.MaxValue);
TimeSpan.FromSeconds(10));
}

public void ToggleWebRtcVideo(bool toggleOn)
Expand Down
10 changes: 9 additions & 1 deletion Desktop.Core/Services/WebRtcSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Threading;

namespace Remotely.Desktop.Core.Services
{
Expand Down Expand Up @@ -109,7 +110,14 @@ public async Task Init(IceServerModel[] iceServers)

public Task SendDto<T>(T dto) where T : BaseDto
{
return Task.Run(() => CaptureChannel.SendMessage(MessagePackSerializer.Serialize(dto)));
return Task.Run(() =>
{
CaptureChannel.SendMessage(MessagePackSerializer.Serialize(dto));
while (CurrentBuffer > 64_000)
{
Thread.Sleep(10);
}
});
}

public async Task SetRemoteDescription(string type, string sdp)
Expand Down
Loading

0 comments on commit b6774e5

Please sign in to comment.