private void OnStreamingClosed(object sender, EventArgs args) { StreamingClosed?.Invoke(this, args); }
private async Task EnsureWebSocketConnectionAsync() { if (_webSocket != null) { return; } if (Interlocked.CompareExchange(ref _webSocket, new ClientWebSocket(), null) != null) { return; } _webSocket.Options.SetRequestHeader("Authorization", $"Bearer {_token}"); await _webSocket.ConnectAsync(_webSocketBaseUri, CancellationToken.None).ConfigureAwait(false); _webSocketTask = Task.Run(async() => { var transferBuffer = new byte[8096]; var messageBuffer = new List <byte>(); try { while (_webSocket.State == WebSocketState.Open) { var buffer = new ArraySegment <byte>(transferBuffer); var result = await _webSocket.ReceiveAsync(buffer, CancellationToken.None); switch (result.MessageType) { case WebSocketMessageType.Close: await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Ok", CancellationToken.None); StreamingClosed?.Invoke(this, EventArgs.Empty); return; case WebSocketMessageType.Text: var receivedBytes = new byte[result.Count]; Array.ConstrainedCopy(buffer.Array, 0, receivedBytes, 0, result.Count); messageBuffer.AddRange(receivedBytes); if (result.EndOfMessage) { var data = Encoding.UTF8.GetString(messageBuffer.ToArray()); var response = JsonConvert.DeserializeObject <StreamingResponse>(data); OnStreamingEvent(response); messageBuffer.Clear(); } break; } } } catch (WebSocketException e) { WebSocketException?.Invoke(this, e); } finally { _webSocket?.Dispose(); _webSocket = null; } }); }
private async Task EnsureWebSocketConnectionAsync() { if (_webSocket != null) { return; } if (Interlocked.CompareExchange(ref _webSocket, new ClientWebSocket(), null) != null) { return; } _webSocket.Options.SetRequestHeader("Authorization", $"Bearer {_token}"); await _webSocket.ConnectAsync(_webSocketBaseUri, CancellationToken.None).ConfigureAwait(false); _webSocketTask = Task.Run(async() => { var bufferCapacity = 8192; var transferBuffer = new byte[bufferCapacity]; var messageBuffer = new MemoryStream(bufferCapacity); var messageLength = 0; try { while (_webSocket.State == WebSocketState.Open) { var buffer = new ArraySegment <byte>(transferBuffer); var result = await _webSocket.ReceiveAsync(buffer, CancellationToken.None); switch (result.MessageType) { case WebSocketMessageType.Close: await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Ok", CancellationToken.None); StreamingClosed?.Invoke(this, EventArgs.Empty); return; case WebSocketMessageType.Text: if (result.EndOfMessage) { StreamingResponse response; // We can use buffer directly if we got a message without chunking // This is almost always the case if (messageLength == 0) { response = JsonSerializer.Deserialize <StreamingResponse>( buffer.Array.AsSpan(0, result.Count), SerializationOptions.Instance); } else { // ReSharper disable once AssignNullToNotNullAttribute messageBuffer.Write(buffer.Array, 0, result.Count); messageLength += result.Count; response = JsonSerializer.Deserialize <StreamingResponse>( messageBuffer.GetBuffer().AsSpan(0, messageLength), SerializationOptions.Instance); messageBuffer.Position = 0; messageLength = 0; } OnStreamingEvent(response); } else { // ReSharper disable once AssignNullToNotNullAttribute messageBuffer.Write(buffer.Array, 0, result.Count); messageLength += result.Count; } break; } } } catch (WebSocketException e) { WebSocketException?.Invoke(this, e); } finally { _webSocket?.Dispose(); _webSocket = null; } }); }