Add chunking for images sent over SignalR.

This commit is contained in:
Jared Goodwin 2020-05-27 11:44:20 -07:00
parent c523e9c197
commit 35eff7cd31
6 changed files with 74 additions and 34 deletions

View File

@ -139,9 +139,28 @@ namespace Remotely.ScreenCast.Core.Communication
await Connection.SendAsync("SendRtcOfferToBrowser", sdp, viewerID, iceServers);
}
public async Task SendScreenCapture(byte[] captureBytes, string viewerID, int left, int top, int width, int height, int imageQuality)
public async Task SendScreenCapture(byte[] imageBytes, string viewerID, int left, int top, int width, int height, int imageQuality)
{
await Connection.SendAsync("SendScreenCapture", captureBytes, viewerID, left, top, width, height, imageQuality);
for (var i = 0; i < imageBytes.Length; i += 50_000)
{
await Connection.SendAsync("SendScreenCapture",
imageBytes.Skip(i).Take(50_000).ToArray(),
viewerID,
left,
top,
width,
height,
imageQuality,
false);
}
await Connection.SendAsync("SendScreenCapture", Array.Empty<byte>(),
viewerID,
left,
top,
width,
height,
imageQuality,
true);
}
public async Task SendScreenData(string selectedScreen, string[] displayNames, string viewerID)

View File

@ -203,7 +203,7 @@ namespace Remotely.Server.Services
return Task.CompletedTask;
}
public Task SendScreenCapture(byte[] captureBytes, string rcBrowserHubConnectionID, int left, int top, int width, int height, long imageQuality)
public Task SendScreenCapture(byte[] captureBytes, string rcBrowserHubConnectionID, int left, int top, int width, int height, long imageQuality, bool endOfFrame)
{
if (AppConfig.RecordRemoteControlSessions)
{
@ -211,7 +211,7 @@ namespace Remotely.Server.Services
rcBrowserHubConnectionID, SessionInfo.MachineName, SessionInfo.StartTime);
}
return RCBrowserHubContext.Clients.Client(rcBrowserHubConnectionID).SendAsync("ScreenCapture", captureBytes, left, top, width, height, imageQuality);
return RCBrowserHubContext.Clients.Client(rcBrowserHubConnectionID).SendAsync("ScreenCapture", captureBytes, left, top, width, height, imageQuality, endOfFrame);
}
public Task SendScreenDataToBrowser(string selectedDisplay, string[] displayNames, string browserHubConnectionId)

View File

@ -124,7 +124,7 @@ namespace Remotely.Server
services.AddSignalR(options =>
{
options.EnableDetailedErrors = IsDev;
options.MaximumReceiveMessageSize = 20000000;
options.MaximumReceiveMessageSize = 500_000;
})
.AddJsonProtocol(options =>
{
@ -194,23 +194,23 @@ namespace Remotely.Server
{
routeBuilder.MapHub<BrowserHub>("/BrowserHub", options =>
{
options.ApplicationMaxBufferSize = 500000;
options.TransportMaxBufferSize = 500000;
options.ApplicationMaxBufferSize = 500_000;
options.TransportMaxBufferSize = 500_000;
});
routeBuilder.MapHub<DeviceHub>("/DeviceHub", options =>
{
options.ApplicationMaxBufferSize = 500000;
options.TransportMaxBufferSize = 500000;
options.ApplicationMaxBufferSize = 500_000;
options.TransportMaxBufferSize = 500_000;
});
routeBuilder.MapHub<RCDeviceHub>("/RCDeviceHub", options =>
{
options.ApplicationMaxBufferSize = 2000000;
options.TransportMaxBufferSize = 2000000;
options.ApplicationMaxBufferSize = 100_000;
options.TransportMaxBufferSize = 100_000;
});
routeBuilder.MapHub<RCBrowserHub>("/RCBrowserHub", options =>
{
options.ApplicationMaxBufferSize = 2000000;
options.TransportMaxBufferSize = 2000000;
options.ApplicationMaxBufferSize = 100_000;
options.TransportMaxBufferSize = 100_000;
});
routeBuilder.MapRazorPages();

View File

@ -5,6 +5,9 @@ import { ShowMessage } from "../UI.js";
import { RemoteControlMode } from "../Enums/RemoteControlMode.js";
var signalR = window["signalR"];
export class RCHubConnection {
constructor() {
this.PartialCaptureFrames = [];
}
Connect() {
this.Connection = new signalR.HubConnectionBuilder()
.withUrl("/RCBrowserHub")
@ -138,19 +141,24 @@ export class RCHubConnection {
hubConnection.on("ScreenSize", (width, height) => {
UI.SetScreenSize(width, height);
});
hubConnection.on("ScreenCapture", (buffer, left, top, width, height, imageQuality) => {
hubConnection.on("ScreenCapture", (buffer, left, top, width, height, imageQuality, endOfFrame) => {
this.SendFrameReceived(buffer.byteLength);
if (UI.AutoQualityAdjustCheckBox.checked &&
Number(UI.QualitySlider.value) != imageQuality) {
if (UI.AutoQualityAdjustCheckBox.checked && Number(UI.QualitySlider.value) != imageQuality) {
UI.QualitySlider.value = String(imageQuality);
}
var url = window.URL.createObjectURL(new Blob([buffer]));
var img = document.createElement("img");
img.onload = () => {
UI.Screen2DContext.drawImage(img, left, top, width, height);
window.URL.revokeObjectURL(url);
};
img.src = url;
if (endOfFrame) {
var url = window.URL.createObjectURL(new Blob(this.PartialCaptureFrames));
var img = document.createElement("img");
img.onload = () => {
UI.Screen2DContext.drawImage(img, left, top, width, height);
window.URL.revokeObjectURL(url);
};
img.src = url;
this.PartialCaptureFrames = [];
}
else {
this.PartialCaptureFrames.push(buffer);
}
});
hubConnection.on("AudioSample", (buffer) => {
Sound.Play(buffer);

File diff suppressed because one or more lines are too long

View File

@ -19,6 +19,7 @@ type HubConnection = {
export class RCHubConnection {
Connection: HubConnection;
PartialCaptureFrames: Uint8Array[] = [];
Connect() {
this.Connection = new signalR.HubConnectionBuilder()
.withUrl("/RCBrowserHub")
@ -157,21 +158,33 @@ export class RCHubConnection {
hubConnection.on("ScreenSize", (width: number, height: number) => {
UI.SetScreenSize(width, height);
});
hubConnection.on("ScreenCapture", (buffer: Uint8Array, left:number, top:number, width:number, height:number, imageQuality: number) => {
hubConnection.on("ScreenCapture", (buffer: Uint8Array,
left: number,
top: number,
width: number,
height: number,
imageQuality: number,
endOfFrame: boolean) => {
this.SendFrameReceived(buffer.byteLength);
if (UI.AutoQualityAdjustCheckBox.checked &&
Number(UI.QualitySlider.value) != imageQuality) {
if (UI.AutoQualityAdjustCheckBox.checked && Number(UI.QualitySlider.value) != imageQuality) {
UI.QualitySlider.value = String(imageQuality);
}
var url = window.URL.createObjectURL(new Blob([buffer]));
var img = document.createElement("img");
img.onload = () => {
UI.Screen2DContext.drawImage(img, left, top, width, height);
window.URL.revokeObjectURL(url);
};
img.src = url;
if (endOfFrame) {
var url = window.URL.createObjectURL(new Blob(this.PartialCaptureFrames));
var img = document.createElement("img");
img.onload = () => {
UI.Screen2DContext.drawImage(img, left, top, width, height);
window.URL.revokeObjectURL(url);
};
img.src = url;
this.PartialCaptureFrames = [];
}
else {
this.PartialCaptureFrames.push(buffer);
}
});
hubConnection.on("AudioSample", (buffer: Uint8Array) => {
Sound.Play(buffer);