feat: enhance WebSocket services with HTTP GET handler for certificate confirmation and increase timeout for port forwarding

This commit is contained in:
Neil Dorin 2026-06-23 16:08:42 -06:00
parent a18f7800d1
commit a732c5e08e
6 changed files with 53 additions and 5 deletions

View file

@ -262,6 +262,7 @@ public class DebugWebsocketSink : ILogEventSink, IKeyed
} }
Debug.LogInformation("Adding Debug Client Service"); Debug.LogInformation("Adding Debug Client Service");
_httpsServer.AddWebSocketService<DebugClient>(_path); _httpsServer.AddWebSocketService<DebugClient>(_path);
_httpsServer.OnGet += HandleHttpGet;
Debug.LogInformation("Assigning Log Info"); Debug.LogInformation("Assigning Log Info");
_httpsServer.Log.Level = LogLevel.Trace; _httpsServer.Log.Level = LogLevel.Trace;
_httpsServer.Log.Output = WriteWebSocketInternalLog; _httpsServer.Log.Output = WriteWebSocketInternalLog;
@ -279,6 +280,16 @@ public class DebugWebsocketSink : ILogEventSink, IKeyed
} }
} }
private void HandleHttpGet(object sender, HttpRequestEventArgs e)
{
var res = e.Response;
var body = System.Text.Encoding.UTF8.GetBytes(
"<html><body><h2>Certificate accepted.</h2><p>You can close this tab and return to the application.</p></body></html>");
res.ContentType = "text/html";
res.ContentLength64 = body.Length;
res.Close(body, true);
}
/// <summary> /// <summary>
/// Stops the WebSocket server if it is currently running. /// Stops the WebSocket server if it is currently running.
/// </summary> /// </summary>

View file

@ -196,7 +196,7 @@ public class DebugSessionRequestHandler : WebApiBaseRequestHandler
return; return;
} }
Debug.LogMessage(LogEventLevel.Information, "No debug websocket connection within 30 seconds; removing port forward for port {0}", port); Debug.LogMessage(LogEventLevel.Information, "No debug websocket connection within timeout; removing port forward for port {0}", port);
try try
{ {
@ -217,7 +217,7 @@ public class DebugSessionRequestHandler : WebApiBaseRequestHandler
{ {
Debug.LogMessage(LogEventLevel.Warning, "Error removing port forwarding on timeout: {0}", ex.Message); Debug.LogMessage(LogEventLevel.Warning, "Error removing port forwarding on timeout: {0}", ex.Message);
} }
}, 30000); }, 120000);
} }
} }

View file

@ -210,7 +210,7 @@ public class RoutingFeedbackSessionRequestHandler : WebApiBaseRequestHandler
{ {
Debug.LogMessage(LogEventLevel.Warning, "Error removing port forwarding on timeout: {0}", ex.Message); Debug.LogMessage(LogEventLevel.Warning, "Error removing port forwarding on timeout: {0}", ex.Message);
} }
}, 30000); }, 120000);
} }
} }

View file

@ -113,6 +113,7 @@ public class RoutingFeedbackWebsocket : IKeyed
_httpsServer.SslConfiguration.ClientCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; _httpsServer.SslConfiguration.ClientCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
_httpsServer.AddWebSocketService<RoutingFeedbackClient>(_path); _httpsServer.AddWebSocketService<RoutingFeedbackClient>(_path);
_httpsServer.OnGet += HandleHttpGet;
_httpsServer.Log.Level = LogLevel.Warn; _httpsServer.Log.Level = LogLevel.Warn;
_httpsServer.Start(); _httpsServer.Start();
@ -338,6 +339,16 @@ public class RoutingFeedbackWebsocket : IKeyed
service.Sessions.Broadcast(message); service.Sessions.Broadcast(message);
} }
private void HandleHttpGet(object sender, HttpRequestEventArgs e)
{
var res = e.Response;
var body = System.Text.Encoding.UTF8.GetBytes(
"<html><body><h2>Certificate accepted.</h2><p>You can close this tab and return to the application.</p></body></html>");
res.ContentType = "text/html";
res.ContentLength64 = body.Length;
res.Close(body, true);
}
private static X509Certificate2 LoadCert(string certPath, string certPassword) private static X509Certificate2 LoadCert(string certPath, string certPassword)
{ {
return new X509Certificate2(certPath, certPassword, X509KeyStorageFlags.EphemeralKeySet); return new X509Certificate2(certPath, certPassword, X509KeyStorageFlags.EphemeralKeySet);

View file

@ -21,7 +21,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
/// <summary> /// <summary>
/// Represents a MockVC /// Represents a MockVC
/// </summary> /// </summary>
public class MockVC : VideoCodecBase, IRoutingSource, IHasCallHistory, IHasScheduleAwareness, IHasCallFavorites, IHasDirectory, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets public class MockVC : VideoCodecBase, IHasCallHistory, IHasScheduleAwareness, IHasCallFavorites, IHasDirectory, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, IRoutingSinkWithFeedback
{ {
/// <summary> /// <summary>
/// Gets or sets the PropertiesConfig /// Gets or sets the PropertiesConfig
@ -858,6 +858,32 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
#endregion #endregion
#region IRoutingSinkWithFeedback Members
public RoutingInputPort CurrentInputPort { get; private set; }
public event InputChangedEventHandler InputChanged;
#endregion
#region ICurrentSources Members
public Dictionary<eRoutingSignalType, IRoutingSource> CurrentSources { get; private set; } = new Dictionary<eRoutingSignalType, IRoutingSource>();
public Dictionary<eRoutingSignalType, string> CurrentSourceKeys { get; private set; } = new Dictionary<eRoutingSignalType, string>();
public event EventHandler<CurrentSourcesChangedEventArgs> CurrentSourcesChanged;
public void SetCurrentSource(eRoutingSignalType signalType, IRoutingSource sourceDevice)
{
CurrentSources.TryGetValue(signalType, out var previousSource);
CurrentSources[signalType] = sourceDevice;
CurrentSourceKeys[signalType] = sourceDevice?.Key;
CurrentSourcesChanged?.Invoke(this, new CurrentSourcesChangedEventArgs(signalType, previousSource, sourceDevice));
}
#endregion
/// <inheritdoc /> /// <inheritdoc />
protected override void CustomSetConfig(DeviceConfig config) protected override void CustomSetConfig(DeviceConfig config)
{ {

View file

@ -27,7 +27,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec;
/// Base class for video codecs. Contains common properties, methods, and feedback for video codecs. /// Base class for video codecs. Contains common properties, methods, and feedback for video codecs.
/// Also contains the logic to link commonly implemented interfaces to the API bridge. /// Also contains the logic to link commonly implemented interfaces to the API bridge.
/// </summary> /// </summary>
public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingMidpoint, public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingSource,
IUsageTracking, ICodecCallControls, IHasContentSharing, ICodecAudio, IVideoCodecInfo, IBridgeAdvanced, IHasStandbyMode, IHasReady IUsageTracking, ICodecCallControls, IHasContentSharing, ICodecAudio, IVideoCodecInfo, IBridgeAdvanced, IHasStandbyMode, IHasReady
{ {
private const int XSigEncoding = 28591; private const int XSigEncoding = 28591;