Skip to content

Commit

Permalink
#895: add extra verbose logging, and fix websocket close hanging
Browse files Browse the repository at this point in the history
  • Loading branch information
Badgerati committed May 22, 2022
1 parent 4a9573d commit 2e035b1
Show file tree
Hide file tree
Showing 13 changed files with 166 additions and 84 deletions.
28 changes: 14 additions & 14 deletions examples/web-signal-connection.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@ Start-PodeServer -EnablePool WebSockets {
New-PodeLoggingMethod -Terminal | Enable-PodeErrorLogging -Level Error, Debug, Verbose

# connect to web socket from web-signal.ps1
# Connect-PodeWebSocket -Name 'Example' -Url 'ws://localhost:8091' -ScriptBlock {
# $WsEvent.Request | out-default
# if ($WsEvent.Request.Body -inotlike '*Ex:*') {
# Send-PodeWebSocket -Message (@{ message = "Ex: $($WsEvent.Request.Body)" } | ConvertTo-Json -Compress)
Connect-PodeWebSocket -Name 'Example' -Url 'ws://localhost:8091' -ScriptBlock {
$WsEvent.Request | out-default
# if ($WsEvent.Request.Body -inotlike '*Ex:*') {
# Send-PodeWebSocket -Message (@{ message = "Ex: $($WsEvent.Request.Body)" } | ConvertTo-Json -Compress)
# }
}

# Add-PodeRoute -Method Get -Path '/connect' -ScriptBlock {
# Connect-PodeWebSocket -Name 'Test' -Url 'wss://ws.ifelse.io/' -ScriptBlock {
# $WsEvent.Request | out-default
# }
# }

Add-PodeRoute -Method Get -Path '/connect' -ScriptBlock {
Connect-PodeWebSocket -Name 'Test' -Url 'wss://ws.ifelse.io/' -ScriptBlock {
$WsEvent.Request | out-default
}
}

Add-PodeTimer -Name 'Test' -Interval 10 -ScriptBlock {
$rand = Get-Random -Minimum 10 -Maximum 1000
Send-PodeWebSocket -Name 'Test' -Message "hello $rand"
}
# Add-PodeTimer -Name 'Test' -Interval 10 -ScriptBlock {
# $rand = Get-Random -Minimum 10 -Maximum 1000
# Send-PodeWebSocket -Name 'Test' -Message "hello $rand"
# }

# Add-PodeRoute -Method Get -Path '/reset' -ScriptBlock {
# Reset-PodeWebSocket -Name 'Example'
Expand Down
14 changes: 14 additions & 0 deletions pode.build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,24 @@ task Build BuildDeps, {

try {
dotnet build --configuration Release --self-contained --framework netstandard2.0
if (!$?) {
throw "dotnet build failed for netstandard2"
}

dotnet publish --configuration Release --self-contained --framework netstandard2.0 --output ../Libs/netstandard2.0
if (!$?) {
throw "dotnet publish failed for netstandard2"
}

dotnet build --configuration Release --self-contained --framework net6.0
if (!$?) {
throw "dotnet build failed for net6"
}

dotnet publish --configuration Release --self-contained --framework net6.0 --output ../Libs/net6.0
if (!$?) {
throw "dotnet publish failed for net6"
}
}
finally {
Pop-Location
Expand Down
50 changes: 50 additions & 0 deletions src/Listener/PodeConnector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Linq;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Pode
{
public class PodeConnector : IDisposable
{
public bool IsConnected { get; private set; }
public bool IsDisposed { get; private set; }
public bool ErrorLoggingEnabled { get; set; }
public string[] ErrorLoggingLevels { get; set; }
public CancellationToken CancellationToken { get; private set; }

public PodeConnector(CancellationToken cancellationToken = default(CancellationToken))
{
CancellationToken = cancellationToken == default(CancellationToken)
? cancellationToken
: (new CancellationTokenSource()).Token;

// IsConnected = true;
IsDisposed = false;
}

public virtual void Start()
{
IsConnected = true;
}

protected virtual void Close()
{
throw new NotImplementedException();
}

public void Dispose()
{
// stop connecting
IsConnected = false;

// close
Close();

// disposed
IsDisposed = true;
}
}
}
31 changes: 24 additions & 7 deletions src/Listener/PodeHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Reflection;
using System.Runtime.Versioning;

namespace Pode
{
public class PodeHelpers
{

public static readonly string[] HTTP_METHODS = new string[] { "DELETE", "GET", "HEAD", "MERGE", "OPTIONS", "PATCH", "POST", "PUT", "TRACE" };
public const string WEB_SOCKET_MAGIC_KEY = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
public readonly static char[] NEW_LINE_ARRAY = new char[] { '\r', '\n' };
Expand All @@ -19,15 +20,31 @@ public class PodeHelpers
public const byte CARRIAGE_RETURN_BYTE = 13;
public const byte DASH_BYTE = 45;

public static void WriteException(Exception ex, PodeListener listener = default(PodeListener), PodeLoggingLevel level = PodeLoggingLevel.Error)
private static string _dotnet_version = string.Empty;
private static bool _is_net_framework = false;
public static bool IsNetFramework
{
get
{
if (String.IsNullOrWhiteSpace(_dotnet_version))
{
_dotnet_version = Assembly.GetEntryAssembly()?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName ?? "Framework";
_is_net_framework = _dotnet_version.Equals("Framework", StringComparison.InvariantCultureIgnoreCase);
}

return _is_net_framework;
}
}

public static void WriteException(Exception ex, PodeConnector connector = default(PodeConnector), PodeLoggingLevel level = PodeLoggingLevel.Error)
{
if (ex == default(Exception))
{
return;
}

// return if logging disabled, or if level isn't being logged
if (listener != default(PodeListener) && (!listener.ErrorLoggingEnabled || !listener.ErrorLoggingLevels.Contains(level.ToString(), StringComparer.InvariantCultureIgnoreCase)))
if (connector != default(PodeConnector) && (!connector.ErrorLoggingEnabled || !connector.ErrorLoggingLevels.Contains(level.ToString(), StringComparer.InvariantCultureIgnoreCase)))
{
return;
}
Expand All @@ -43,7 +60,7 @@ public class PodeHelpers
}
}

public static void HandleAggregateException(AggregateException aex, PodeListener listener = default(PodeListener), PodeLoggingLevel level = PodeLoggingLevel.Error, bool handled = false)
public static void HandleAggregateException(AggregateException aex, PodeConnector connector = default(PodeConnector), PodeLoggingLevel level = PodeLoggingLevel.Error, bool handled = false)
{
try
{
Expand All @@ -54,7 +71,7 @@ public class PodeHelpers
return true;
}

PodeHelpers.WriteException(ex, listener, level);
PodeHelpers.WriteException(ex, connector, level);
return false;
});
}
Expand All @@ -67,7 +84,7 @@ public class PodeHelpers
}
}

public static void WriteErrorMessage(string message, PodeListener listener = default(PodeListener), PodeLoggingLevel level = PodeLoggingLevel.Error, PodeContext context = default(PodeContext))
public static void WriteErrorMessage(string message, PodeConnector connector = default(PodeConnector), PodeLoggingLevel level = PodeLoggingLevel.Error, PodeContext context = default(PodeContext))
{
// do nothing if no message
if (string.IsNullOrWhiteSpace(message))
Expand All @@ -76,7 +93,7 @@ public class PodeHelpers
}

// return if logging disabled, or if level isn't being logged
if (listener != default(PodeListener) && (!listener.ErrorLoggingEnabled || !listener.ErrorLoggingLevels.Contains(level.ToString(), StringComparer.InvariantCultureIgnoreCase)))
if (connector != default(PodeConnector) && (!connector.ErrorLoggingEnabled || !connector.ErrorLoggingLevels.Contains(level.ToString(), StringComparer.InvariantCultureIgnoreCase)))
{
return;
}
Expand Down
37 changes: 13 additions & 24 deletions src/Listener/PodeListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,11 @@

namespace Pode
{
public class PodeListener : IDisposable
public class PodeListener : PodeConnector
{
public IDictionary<string, PodeSignal> Signals { get; private set; }
public bool IsListening { get; private set; }
public bool IsDisposed { get; private set; }
public bool ErrorLoggingEnabled { get; set; }
public string[] ErrorLoggingLevels { get; set; }
public CancellationToken CancellationToken { get; private set; }

private IList<PodeSocket> Sockets;

public IDictionary<string, PodeSignal> Signals { get; private set; }
public PodeItemQueue<PodeContext> Contexts { get; private set; }
public PodeItemQueue<PodeServerSignal> ServerSignals { get; private set; }
public PodeItemQueue<PodeClientSignal> ClientSignals { get; private set; }
Expand All @@ -43,12 +37,6 @@ public int RequestBodySize

public PodeListener(CancellationToken cancellationToken = default(CancellationToken))
{
CancellationToken = cancellationToken == default(CancellationToken)
? cancellationToken
: (new CancellationTokenSource()).Token;

IsDisposed = false;

Sockets = new List<PodeSocket>();
Signals = new Dictionary<string, PodeSignal>();

Expand Down Expand Up @@ -151,48 +139,49 @@ public void RemoveProcessingClientSignal(PodeClientSignal signal)
ClientSignals.RemoveProcessing(signal);
}

public void Start()
public override void Start()
{
foreach (var socket in Sockets)
{
socket.Listen();
socket.Start();
}

IsListening = true;
base.Start();
}

public void Dispose()
// public void Dispose()
protected override void Close()
{
// stop listening
IsListening = false;

// shutdown the sockets
PodeHelpers.WriteErrorMessage($"Closing sockets", this, PodeLoggingLevel.Verbose);
for (var i = Sockets.Count - 1; i >= 0; i--)
{
Sockets[i].Dispose();
}

Sockets.Clear();
PodeHelpers.WriteErrorMessage($"Closed sockets", this, PodeLoggingLevel.Verbose);

// close existing contexts
PodeHelpers.WriteErrorMessage($"Closing contexts", this, PodeLoggingLevel.Verbose);
foreach (var _context in Contexts.ToArray())
{
_context.Dispose(true);
}

Contexts.Clear();
PodeHelpers.WriteErrorMessage($"Closed contexts", this, PodeLoggingLevel.Verbose);

// close connected signals
foreach (var _signal in Signals.Values)
PodeHelpers.WriteErrorMessage($"Closing signals", this, PodeLoggingLevel.Verbose);
foreach (var _signal in Signals.Values.ToArray())
{
_signal.Context.Dispose(true);
}

Signals.Clear();

// disposed
IsDisposed = true;
PodeHelpers.WriteErrorMessage($"Closed signals", this, PodeLoggingLevel.Verbose);
}
}
}
33 changes: 11 additions & 22 deletions src/Listener/PodeReceiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,18 @@

namespace Pode
{
public class PodeReceiver : IDisposable
public class PodeReceiver : PodeConnector
{
public bool IsReceiving { get; private set; }
public bool IsDisposed { get; private set; }
public bool ErrorLoggingEnabled { get; set; }
public string[] ErrorLoggingLevels { get; set; }
public CancellationToken CancellationToken { get; private set; }

private IDictionary<string, PodeWebSocket> WebSockets;

public PodeItemQueue<PodeWebSocketRequest> Requests { get; private set; }

public PodeReceiver(CancellationToken cancellationToken = default(CancellationToken))
: base(cancellationToken)
{
CancellationToken = cancellationToken == default(CancellationToken)
? cancellationToken
: (new CancellationTokenSource()).Token;

WebSockets = new Dictionary<string, PodeWebSocket>();
Requests = new PodeItemQueue<PodeWebSocketRequest>();

IsReceiving = true;
IsDisposed = false;
Start();
}

public void ConnectWebSocket(string name, string url)
Expand Down Expand Up @@ -95,29 +84,29 @@ public void AddWebSocketRequest(PodeWebSocketRequest request)
return Requests.GetAsync(cancellationToken);
}

public void Dispose()
protected override void Close()
{
// stop receiving
IsReceiving = false;

// disconnect websockets
foreach (var _webSocket in WebSockets.Values)
PodeHelpers.WriteErrorMessage($"Closing client web sockets", this, PodeLoggingLevel.Verbose);

foreach (var _webSocket in WebSockets.Values.ToArray())
{
_webSocket.Dispose();
}

WebSockets.Clear();
PodeHelpers.WriteErrorMessage($"Closed client web sockets", this, PodeLoggingLevel.Verbose);

// close existing websocket requests
PodeHelpers.WriteErrorMessage($"Closing client web sockets requests", this, PodeLoggingLevel.Verbose);

foreach (var _req in Requests.ToArray())
{
_req.Dispose();
}

Requests.Clear();

// disposed
IsDisposed = true;
PodeHelpers.WriteErrorMessage($"Closed client web requests", this, PodeLoggingLevel.Verbose);
}
}
}
4 changes: 2 additions & 2 deletions src/Listener/PodeSocket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ private void ProcessAccept(SocketAsyncEventArgs args)
socket.Start();

// close socket if not successful, or if listener is stopped - close now!
if ((accepted == default(Socket)) || (error != SocketError.Success) || (!Listener.IsListening))
if ((accepted == default(Socket)) || (error != SocketError.Success) || (!Listener.IsConnected))
{
if (error != SocketError.Success)
{
Expand Down Expand Up @@ -202,7 +202,7 @@ private void ProcessReceive(SocketAsyncEventArgs args)
RemovePendingSocket(received);

// close socket if not successful, or if listener is stopped - close now!
if ((received == default(Socket)) || (error != SocketError.Success) || (!Listener.IsListening))
if ((received == default(Socket)) || (error != SocketError.Success) || (!Listener.IsConnected))
{
if (error != SocketError.Success)
{
Expand Down
Loading

0 comments on commit 2e035b1

Please sign in to comment.