public async Task IoMetricsLive() { using (var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync()) { var receiveBuffer = new ArraySegment <byte>(new byte[1024]); var receive = webSocket.ReceiveAsync(receiveBuffer, Database.DatabaseShutdown); using (var ms = new MemoryStream()) using (var collector = new LiveIOStatsCollector(Database)) { // 1. Send data to webSocket without making UI wait upon opening webSocket await SendDataOrHeartbeatToWebSocket(receive, webSocket, collector, ms, 100); // 2. Send data to webSocket when available while (Database.DatabaseShutdown.IsCancellationRequested == false) { if (await SendDataOrHeartbeatToWebSocket(receive, webSocket, collector, ms, 4000) == false) { break; } } } } }
private async Task <bool> SendDataOrHeartbeatToWebSocket(Task <WebSocketReceiveResult> receive, WebSocket webSocket, LiveIOStatsCollector collector, MemoryStream ms, int timeToWait) { if (receive.IsCompleted || webSocket.State != WebSocketState.Open) { return(false); } // Check queue for new data from server var tuple = await collector.MetricsQueue.TryDequeueAsync(TimeSpan.FromMilliseconds(timeToWait)); if (tuple.Item1 == false) { // No new info, Send heart beat await webSocket.SendAsync(WebSocketHelper.Heartbeat, WebSocketMessageType.Text, true, Database.DatabaseShutdown); return(true); } // New info, Send data ms.SetLength(0); using (ContextPool.AllocateOperationContext(out JsonOperationContext context)) using (var writer = new BlittableJsonTextWriter(context, ms)) { context.Write(writer, tuple.Item2.ToJson()); } ms.TryGetBuffer(out ArraySegment <byte> bytes); await webSocket.SendAsync(bytes, WebSocketMessageType.Text, true, Database.DatabaseShutdown); return(true); }