diff --git a/BTCPayServer/WebsocketExtensions.cs b/BTCPayServer/WebsocketExtensions.cs new file mode 100644 index 000000000..849fe4d2b --- /dev/null +++ b/BTCPayServer/WebsocketExtensions.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace BTCPayServer +{ + public static class WebsocketExtensions + { + /// + /// NGINX closes websocket connections after 1 min if there is no activity, so here we do some busy work every 30s + /// + /// + public static async Task ReceiveAndPingAsync(this WebSocket webSocket, ArraySegment buffer, CancellationToken cancellationToken = default) + { + var waiting = Task.Delay(TimeSpan.FromSeconds(30), cancellationToken); + var receiving = webSocket.ReceiveAsync(buffer, cancellationToken); +wait: + var completed = await Task.WhenAny(waiting, receiving); + if (completed == waiting) + { + await webSocket.SendAsync(Encoding.UTF8.GetBytes("ping"), WebSocketMessageType.Text, true, cancellationToken); + waiting = Task.Delay(TimeSpan.FromSeconds(30), cancellationToken); + goto wait; + } + return receiving.Result; + } + } +}