Skip to content
Closed
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
16 changes: 16 additions & 0 deletions src/PepperDash.Core/Logging/DebugWebsocketSink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ public string Url
/// </summary>
public bool IsRunning { get => _httpsServer?.IsListening ?? false; }

/// <summary>
/// Gets a value indicating whether there are active WebSocket connections.
/// </summary>
public bool HasActiveConnections
{
get
{
if (_httpsServer == null || !_httpsServer.IsListening) return false;
var service = _httpsServer.WebSocketServices[_path];
if (service == null) return false;
return service.Sessions.Count > 0;
}
}


private readonly ITextFormatter _textFormatter;

Expand Down Expand Up @@ -217,6 +231,8 @@ public void StartServerAndSetPort(int port)
{
Debug.LogInformation("Starting Websocket Server on port: {0}", port);




Start(port, CertPath, _certificatePassword);
Comment on lines 232 to 237
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers
/// Represents a DebugSessionRequestHandler
/// </summary>
public class DebugSessionRequestHandler : WebApiBaseRequestHandler
{
{
private CTimer _portForwardTimeoutTimer;
private readonly object _timerLock = new object();

/// <summary>
/// Constructor
/// </summary>
Expand Down Expand Up @@ -48,6 +51,7 @@ protected override void HandleGet(Crestron.SimplSharp.WebScripting.HttpCwsContex
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);

var port = 0;
string csIp = null;
Comment on lines 53 to +54

if (!Debug.WebsocketSink.IsRunning)
{
Expand All @@ -57,15 +61,18 @@ protected override void HandleGet(Crestron.SimplSharp.WebScripting.HttpCwsContex
// Start the WS Server
Debug.WebsocketSink.StartServerAndSetPort(port);
Debug.SetWebSocketMinimumDebugLevel(Serilog.Events.LogEventLevel.Verbose);
}

// Attempt to forward the port to the CS LAN
try
{
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(
EthernetAdapterType.EthernetCSAdapter);
var csIp = CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);
// Attempt to get the CS LAN IP and forward the port
try
{
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(
EthernetAdapterType.EthernetCSAdapter);
csIp = CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);

if (port > 0)
{
Comment on lines +71 to +75
var result = CrestronEthernetHelper.AddPortForwarding(
(ushort)port, (ushort)port, csIp,
CrestronEthernetHelper.ePortMapTransport.TCP);
Expand All @@ -77,26 +84,29 @@ protected override void HandleGet(Crestron.SimplSharp.WebScripting.HttpCwsContex
else
{
Debug.LogMessage(LogEventLevel.Information, "Port {0} forwarded to CS LAN for debug websocket", port);
StartPortForwardTimeout(port, csIp);
}
}
catch (ArgumentException)
{
Debug.LogMessage(LogEventLevel.Debug, "This processor does not have a CS LAN adapter; skipping port forwarding");
}
catch (Exception ex)
{
Debug.LogMessage(LogEventLevel.Warning, "Error automatically forwarding debug websocket port to CS LAN: {0}", ex.Message);
}
}
catch (ArgumentException)
{
Debug.LogMessage(LogEventLevel.Debug, "This processor does not have a CS LAN adapter; skipping port forwarding");
}
catch (Exception ex)
{
Debug.LogMessage(LogEventLevel.Warning, "Error automatically forwarding debug websocket port to CS LAN: {0}", ex.Message);
}

var url = Debug.WebsocketSink.Url;

object data = new
var data = new
{
url = Debug.WebsocketSink.Url
url = Debug.WebsocketSink.Url,
fallbackUrl = csIp != null ? url.Replace(csIp, ip) : null
};

Debug.LogMessage(LogEventLevel.Information, "Debug Session URL: {0}", url);
Debug.LogMessage(LogEventLevel.Information, "Fallback Debug Session URL: {0}", data.fallbackUrl);

// Return the port number with the full url of the WS Server
var res = JsonConvert.SerializeObject(data);
Expand All @@ -120,6 +130,8 @@ protected override void HandleGet(Crestron.SimplSharp.WebScripting.HttpCwsContex
/// <param name="context"></param>
protected override void HandlePost(HttpCwsContext context)
{
CancelPortForwardTimeout();

var port = Debug.WebsocketSink.Port;

Debug.WebsocketSink.StopServer();
Expand Down Expand Up @@ -168,5 +180,55 @@ protected override void HandlePost(HttpCwsContext context)
Debug.LogMessage(LogEventLevel.Information, "Websocket Debug Session Stopped");
}

private void StartPortForwardTimeout(int port, string csIp)
{
lock (_timerLock)
{
_portForwardTimeoutTimer?.Dispose();
_portForwardTimeoutTimer = new CTimer(_ =>
{
if (Debug.WebsocketSink.HasActiveConnections)
{
Debug.LogMessage(LogEventLevel.Debug, "Debug websocket has active connections; keeping port forward");
return;
}

Debug.LogMessage(LogEventLevel.Information, "No debug websocket connection within 30 seconds; removing port forward for port {0}", port);

try
{
var result = CrestronEthernetHelper.RemovePortForwarding(
(ushort)port, (ushort)port, csIp,
CrestronEthernetHelper.ePortMapTransport.TCP);

if (result != CrestronEthernetHelper.PortForwardingUserPatRetCodes.NoErr)
{
Debug.LogMessage(LogEventLevel.Warning, "Error removing port forwarding on timeout: {0}", result);
}
else
{
Debug.LogMessage(LogEventLevel.Information, "Port forwarding for port {0} removed due to timeout", port);
}
}
catch (Exception ex)
{
Debug.LogMessage(LogEventLevel.Warning, "Error removing port forwarding on timeout: {0}", ex.Message);
}
}, 30000);
}
}

/// <summary>
/// Cancels the port forward timeout timer if a session is being explicitly stopped.
/// </summary>
private void CancelPortForwardTimeout()
{
lock (_timerLock)
{
_portForwardTimeoutTimer?.Dispose();
_portForwardTimeoutTimer = null;
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ protected void PostStatusMessage(DeviceStateMessageBase message, string clientId

message.Name = _device.Name;

message.MessageBasePath = MessagePath;


var token = JToken.FromObject(message);
Comment on lines +267 to 270

PostStatusMessage(token, MessagePath, clientId);
Expand Down
Loading