From 8233cd4283145a83af455986cd6b1eda36ced98f Mon Sep 17 00:00:00 2001 From: Patrick Ritchie Date: Fri, 2 Aug 2024 18:34:16 -0400 Subject: [PATCH] Update v6.4.5 - Fixed issue with MTConnectHttpClientStream that caused an exception to be thrown when using multiple MTConnectClient connections. Moved the _httpClient variable from being static to be a class member and now requires the MTConnectHttpClientStream class to be disposed. --- build/AssemblyInfo.cs | 4 +-- .../Clients/MTConnectHttpClient.cs | 36 ++++++++++--------- .../Clients/MTConnectHttpClientStream.cs | 19 +++++----- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/build/AssemblyInfo.cs b/build/AssemblyInfo.cs index 0de0e6a5..9ed66cb4 100644 --- a/build/AssemblyInfo.cs +++ b/build/AssemblyInfo.cs @@ -1,6 +1,6 @@ using System.Reflection; -[assembly: AssemblyVersion("6.4.4")] -[assembly: AssemblyFileVersion("6.4.4")] +[assembly: AssemblyVersion("6.4.5")] +[assembly: AssemblyFileVersion("6.4.5")] [assembly: AssemblyCompany("TrakHound Inc.")] [assembly: AssemblyCopyright("Copyright (c) 2024 TrakHound Inc., All Rights Reserved.")] diff --git a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClient.cs b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClient.cs index c601a5c3..a6332839 100644 --- a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClient.cs +++ b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClient.cs @@ -717,23 +717,25 @@ private async Task Worker() if (CurrentOnly) url = CreateCurrentUrl(Authority, Device, Interval, _streamPath); // Create and Start the Stream - _stream = new MTConnectHttpClientStream(url, DocumentFormat); - _stream.Timeout = Heartbeat * 3; - _stream.ContentEncodings = ContentEncodings; - _stream.ContentType = ContentType; - _stream.Starting += (s, o) => StreamStarting?.Invoke(this, url); - _stream.Started += (s, o) => StreamStarted?.Invoke(this, url); - _stream.Stopping += (s, o) => StreamStopping?.Invoke(this, url); - _stream.Stopped += (s, o) => StreamStopped?.Invoke(this, url); - _stream.DocumentReceived += (s, doc) => ProcessSampleDocument(doc, _stop.Token); - _stream.ErrorReceived += (s, doc) => ProcessSampleError(doc); - _stream.FormatError += (s, r) => FormatError?.Invoke(this, r); - _stream.ConnectionError += (s, ex) => ConnectionError?.Invoke(this, ex); - _stream.InternalError += (s, ex) => InternalError?.Invoke(this, ex); - - // Run Stream (Blocking call) - await _stream.Run(_stop.Token); - + using (_stream = new MTConnectHttpClientStream(url, DocumentFormat)) + { + _stream.Timeout = Heartbeat * 3; + _stream.ContentEncodings = ContentEncodings; + _stream.ContentType = ContentType; + _stream.Starting += (s, o) => StreamStarting?.Invoke(this, url); + _stream.Started += (s, o) => StreamStarted?.Invoke(this, url); + _stream.Stopping += (s, o) => StreamStopping?.Invoke(this, url); + _stream.Stopped += (s, o) => StreamStopped?.Invoke(this, url); + _stream.DocumentReceived += (s, doc) => ProcessSampleDocument(doc, _stop.Token); + _stream.ErrorReceived += (s, doc) => ProcessSampleError(doc); + _stream.FormatError += (s, r) => FormatError?.Invoke(this, r); + _stream.ConnectionError += (s, ex) => ConnectionError?.Invoke(this, ex); + _stream.InternalError += (s, ex) => InternalError?.Invoke(this, ex); + + // Run Stream (Blocking call) + await _stream.Run(_stop.Token); + } + initialRequest = false; if (!_stop.Token.IsCancellationRequested) diff --git a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClientStream.cs b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClientStream.cs index 864faf92..cf674d0d 100644 --- a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClientStream.cs +++ b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClientStream.cs @@ -18,25 +18,19 @@ namespace MTConnect.Clients /// /// An Http Stream for reading MTConnect Sample or Current streams and returns MTConnectStreamsResponse documents /// - public class MTConnectHttpClientStream + public class MTConnectHttpClientStream : IDisposable { private const int DefaultTimeout = 300000; private const byte LineFeed = 10; private const byte CarriageReturn = 13; private const byte Dash = 45; - private static readonly HttpClient _httpClient; private static readonly byte[] _trimBytes = new byte[] { 10, 13 }; + private readonly HttpClient _httpClient; private CancellationTokenSource _stop; private string _documentFormat = DocumentFormat.XML; - static MTConnectHttpClientStream() - { - _httpClient = new HttpClient(); - _httpClient.Timeout = TimeSpan.FromMilliseconds(DefaultTimeout); - } - public MTConnectHttpClientStream(string url, string documentFormat = DocumentFormat.XML) { Id = Guid.NewGuid().ToString(); @@ -45,6 +39,14 @@ public MTConnectHttpClientStream(string url, string documentFormat = DocumentFor _documentFormat = documentFormat; ContentEncodings = HttpContentEncodings.DefaultAccept; ContentType = MimeTypes.Get(documentFormat); + + _httpClient = new HttpClient(); + _httpClient.Timeout = TimeSpan.FromMilliseconds(DefaultTimeout); + } + + public void Dispose() + { + if (_httpClient != null) _httpClient.Dispose(); } @@ -158,6 +160,7 @@ public async Task Run(CancellationToken cancellationToken) httpRequest.RequestUri = new Uri(Url); httpRequest.Method = HttpMethod.Get; + using (var response = await _httpClient.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead, stop.Token)) #if NET5_0_OR_GREATER using (var stream = await response.Content.ReadAsStreamAsync(stop.Token))