Add configurable IceServers and concurrent update count.

This commit is contained in:
Jared Goodwin 2020-04-28 21:05:59 -07:00
parent 8cf4cf91f9
commit a4e17d19c5
19 changed files with 126 additions and 52 deletions

View File

@ -67,11 +67,15 @@ namespace Remotely.ScreenCast.Core.Communication
await Connection.DisposeAsync();
}
public async Task<IceServerModel[]> GetIceServers()
{
return await Connection.InvokeAsync<IceServerModel[]>("GetIceServers");
}
public async Task GetSessionID()
{
await Connection.SendAsync("GetSessionID");
}
public async Task NotifyRequesterUnattendedReady(string requesterID)
{
await Connection.SendAsync("NotifyRequesterUnattendedReady", requesterID);
@ -127,9 +131,9 @@ namespace Remotely.ScreenCast.Core.Communication
await Connection.SendAsync("SendMachineName", machineName, viewerID);
}
public async Task SendRtcOfferToBrowser(string sdp, string viewerID)
public async Task SendRtcOfferToBrowser(string sdp, string viewerID, IceServerModel[] iceServers)
{
await Connection.SendAsync("SendRtcOfferToBrowser", sdp, viewerID);
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)

View File

@ -26,6 +26,7 @@ namespace Remotely.ScreenCast.Core.Communication
public bool IsPeerConnected => PeerConnection?.IsConnected == true;
private DataChannel CaptureChannel { get; set; }
private PeerConnection PeerConnection { get; set; }
private IceServerModel[] IceServers { get; set; }
private IRtcMessageHandler RtcMessageHandler { get; }
public void AddIceCandidate(string sdpMid, int sdpMlineIndex, string candidate)
{
@ -38,18 +39,24 @@ namespace Remotely.ScreenCast.Core.Communication
PeerConnection?.Dispose();
}
public async Task Init()
public async Task Init(IceServerModel[] iceServers)
{
Logger.Debug("Starting WebRTC connection.");
IceServers = iceServers;
PeerConnection = new PeerConnection();
var iceList = IceServers.Select(x => new IceServer()
{
Urls = { x.Url },
TurnPassword = x.TurnPassword ?? string.Empty,
TurnUserName = x.TurnUsername ?? string.Empty
}).ToList();
var config = new PeerConnectionConfiguration()
{
IceServers = new List<IceServer>
{
new IceServer{ Urls = { "stun:stun.l.google.com:19302" } },
new IceServer{ Urls = { "stun:stun4.l.google.com:19302" } }
}
IceServers = iceList
};
await PeerConnection.InitializeAsync(config);
@ -139,7 +146,7 @@ namespace Remotely.ScreenCast.Core.Communication
Logger.Debug($"DataChannel state changed. New State: {CaptureChannel.State}");
if (CaptureChannel.State == DataChannel.ChannelState.Closed)
{
await Init();
await Init(IceServers);
}
}
private void DataChannel_BufferingChanged(ulong previous, ulong current, ulong limit)

View File

@ -34,11 +34,8 @@ namespace Remotely.ScreenCast.Core.Models
public IScreenCapturer Capturer { get; }
public bool DisconnectRequested { get; set; }
public EncoderParameters EncoderParams { get; private set; }
public bool HasControl { get; set; } = true;
public int ImageQuality
{
get
@ -81,16 +78,19 @@ namespace Remotely.ScreenCast.Core.Models
{
try
{
var iceServers = await CasterSocket.GetIceServers();
RtcSession = WebRtcSessionFactory.GetNewSession(this);
RtcSession.LocalSdpReady += async (sender, sdp) =>
{
await CasterSocket.SendRtcOfferToBrowser(sdp, ViewerConnectionID);
await CasterSocket.SendRtcOfferToBrowser(sdp, ViewerConnectionID, iceServers);
};
RtcSession.IceCandidateReady += async (sender, args) =>
{
await CasterSocket.SendIceCandidateToBrowser(args.candidate, args.sdpMlineIndex, args.sdpMid, ViewerConnectionID);
};
await RtcSession.Init();
await RtcSession.Init(iceServers);
}
catch (Exception ex)
{

View File

@ -19,7 +19,8 @@ namespace Remotely.ScreenCast.Core.Services
{
public class ScreenCaster : IScreenCaster
{
public ScreenCaster(Conductor conductor, ICursorIconWatcher cursorIconWatcher)
public ScreenCaster(Conductor conductor,
ICursorIconWatcher cursorIconWatcher)
{
Conductor = conductor;
CursorIconWatcher = cursorIconWatcher;

View File

@ -16,13 +16,17 @@ namespace Remotely.Server.API
private static readonly MemoryCache downloadingAgents = new MemoryCache(new MemoryCacheOptions());
public AgentUpdateController(IWebHostEnvironment hostingEnv, DataService dataService)
public AgentUpdateController(IWebHostEnvironment hostingEnv,
DataService dataService,
ApplicationConfig appConfig)
{
this.HostEnv = hostingEnv;
HostEnv = hostingEnv;
DataService = dataService;
AppConfig = appConfig;
}
private DataService DataService { get; }
public ApplicationConfig AppConfig { get; }
private IWebHostEnvironment HostEnv { get; }
@ -50,10 +54,13 @@ namespace Remotely.Server.API
{
try
{
while (downloadingAgents.Count > 10)
var startWait = DateTimeOffset.Now;
while (downloadingAgents.Count > AppConfig.MaxConcurrentUpdates)
{
await Task.Delay(new Random().Next(100, 10000));
}
var waitTime = DateTimeOffset.Now - startWait;
DataService.WriteEvent($"Download started after wait time of {waitTime}.", Shared.Models.EventType.Debug, string.Empty);
downloadingAgents.Set(downloadId, string.Empty, TimeSpan.FromMinutes(10));

View File

@ -47,6 +47,7 @@
<Content Remove="wwwroot\scripts\Models\Device.ts" />
<Content Remove="wwwroot\scripts\Models\DynamicDtoType.ts" />
<Content Remove="wwwroot\scripts\Models\GenericCommandResult.ts" />
<Content Remove="wwwroot\scripts\Models\IceServerModel.ts" />
<Content Remove="wwwroot\scripts\Models\Parameter.ts" />
<Content Remove="wwwroot\scripts\Models\Point.ts" />
<Content Remove="wwwroot\scripts\RemoteControl\MessageSender.ts" />
@ -157,6 +158,7 @@
<TypeScriptCompile Include="wwwroot\scripts\Models\CommandLineParameter.ts" />
<TypeScriptCompile Include="wwwroot\scripts\Models\ConsoleCommand.ts" />
<TypeScriptCompile Include="wwwroot\scripts\Enums\DynamicDtoType.ts" />
<TypeScriptCompile Include="wwwroot\scripts\Models\IceServerModel.ts" />
<TypeScriptCompile Include="wwwroot\scripts\RemoteControl\MessageSender.ts" />
<TypeScriptCompile Include="wwwroot\scripts\Models\Point.ts" />
<TypeScriptCompile Include="wwwroot\scripts\Models\UserOptions.ts" />

View File

@ -1,36 +1,46 @@
using Microsoft.Extensions.Configuration;
using Remotely.Shared.Models;
namespace Remotely.Server.Services
{
public class ApplicationConfig
{
private IceServerModel[] fallbackIceServers = new IceServerModel[]
{
new IceServerModel() { Url = "stun: stun.l.google.com:19302"},
new IceServerModel() { Url = "stun: stun4.l.google.com:19302"}
};
public ApplicationConfig(IConfiguration config)
{
Config = config;
}
public bool AllowApiLogin => bool.Parse(Config["ApplicationOptions:AllowApiLogin"]);
public double DataRetentionInDays => double.Parse(Config["ApplicationOptions:DataRetentionInDays"]);
public string DBProvider => Config["ApplicationOptions:DBProvider"];
public string DefaultPrompt => Config["ApplicationOptions:DefaultPrompt"];
public bool AllowApiLogin => bool.Parse(Config["ApplicationOptions:AllowApiLogin"] ?? "false");
public double DataRetentionInDays => double.Parse(Config["ApplicationOptions:DataRetentionInDays"] ?? "30");
public string DBProvider => Config["ApplicationOptions:DBProvider"] ?? "SQLite";
public string DefaultPrompt => Config["ApplicationOptions:DefaultPrompt"] ?? "~>";
public bool EnableWindowsEventLog => bool.Parse(Config["ApplicationOptions:EnableWindowsEventLog"]);
public IceServerModel[] IceServers => Config.GetSection("ApplicationOptions:IceServers").Get<IceServerModel[]>() ?? fallbackIceServers;
public string[] KnownProxies => Config.GetSection("ApplicationOptions:KnownProxies").Get<string[]>();
public int MaxOrganizationCount => int.Parse(Config["ApplicationOptions:MaxOrganizationCount"]);
public bool RecordRemoteControlSessions => bool.Parse(Config["ApplicationOptions:RecordRemoteControlSessions"]);
public bool RedirectToHttps => bool.Parse(Config["ApplicationOptions:RedirectToHttps"]);
public bool RemoteControlRequiresAuthentication => bool.Parse(Config["ApplicationOptions:RemoteControlRequiresAuthentication"]);
public double RemoteControlSessionLimit => double.Parse(Config["ApplicationOptions:RemoteControlSessionLimit"]);
public bool Require2FA => bool.Parse(Config["ApplicationOptions:Require2FA"]);
public int MaxConcurrentUpdates => int.Parse(Config["ApplicationOptions:MaxConcurrentUpdates"] ?? "10");
public int MaxOrganizationCount => int.Parse(Config["ApplicationOptions:MaxOrganizationCount"] ?? "1");
public bool RecordRemoteControlSessions => bool.Parse(Config["ApplicationOptions:RecordRemoteControlSessions"] ?? "false");
public bool RedirectToHttps => bool.Parse(Config["ApplicationOptions:RedirectToHttps"] ?? "false");
public bool RemoteControlRequiresAuthentication => bool.Parse(Config["ApplicationOptions:RemoteControlRequiresAuthentication"] ?? "true");
public double RemoteControlSessionLimit => double.Parse(Config["ApplicationOptions:RemoteControlSessionLimit"] ?? "3");
public bool Require2FA => bool.Parse(Config["ApplicationOptions:Require2FA"] ?? "false");
public string SmtpDisplayName => Config["ApplicationOptions:SmtpDisplayName"];
public string SmtpEmail => Config["ApplicationOptions:SmtpEmail"];
public bool SmtpEnableSsl => bool.Parse(Config["ApplicationOptions:SmtpEnableSsl"]);
public bool SmtpEnableSsl => bool.Parse(Config["ApplicationOptions:SmtpEnableSsl"] ?? "true");
public string SmtpHost => Config["ApplicationOptions:SmtpHost"];
public string SmtpPassword => Config["ApplicationOptions:SmtpPassword"];
public int SmtpPort => int.Parse(Config["ApplicationOptions:SmtpPort"]);
public string SmtpUserName => Config["ApplicationOptions:SmtpUserName"];
public string Theme => Config["ApplicationOptions:Theme"];
public string[] TrustedCorsOrigins => Config.GetSection("ApplicationOptions:TrustedCorsOrigins").Get<string[]>();
public bool UseHsts => bool.Parse(Config["ApplicationOptions:UseHsts"]);
public bool UseWebRtc => bool.Parse(Config["ApplicationOptions:UseWebRtc"]);
public bool UseHsts => bool.Parse(Config["ApplicationOptions:UseHsts"] ?? "false");
public bool UseWebRtc => bool.Parse(Config["ApplicationOptions:UseWebRtc"] ?? "true");
private IConfiguration Config { get; set; }
}
}

View File

@ -84,6 +84,11 @@ namespace Remotely.Server.Services
{
return DeviceHubContext.Clients.Client(SessionInfo.ServiceID).SendAsync("CtrlAltDel");
}
public IceServerModel[] GetIceServers()
{
return AppConfig.IceServers;
}
public Task GetSessionID()
{
var random = new Random();
@ -186,11 +191,11 @@ namespace Remotely.Server.Services
return RCBrowserHubContext.Clients.Client(viewerID).SendAsync("ReceiveMachineName", machineName);
}
public Task SendRtcOfferToBrowser(string sdp, string viewerID)
public Task SendRtcOfferToBrowser(string sdp, string viewerID, IceServerModel[] iceServers)
{
if (AppConfig.UseWebRtc)
{
return RCBrowserHubContext.Clients.Client(viewerID).SendAsync("ReceiveRtcOffer", sdp);
return RCBrowserHubContext.Clients.Client(viewerID).SendAsync("ReceiveRtcOffer", sdp, iceServers);
}
return Task.CompletedTask;

View File

@ -11,15 +11,20 @@
},
"ApplicationOptions": {
"AllowApiLogin": false,
"MaxOrganizationCount": 1,
"DataRetentionInDays": 90,
"DBProvider": "SQLite",
"DefaultPrompt": "~>",
"EnableWindowsEventLog": false,
"IceServers": [
{ "Url": "stun: stun.l.google.com:19302" },
{ "Url": "stun: stun4.l.google.com:19302" }
],
"KnownProxies": [],
"MaxConcurrentUpdates": 10,
"MaxOrganizationCount": 1,
"RecordRemoteControlSessions": false,
"RedirectToHttps": false,
"RemoteControlSessionLimit": 1,
"RemoteControlSessionLimit": 3,
"RemoteControlRequiresAuthentication": true,
"Require2FA": false,
"SmtpHost": "",

View File

@ -0,0 +1,3 @@
export class IceServerModel {
}
//# sourceMappingURL=IceServerModel.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"IceServerModel.js","sourceRoot":"","sources":["IceServerModel.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,cAAc;CAI1B"}

View File

@ -0,0 +1,5 @@
export class IceServerModel {
Url: string;
TurnPassword: string;
TurnUsername: string;
}

View File

@ -191,9 +191,9 @@ export class RCHubConnection {
hubConnection.on("RequestingScreenCast", () => {
UI.ShowMessage("Requesting remote control...");
});
hubConnection.on("ReceiveRtcOffer", async (sdp) => {
hubConnection.on("ReceiveRtcOffer", async (sdp, iceServers) => {
console.log("Rtc offer SDP received.");
MainRc.RtcSession.Init();
MainRc.RtcSession.Init(iceServers);
await MainRc.RtcSession.ReceiveRtcOffer(sdp);
});
hubConnection.on("ReceiveIceCandidate", (candidate, sdpMlineIndex, sdpMid) => {

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,7 @@ import { MainRc } from "./Main.js";
import { CursorInfo } from "../Models/CursorInfo.js";
import { Sound } from "../Sound.js";
import { ShowMessage } from "../UI.js";
import { IceServerModel } from "../Models/IceServerModel.js";
var signalR = window["signalR"];
@ -215,9 +216,9 @@ export class RCHubConnection {
});
hubConnection.on("ReceiveRtcOffer", async (sdp: string) => {
hubConnection.on("ReceiveRtcOffer", async (sdp: string, iceServers: IceServerModel[]) => {
console.log("Rtc offer SDP received.");
MainRc.RtcSession.Init();
MainRc.RtcSession.Init(iceServers);
await MainRc.RtcSession.ReceiveRtcOffer(sdp);
});

View File

@ -5,12 +5,16 @@ export class RtcSession {
constructor() {
this.MessagePack = window['MessagePack'];
}
Init() {
Init(iceServers) {
this.PeerConnection = new RTCPeerConnection({
iceServers: [
{ urls: "stun: stun.l.google.com:19302" },
{ urls: "stun:stun4.l.google.com:19302" }
]
iceServers: iceServers.map(x => {
return {
urls: x.Url,
username: x.TurnUsername,
credential: x.TurnPassword,
credentialType: "password"
};
})
});
this.PeerConnection.ondatachannel = (ev) => {
console.log("Data channel received.");

View File

@ -1 +1 @@
{"version":3,"file":"RtcSession.js","sourceRoot":"","sources":["RtcSession.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"RtcSession.js","sourceRoot":"","sources":["RtcSession.ts"],"names":[],"mappings":"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"}

View File

@ -1,17 +1,23 @@
import * as UI from "./UI.js";
import * as Utilities from "../Utilities.js";
import { MainRc } from "./Main.js";
import { IceServerModel } from "../Models/IceServerModel.js";
export class RtcSession {
PeerConnection: RTCPeerConnection;
DataChannel: RTCDataChannel;
MessagePack: any = window['MessagePack'];
Init() {
Init(iceServers: IceServerModel[]) {
this.PeerConnection = new RTCPeerConnection({
iceServers: [
{ urls: "stun: stun.l.google.com:19302" },
{ urls: "stun:stun4.l.google.com:19302" }
]
iceServers: iceServers.map(x => {
return {
urls: x.Url,
username: x.TurnUsername,
credential: x.TurnPassword,
credentialType: "password"
}
})
});
this.PeerConnection.ondatachannel = (ev) => {

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Remotely.Shared.Models
{
public class IceServerModel
{
public string Url { get; set; }
public string TurnPassword { get; set; }
public string TurnUsername { get; set; }
}
}