diff --git a/Directory.Build.props b/Directory.Build.props
index ed533330d..361ea7fe8 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,6 +1,6 @@
- 7.0.0
+ 7.2.0
prerelease
Copyright (c) 2026 TrakHound Inc., All Rights Reserved.
TrakHound Inc.
diff --git a/agent/Modules/MTConnect.NET-AgentModule-HttpAdapter/MTConnect.NET-AgentModule-HttpAdapter.csproj b/agent/Modules/MTConnect.NET-AgentModule-HttpAdapter/MTConnect.NET-AgentModule-HttpAdapter.csproj
index 1b994730a..540077ab1 100644
--- a/agent/Modules/MTConnect.NET-AgentModule-HttpAdapter/MTConnect.NET-AgentModule-HttpAdapter.csproj
+++ b/agent/Modules/MTConnect.NET-AgentModule-HttpAdapter/MTConnect.NET-AgentModule-HttpAdapter.csproj
@@ -51,4 +51,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/MTConnect.NET.Builder/MTConnect.NET.Builder.csproj b/build/MTConnect.NET.Builder/MTConnect.NET.Builder.csproj
index 010ba632b..949c71956 100644
--- a/build/MTConnect.NET.Builder/MTConnect.NET.Builder.csproj
+++ b/build/MTConnect.NET.Builder/MTConnect.NET.Builder.csproj
@@ -13,6 +13,9 @@
+
+ Always
+
Always
diff --git a/build/MTConnect.NET.Builder/config.development.yaml b/build/MTConnect.NET.Builder/config.development.yaml
new file mode 100644
index 000000000..09bbc04e8
--- /dev/null
+++ b/build/MTConnect.NET.Builder/config.development.yaml
@@ -0,0 +1,126 @@
+publisher: TrakHound Inc.
+
+input: D:\Source-Code\TrakHound\MTConnect.NET
+output: D:\Source-Code\TrakHound\MTConnect.NET\build\output\development
+
+versionInfoPath: D:\Source-Code\TrakHound\MTConnect.NET\Directory.build.props
+innoSetupPath: c:\\Program Files (x86)\\Inno Setup 6\\iscc
+
+agent:
+
+ styles: D:\Source-Code\TrakHound\MTConnect.NET\build\styles
+ schemas: D:\Source-Code\TrakHound\MTConnect.NET\build\schemas
+
+ installer:
+ projectPath: agent\MTConnect.NET-Agent
+ applicationName: MTConnect.NET Agent
+ filename: mtconnect.net-agent
+ runtimes:
+ - win-x86
+ - win-x64
+ frameworks:
+ - net10.0
+ - net9.0
+ - net8.0
+ - net7.0
+ - net6.0
+ - net48
+ - net461
+
+
+ docker:
+ projectPath: agent\MTConnect.NET-Agent
+ imageName: trakhound/mtconnect.net-agent
+ images:
+ - baseImage: 8.0.0-alpine3.18-amd64
+ runtime: linux-x64
+ framework: net8.0
+ - baseImage: 8.0.0-alpine3.18-arm64v8
+ tag: -arm
+ runtime: linux-arm64
+ framework: net8.0
+
+
+libraries:
+
+ - name: Libraries
+ nugetServer: https://nuget.trakhound.com/nuget
+ projectConfiguration: Package
+ authors: TrakHound
+ repositoryUrl: https://github.com/TrakHound/MTConnect.NET
+ repositoryBranch: v{VERSION}
+ packageTags: mtconnect;iiot;iot;cnc;
+ packageProjectUrl: www.TrakHound.com
+ packageLicenseExpression: MIT
+ packageIconUrl: https://www.trakhound.com/static/mtconnect-net-nuget.png
+ packages:
+ - name: MTConnect.NET-Common
+ projectPath: libraries/MTConnect.NET-Common
+ - name: MTConnect.NET-DeviceFinder
+ projectPath: libraries/MTConnect.NET-DeviceFinder
+ - name: MTConnect.NET-HTTP
+ projectPath: libraries/MTConnect.NET-HTTP
+ - name: MTConnect.NET-JSON
+ projectPath: libraries/MTConnect.NET-JSON
+ - name: MTConnect.NET-JSON-cppagent
+ projectPath: libraries/MTConnect.NET-JSON-cppagent
+ - name: MTConnect.NET-MQTT
+ projectPath: libraries/MTConnect.NET-MQTT
+ - name: MTConnect.NET-Services
+ projectPath: libraries/MTConnect.NET-Services
+ - name: MTConnect.NET-SHDR
+ projectPath: libraries/MTConnect.NET-SHDR
+ - name: MTConnect.NET-SysML
+ projectPath: libraries/MTConnect.NET-SysML
+ - name: MTConnect.NET-TLS
+ projectPath: libraries/MTConnect.NET-TLS
+ - name: MTConnect.NET-XML
+ projectPath: libraries/MTConnect.NET-XML
+ - name: MTConnect.NET
+ projectPath: libraries/MTConnect.NET
+
+ - name: Adapter
+ nugetServer: https://nuget.trakhound.com/nuget
+ projectConfiguration: Package
+ authors: TrakHound
+ repositoryUrl: https://github.com/TrakHound/MTConnect.NET
+ repositoryBranch: v{VERSION}
+ packageTags: mtconnect;iiot;iot;cnc;
+ packageProjectUrl: www.TrakHound.com
+ packageLicenseExpression: MIT
+ packageIconUrl: https://www.trakhound.com/static/mtconnect-net-nuget.png
+ packages:
+ - name: MTConnect.NET-Applications-Adapter
+ projectPath: adapter/MTConnect.NET-Applications-Adapter
+ - name: MTConnect.NET-AdapterModule-MQTT
+ projectPath: adapter/Modules/MTConnect.NET-AdapterModule-MQTT
+ - name: MTConnect.NET-AdapterModule-SHDR
+ projectPath: adapter/Modules/MTConnect.NET-AdapterModule-SHDR
+
+ - name: Agent
+ nugetServer: https://nuget.trakhound.com/nuget
+ projectConfiguration: Package
+ authors: TrakHound
+ repositoryUrl: https://github.com/TrakHound/MTConnect.NET
+ repositoryBranch: v{VERSION}
+ packageTags: mtconnect;iiot;iot;cnc;
+ packageProjectUrl: www.TrakHound.com
+ packageLicenseExpression: MIT
+ packageIconUrl: https://www.trakhound.com/static/mtconnect-net-nuget.png
+ packages:
+ - name: MTConnect.NET-Applications-Agents
+ projectPath: agent/MTConnect.NET-Applications-Agents
+ - name: MTConnect.NET-AgentModule-HttpAdapter
+ projectPath: agent/Modules/MTConnect.NET-AgentModule-HttpAdapter
+ - name: MTConnect.NET-AgentModule-HttpServer
+ projectPath: agent/Modules/MTConnect.NET-AgentModule-HttpServer
+ - name: MTConnect.NET-AgentModule-MqttAdapter
+ projectPath: agent/Modules/MTConnect.NET-AgentModule-MqttAdapter
+ - name: MTConnect.NET-AgentModule-MqttBroker
+ projectPath: agent/Modules/MTConnect.NET-AgentModule-MqttBroker
+ - name: MTConnect.NET-AgentModule-MqttRelay
+ projectPath: agent/Modules/MTConnect.NET-AgentModule-MqttRelay
+ - name: MTConnect.NET-AgentModule-ShdrAdapter
+ projectPath: agent/Modules/MTConnect.NET-AgentModule-ShdrAdapter
+ - name: MTConnect.NET-AgentProcessor-Python
+ projectPath: agent/Processors/MTConnect.NET-AgentProcessor-Python
\ No newline at end of file
diff --git a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpAssetClient.cs b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpAssetClient.cs
index 4c734d946..3e83e296a 100644
--- a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpAssetClient.cs
+++ b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpAssetClient.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2026 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Assets;
@@ -20,12 +20,13 @@ namespace MTConnect.Clients
public class MTConnectHttpAssetClient : IMTConnectAssetClient
{
private const int DefaultTimeout = 15000;
- private static readonly HttpClient _httpClient;
+ private static readonly HttpClient _defaultHttpClient;
+ private readonly HttpClient _httpClient;
static MTConnectHttpAssetClient()
{
- _httpClient = new HttpClient();
- _httpClient.Timeout = TimeSpan.FromMilliseconds(DefaultTimeout);
+ _defaultHttpClient = new HttpClient();
+ _defaultHttpClient.Timeout = TimeSpan.FromMilliseconds(DefaultTimeout);
}
@@ -42,6 +43,7 @@ static MTConnectHttpAssetClient()
/// Gets or Sets the Document Format to return
public MTConnectHttpAssetClient(string authority, string assetId, string documentFormat = MTConnect.DocumentFormat.XML)
{
+ _httpClient = _defaultHttpClient;
Init();
Authority = authority;
AssetId = assetId;
@@ -64,6 +66,53 @@ public MTConnectHttpAssetClient(string authority, string assetId, string documen
/// Gets or Sets the Document Format to return
public MTConnectHttpAssetClient(string authority, long count = -1, string type = null, string device = null, string documentFormat = MTConnect.DocumentFormat.XML)
{
+ _httpClient = _defaultHttpClient;
+ Init();
+ Authority = authority;
+ Device = device;
+ Type = type;
+ Count = count;
+ DocumentFormat = documentFormat;
+ ContentType = MimeTypes.Get(documentFormat);
+ }
+
+ ///
+ /// Initializes a new instance of the MTConnectAssetClient class that is used to perform
+ /// an Assets request from an MTConnect Agent using the MTConnect HTTP REST Api protocol
+ ///
+ ///
+ /// The authority portion consists of the DNS name or IP address associated with an Agent and an optional
+ /// TCP port number[:port] that the Agent is listening to for incoming Requests from client software applications.
+ /// If the port number is the default Port 80, port is not required.
+ ///
+ /// The Id of the requested Asset
+ /// Gets or Sets the Document Format to return
+ public MTConnectHttpAssetClient(HttpClient httpClient, string authority, string assetId, string documentFormat = MTConnect.DocumentFormat.XML)
+ {
+ _httpClient = httpClient != null ? httpClient : _defaultHttpClient;
+ Init();
+ Authority = authority;
+ AssetId = assetId;
+ DocumentFormat = documentFormat;
+ ContentType = MimeTypes.Get(documentFormat);
+ }
+
+ ///
+ /// Initializes a new instance of the MTConnectAssetClient class that is used to perform
+ /// an Assets request from an MTConnect Agent using the MTConnect HTTP REST Api protocol
+ ///
+ ///
+ /// The authority portion consists of the DNS name or IP address associated with an Agent and an optional
+ /// TCP port number[:port] that the Agent is listening to for incoming Requests from client software applications.
+ /// If the port number is the default Port 80, port is not required.
+ ///
+ /// The Type of Assets to retrieve
+ /// The Device to retrieve Assets for
+ /// Specifies the maximum number of MTConnectAssets Response Documents returned in an MTConnectAssets Response Document
+ /// Gets or Sets the Document Format to return
+ public MTConnectHttpAssetClient(HttpClient httpClient, string authority, long count = -1, string type = null, string device = null, string documentFormat = MTConnect.DocumentFormat.XML)
+ {
+ _httpClient = httpClient != null ? httpClient : _defaultHttpClient;
Init();
Authority = authority;
Device = device;
diff --git a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClient.cs b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClient.cs
index caa38aeaa..1c106eeea 100644
--- a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClient.cs
+++ b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClient.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2026 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Assets;
@@ -13,6 +13,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
+using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
@@ -23,6 +24,7 @@ namespace MTConnect.Clients
///
public class MTConnectHttpClient : IMTConnectClient, IMTConnectEntityClient
{
+ private readonly HttpClient _httpClient;
private readonly Dictionary _devices = new Dictionary();
private readonly Dictionary _cachedComponents = new Dictionary();
private readonly Dictionary _cachedDataItems = new Dictionary();
@@ -84,6 +86,55 @@ public MTConnectHttpClient(string hostname, int port, string device = null, stri
DocumentFormat = documentFormat;
}
+ ///
+ /// Initializes a new instance of the MTConnectClient class that is used to perform
+ /// the full request and stream protocol from an MTConnect Agent using the MTConnect HTTP REST Api protocol
+ ///
+ ///
+ /// The authority portion consists of the DNS name or IP address associated with an Agent and an optional
+ /// TCP port number[:port] that the Agent is listening to for incoming Requests from client software applications.
+ /// If the port number is the default Port 80, port is not required.
+ ///
+ ///
+ /// If present, specifies that only the Equipment Metadata for the piece of equipment represented by the name or uuid will be published.
+ /// If not present, Metadata for all pieces of equipment associated with the Agent will be published.
+ ///
+ /// Gets or Sets the Document Format to return
+ public MTConnectHttpClient(HttpClient httpClient, string authority, string device = null, string documentFormat = MTConnect.DocumentFormat.XML)
+ {
+ _httpClient = httpClient;
+ Id = Guid.NewGuid().ToString();
+ Init();
+ Authority = authority;
+ Device = device;
+ DocumentFormat = documentFormat;
+ }
+
+ ///
+ /// Initializes a new instance of the MTConnectClient class that is used to perform
+ /// the full request and stream protocol from an MTConnect Agent using the MTConnect HTTP REST Api protocol
+ ///
+ ///
+ /// The Hostname of the MTConnect Agent
+ ///
+ ///
+ /// The Port of the MTConnect Agent
+ ///
+ ///
+ /// If present, specifies that only the Equipment Metadata for the piece of equipment represented by the name or uuid will be published.
+ /// If not present, Metadata for all pieces of equipment associated with the Agent will be published.
+ ///
+ /// Gets or Sets the Document Format to return
+ public MTConnectHttpClient(HttpClient httpClient, string hostname, int port, string device = null, string documentFormat = MTConnect.DocumentFormat.XML)
+ {
+ _httpClient = httpClient;
+ Id = Guid.NewGuid().ToString();
+ Init();
+ Authority = CreateUrl(hostname, port);
+ Device = device;
+ DocumentFormat = documentFormat;
+ }
+
private void Init()
{
Interval = 500;
@@ -490,7 +541,7 @@ public void Reset()
///
public IDevicesResponseDocument GetProbe()
{
- var client = new MTConnectHttpProbeClient(Authority, Device, DocumentFormat);
+ var client = new MTConnectHttpProbeClient(_httpClient, Authority, Device, DocumentFormat);
client.Timeout = Timeout;
client.ContentEncodings = ContentEncodings;
client.ContentType = ContentType;
@@ -514,7 +565,7 @@ public async Task GetProbeAsync()
///
public async Task GetProbeAsync(CancellationToken cancellationToken)
{
- var client = new MTConnectHttpProbeClient(Authority, Device, DocumentFormat);
+ var client = new MTConnectHttpProbeClient(_httpClient, Authority, Device, DocumentFormat);
client.Timeout = Timeout;
client.ContentEncodings = ContentEncodings;
client.ContentType = ContentType;
@@ -531,7 +582,7 @@ public async Task GetProbeAsync(CancellationToken canc
///
public IStreamsResponseDocument GetCurrent(long at = 0, string path = null)
{
- var client = new MTConnectHttpCurrentClient(Authority, Device, at: at, path: path, documentFormat: DocumentFormat);
+ var client = new MTConnectHttpCurrentClient(_httpClient, Authority, Device, at: at, path: path, documentFormat: DocumentFormat);
client.Timeout = Timeout;
client.ContentEncodings = ContentEncodings;
client.ContentType = ContentType;
@@ -555,7 +606,7 @@ public async Task GetCurrentAsync(long at = 0, string
///
public async Task GetCurrentAsync(CancellationToken cancellationToken, long at = 0, string path = null)
{
- var client = new MTConnectHttpCurrentClient(Authority, Device, at: at, path: path, documentFormat: DocumentFormat);
+ var client = new MTConnectHttpCurrentClient(_httpClient, Authority, Device, at: at, path: path, documentFormat: DocumentFormat);
client.Timeout = Timeout;
client.ContentEncodings = ContentEncodings;
client.ContentType = ContentType;
@@ -572,7 +623,7 @@ public async Task GetCurrentAsync(CancellationToken ca
///
public IStreamsResponseDocument GetSample(long from = 0, long to = 0, int count = 0, string path = null)
{
- var client = new MTConnectHttpSampleClient(Authority, Device, from: from, to: to, count: count, path: path, documentFormat: DocumentFormat);
+ var client = new MTConnectHttpSampleClient(_httpClient, Authority, Device, from: from, to: to, count: count, path: path, documentFormat: DocumentFormat);
client.Timeout = Timeout;
client.ContentEncodings = ContentEncodings;
client.ContentType = ContentType;
@@ -596,7 +647,7 @@ public async Task GetSampleAsync(long from = 0, long t
///
public async Task GetSampleAsync(CancellationToken cancellationToken, long from = 0, long to = 0, int count = 0, string path = null)
{
- var client = new MTConnectHttpSampleClient(Authority, Device, from: from, to: to, count: count, path: path, documentFormat: DocumentFormat);
+ var client = new MTConnectHttpSampleClient(_httpClient, Authority, Device, from: from, to: to, count: count, path: path, documentFormat: DocumentFormat);
client.Timeout = Timeout;
client.ContentEncodings = ContentEncodings;
client.ContentType = ContentType;
@@ -613,7 +664,7 @@ public async Task GetSampleAsync(CancellationToken can
///
public IAssetsResponseDocument GetAssets(long count = 100)
{
- var client = new MTConnectHttpAssetClient(Authority, count, null, null, DocumentFormat);
+ var client = new MTConnectHttpAssetClient(_httpClient, Authority, count, null, null, DocumentFormat);
client.Timeout = Timeout;
client.ContentEncodings = ContentEncodings;
client.ContentType = ContentType;
@@ -637,7 +688,7 @@ public async Task GetAssetsAsync(ulong count = 100)
///
public async Task GetAssetsAsync(CancellationToken cancellationToken, ulong count = 100)
{
- var client = new MTConnectHttpAssetClient(Authority, (long)count, null, null, DocumentFormat);
+ var client = new MTConnectHttpAssetClient(_httpClient, Authority, (long)count, null, null, DocumentFormat);
client.Timeout = Timeout;
client.ContentEncodings = ContentEncodings;
client.ContentType = ContentType;
@@ -654,7 +705,7 @@ public async Task GetAssetsAsync(CancellationToken canc
///
public IAssetsResponseDocument GetAsset(string assetId)
{
- var client = new MTConnectHttpAssetClient(Authority, assetId, DocumentFormat);
+ var client = new MTConnectHttpAssetClient(_httpClient, Authority, assetId, DocumentFormat);
client.Timeout = Timeout;
client.ContentEncodings = ContentEncodings;
client.ContentType = ContentType;
@@ -678,7 +729,7 @@ public async Task GetAssetAsync(string assetId)
///
public async Task GetAssetAsync(string assetId, CancellationToken cancellationToken)
{
- var client = new MTConnectHttpAssetClient(Authority, assetId, DocumentFormat);
+ var client = new MTConnectHttpAssetClient(_httpClient, Authority, assetId, DocumentFormat);
client.Timeout = Timeout;
client.ContentEncodings = ContentEncodings;
client.ContentType = ContentType;
@@ -772,7 +823,7 @@ private async Task Worker()
if (CurrentOnly) url = CreateCurrentUrl(Authority, Device, Interval, _streamPath);
// Create and Start the Stream
- using (_stream = new MTConnectHttpClientStream(url, DocumentFormat))
+ using (_stream = new MTConnectHttpClientStream(_httpClient, url, DocumentFormat))
{
_stream.Timeout = Heartbeat * 3;
_stream.ContentEncodings = ContentEncodings;
diff --git a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClientStream.cs b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClientStream.cs
index 71c27bb25..d2c06d740 100644
--- a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClientStream.cs
+++ b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClientStream.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2026 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Errors;
@@ -25,8 +25,15 @@ public class MTConnectHttpClientStream : IDisposable
private const byte CarriageReturn = 13;
private const byte Dash = 45;
private static readonly byte[] _trimBytes = new byte[] { LineFeed, CarriageReturn };
+ private static readonly HttpClient _defaultHttpClient;
private readonly HttpClient _httpClient;
+ static MTConnectHttpClientStream()
+ {
+ _defaultHttpClient = new HttpClient();
+ _defaultHttpClient.Timeout = TimeSpan.FromMilliseconds(DefaultTimeout);
+ }
+
private CancellationTokenSource _stop;
private string _documentFormat = DocumentFormat.XML;
@@ -42,23 +49,42 @@ public class MTConnectHttpClientStream : IDisposable
/// Document format key (e.g. xml, json) to request and to parse the response with.
public MTConnectHttpClientStream(string url, string documentFormat = DocumentFormat.XML)
{
+ _httpClient = _defaultHttpClient;
Id = Guid.NewGuid().ToString();
Url = url;
Timeout = DefaultTimeout;
_documentFormat = documentFormat;
ContentEncodings = HttpContentEncodings.DefaultAccept;
ContentType = MimeTypes.Get(documentFormat);
-
- _httpClient = new HttpClient();
- _httpClient.Timeout = TimeSpan.FromMilliseconds(DefaultTimeout);
}
- /// Disposes the underlying . The stream itself should be ped first; does not cancel pending reads.
- public void Dispose()
+ ///
+ /// Constructs an HTTP streaming reader for the MTConnect long-poll sample response
+ /// at . The stream assigns itself a fresh , defaults
+ /// the read timeout to five minutes, advertises the standard
+ /// on Accept-Encoding, and picks
+ /// the matching Accept MIME type for .
+ ///
+ /// The fully built sample URL with interval / heartbeat parameters.
+ /// Document format key (e.g. xml, json) to request and to parse the response with.
+ public MTConnectHttpClientStream(HttpClient httpClient, string url, string documentFormat = DocumentFormat.XML)
{
- if (_httpClient != null) _httpClient.Dispose();
+ _httpClient = httpClient != null ? httpClient : _defaultHttpClient;
+ Id = Guid.NewGuid().ToString();
+ Url = url;
+ Timeout = DefaultTimeout;
+ _documentFormat = documentFormat;
+ ContentEncodings = HttpContentEncodings.DefaultAccept;
+ ContentType = MimeTypes.Get(documentFormat);
}
+ ///
+ /// Releases the stream. The underlying is not disposed since it is either
+ /// supplied by the caller or shared across all streams. The stream itself should be ped first;
+ /// does not cancel pending reads.
+ ///
+ public void Dispose() { }
+
///
/// The unique ID of the Stream
@@ -180,24 +206,7 @@ public async Task Run(CancellationToken cancellationToken)
Started.Raise(this, EventArgs.Empty, InternalError);
- // Add 'Accept' HTTP Header
- _httpClient.DefaultRequestHeaders.Add(HttpHeaders.Accept, ContentType);
-
- // Add 'Accept-Encoding' HTTP Header
- if (!ContentEncodings.IsNullOrEmpty())
- {
- foreach (var acceptEncoding in ContentEncodings)
- {
- _httpClient.DefaultRequestHeaders.Add(HttpHeaders.AcceptEncoding, acceptEncoding.ToString().ToLower());
- }
- }
-
-
- var httpRequest = new HttpRequestMessage();
- httpRequest.RequestUri = new Uri(Url);
- httpRequest.Method = HttpMethod.Get;
-
-
+ using (var httpRequest = CreateRequest())
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))
@@ -325,6 +334,29 @@ public async Task Run(CancellationToken cancellationToken)
Stopped.Raise(this, EventArgs.Empty, InternalError);
}
+ private HttpRequestMessage CreateRequest()
+ {
+ var httpRequest = new HttpRequestMessage();
+ httpRequest.RequestUri = new Uri(Url);
+ httpRequest.Method = HttpMethod.Get;
+
+ // Headers are set on the Request (not HttpClient.DefaultRequestHeaders) since the HttpClient may be shared
+
+ // Add 'Accept' HTTP Header
+ httpRequest.Headers.Add(HttpHeaders.Accept, ContentType);
+
+ // Add 'Accept-Encoding' HTTP Header
+ if (!ContentEncodings.IsNullOrEmpty())
+ {
+ foreach (var acceptEncoding in ContentEncodings)
+ {
+ httpRequest.Headers.Add(HttpHeaders.AcceptEncoding, acceptEncoding.ToString().ToLower());
+ }
+ }
+
+ return httpRequest;
+ }
+
private static string GetHeaderValue(string s, string name)
{
if (!string.IsNullOrEmpty(s))
diff --git a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpCurrentClient.cs b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpCurrentClient.cs
index 859b13bd6..cf0beb79c 100644
--- a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpCurrentClient.cs
+++ b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpCurrentClient.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2026 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Errors;
@@ -21,12 +21,13 @@ namespace MTConnect.Clients
public class MTConnectHttpCurrentClient : IMTConnectCurrentClient
{
private const int DefaultTimeout = 15000;
- private static readonly HttpClient _httpClient;
+ private static readonly HttpClient _defaultHttpClient;
+ private readonly HttpClient _httpClient;
static MTConnectHttpCurrentClient()
{
- _httpClient = new HttpClient();
- _httpClient.Timeout = TimeSpan.FromMilliseconds(DefaultTimeout);
+ _defaultHttpClient = new HttpClient();
+ _defaultHttpClient.Timeout = TimeSpan.FromMilliseconds(DefaultTimeout);
}
@@ -48,6 +49,7 @@ static MTConnectHttpCurrentClient()
/// Gets or Sets the Document Format to return
public MTConnectHttpCurrentClient(string authority, string device = null, string path = null, long at = -1, string documentFormat = MTConnect.DocumentFormat.XML)
{
+ _httpClient = _defaultHttpClient;
Authority = authority;
Device = device;
Path = path;
@@ -77,6 +79,66 @@ public MTConnectHttpCurrentClient(string authority, string device = null, string
/// Gets or Sets the Document Format to return
public MTConnectHttpCurrentClient(string hostname, int port, string device = null, string path = null, long at = -1, string documentFormat = MTConnect.DocumentFormat.XML)
{
+ _httpClient = _defaultHttpClient;
+ Authority = CreateUri(hostname, port).ToString();
+ Device = device;
+ Path = path;
+ At = at;
+ DocumentFormat = documentFormat;
+ Timeout = DefaultTimeout;
+ ContentEncodings = HttpContentEncodings.DefaultAccept;
+ ContentType = MimeTypes.Get(documentFormat);
+ }
+
+ ///
+ /// Initializes a new instance of the MTConnectCurrentClient class that is used to perform
+ /// a Current request from an MTConnect Agent using the MTConnect HTTP REST Api protocol
+ ///
+ ///
+ /// The authority portion consists of the DNS name or IP address associated with an Agent and an optional
+ /// TCP port number[:port] that the Agent is listening to for incoming Requests from client software applications.
+ /// If the port number is the default Port 80, port is not required.
+ ///
+ ///
+ /// If present, specifies that only the Equipment Metadata for the piece of equipment represented by the name or uuid will be published.
+ /// If not present, Metadata for all pieces of equipment associated with the Agent will be published.
+ ///
+ /// The XPath expression specifying the components and/or data items to include
+ /// The sequence number to retrieve the current data for
+ /// Gets or Sets the Document Format to return
+ public MTConnectHttpCurrentClient(HttpClient httpClient, string authority, string device = null, string path = null, long at = -1, string documentFormat = MTConnect.DocumentFormat.XML)
+ {
+ _httpClient = httpClient != null ? httpClient : _defaultHttpClient;
+ Authority = authority;
+ Device = device;
+ Path = path;
+ At = at;
+ DocumentFormat = documentFormat;
+ Timeout = DefaultTimeout;
+ ContentEncodings = HttpContentEncodings.DefaultAccept;
+ ContentType = MimeTypes.Get(documentFormat);
+ }
+
+ ///
+ /// Initializes a new instance of the MTConnectCurrentClient class that is used to perform
+ /// a Current request from an MTConnect Agent using the MTConnect HTTP REST Api protocol
+ ///
+ ///
+ /// The Hostname of the MTConnect Agent
+ ///
+ ///
+ /// The Port of the MTConnect Agent
+ ///
+ ///
+ /// If present, specifies that only the Equipment Metadata for the piece of equipment represented by the name or uuid will be published.
+ /// If not present, Metadata for all pieces of equipment associated with the Agent will be published.
+ ///
+ /// The XPath expression specifying the components and/or data items to include
+ /// The sequence number to retrieve the current data for
+ /// Gets or Sets the Document Format to return
+ public MTConnectHttpCurrentClient(HttpClient httpClient, string hostname, int port, string device = null, string path = null, long at = -1, string documentFormat = MTConnect.DocumentFormat.XML)
+ {
+ _httpClient = httpClient != null ? httpClient : _defaultHttpClient;
Authority = CreateUri(hostname, port).ToString();
Device = device;
Path = path;
diff --git a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpProbeClient.cs b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpProbeClient.cs
index af90cebc4..aa8c72cff 100644
--- a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpProbeClient.cs
+++ b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpProbeClient.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2026 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Devices;
@@ -22,12 +22,13 @@ namespace MTConnect.Clients
public class MTConnectHttpProbeClient : IMTConnectProbeClient
{
private const int DefaultTimeout = 15000;
- private static readonly HttpClient _httpClient;
+ private static readonly HttpClient _defaultHttpClient;
+ private readonly HttpClient _httpClient;
static MTConnectHttpProbeClient()
{
- _httpClient = new HttpClient();
- _httpClient.Timeout = TimeSpan.FromMilliseconds(DefaultTimeout);
+ _defaultHttpClient = new HttpClient();
+ _defaultHttpClient.Timeout = TimeSpan.FromMilliseconds(DefaultTimeout);
}
///
@@ -105,6 +106,7 @@ public static bool GetResolvedConnecionIPAddress(string serverNameOrURL, out IPA
/// Gets or Sets the Document Format to return
public MTConnectHttpProbeClient(string authority, string device = null, string documentFormat = MTConnect.DocumentFormat.XML)
{
+ _httpClient = _defaultHttpClient;
Authority = authority;
Device = device;
DocumentFormat = documentFormat;
@@ -130,6 +132,58 @@ public MTConnectHttpProbeClient(string authority, string device = null, string d
/// Gets or Sets the Document Format to return
public MTConnectHttpProbeClient(string hostname, int port, string device = null, string documentFormat = MTConnect.DocumentFormat.XML)
{
+ _httpClient = _defaultHttpClient;
+ Authority = CreateUri(hostname, port).ToString();
+ Device = device;
+ DocumentFormat = documentFormat;
+ Timeout = DefaultTimeout;
+ ContentEncodings = HttpContentEncodings.DefaultAccept;
+ ContentType = MimeTypes.Get(documentFormat);
+ }
+
+ ///
+ /// Initializes a new instance of the MTConnectProbeClient class that is used to perform
+ /// a Probe request from an MTConnect Agent using the MTConnect HTTP REST Api protocol
+ ///
+ ///
+ /// The authority portion consists of the DNS name or IP address associated with an Agent and an optional
+ /// TCP port number[:port] that the Agent is listening to for incoming Requests from client software applications.
+ /// If the port number is the default Port 80, port is not required.
+ ///
+ ///
+ /// If present, specifies that only the Equipment Metadata for the piece of equipment represented by the name or uuid will be published.
+ /// If not present, Metadata for all pieces of equipment associated with the Agent will be published.
+ ///
+ /// Gets or Sets the Document Format to return
+ public MTConnectHttpProbeClient(HttpClient httpClient, string authority, string device = null, string documentFormat = MTConnect.DocumentFormat.XML)
+ {
+ _httpClient = httpClient != null ? httpClient : _defaultHttpClient;
+ Authority = authority;
+ Device = device;
+ DocumentFormat = documentFormat;
+ Timeout = DefaultTimeout;
+ ContentEncodings = HttpContentEncodings.DefaultAccept;
+ ContentType = MimeTypes.Get(documentFormat);
+ }
+
+ ///
+ /// Initializes a new instance of the MTConnectProbeClient class that is used to perform
+ /// a Probe request from an MTConnect Agent using the MTConnect HTTP REST Api protocol
+ ///
+ ///
+ /// The Hostname of the MTConnect Agent
+ ///
+ ///
+ /// The Port of the MTConnect Agent
+ ///
+ ///
+ /// If present, specifies that only the Equipment Metadata for the piece of equipment represented by the name or uuid will be published.
+ /// If not present, Metadata for all pieces of equipment associated with the Agent will be published.
+ ///
+ /// Gets or Sets the Document Format to return
+ public MTConnectHttpProbeClient(HttpClient httpClient, string hostname, int port, string device = null, string documentFormat = MTConnect.DocumentFormat.XML)
+ {
+ _httpClient = httpClient != null ? httpClient : _defaultHttpClient;
Authority = CreateUri(hostname, port).ToString();
Device = device;
DocumentFormat = documentFormat;
diff --git a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpSampleClient.cs b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpSampleClient.cs
index 56ac4990c..63299023c 100644
--- a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpSampleClient.cs
+++ b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpSampleClient.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2026 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Errors;
@@ -21,12 +21,13 @@ namespace MTConnect.Clients
public class MTConnectHttpSampleClient : IMTConnectSampleClient
{
private const int DefaultTimeout = 15000;
- private static readonly HttpClient _httpClient;
+ private static readonly HttpClient _defaultHttpClient;
+ private readonly HttpClient _httpClient;
static MTConnectHttpSampleClient()
{
- _httpClient = new HttpClient();
- _httpClient.Timeout = TimeSpan.FromMilliseconds(DefaultTimeout);
+ _defaultHttpClient = new HttpClient();
+ _defaultHttpClient.Timeout = TimeSpan.FromMilliseconds(DefaultTimeout);
}
@@ -50,6 +51,7 @@ static MTConnectHttpSampleClient()
/// Gets or Sets the Document Format to return
public MTConnectHttpSampleClient(string authority, string device = null, string path = null, long from = -1, long to = -1, long count = -1, string documentFormat = MTConnect.DocumentFormat.XML)
{
+ _httpClient = _defaultHttpClient;
Authority = authority;
Device = device;
Path = path;
@@ -83,6 +85,74 @@ public MTConnectHttpSampleClient(string authority, string device = null, string
/// Gets or Sets the Document Format to return
public MTConnectHttpSampleClient(string hostname, int port, string device = null, string path = null, long from = -1, long to = -1, long count = -1, string documentFormat = MTConnect.DocumentFormat.XML)
{
+ _httpClient = _defaultHttpClient;
+ Authority = CreateUri(hostname, port).ToString();
+ Device = device;
+ Path = path;
+ From = from;
+ To = to;
+ Count = count;
+ DocumentFormat = documentFormat;
+ Timeout = DefaultTimeout;
+ ContentEncodings = HttpContentEncodings.DefaultAccept;
+ ContentType = MimeTypes.Get(documentFormat);
+ }
+
+ ///
+ /// Initializes a new instance of the MTConnectSampleClient class that is used to perform
+ /// a Sample request from an MTConnect Agent using the MTConnect HTTP REST Api protocol
+ ///
+ ///
+ /// The authority portion consists of the DNS name or IP address associated with an Agent and an optional
+ /// TCP port number[:port] that the Agent is listening to for incoming Requests from client software applications.
+ /// If the port number is the default Port 80, port is not required.
+ ///
+ ///
+ /// If present, specifies that only the Equipment Metadata for the piece of equipment represented by the name or uuid will be published.
+ /// If not present, Metadata for all pieces of equipment associated with the Agent will be published.
+ ///
+ /// The XPath expression specifying the components and/or data items to include
+ /// The sequence to retrieve the sample data from
+ /// The sequence to retrieve the sample data to
+ /// The number of sequences to include in the sample data
+ /// Gets or Sets the Document Format to return
+ public MTConnectHttpSampleClient(HttpClient httpClient, string authority, string device = null, string path = null, long from = -1, long to = -1, long count = -1, string documentFormat = MTConnect.DocumentFormat.XML)
+ {
+ _httpClient = httpClient != null ? httpClient : _defaultHttpClient;
+ Authority = authority;
+ Device = device;
+ Path = path;
+ From = from;
+ To = to;
+ Count = count;
+ DocumentFormat = documentFormat;
+ Timeout = DefaultTimeout;
+ ContentEncodings = HttpContentEncodings.DefaultAccept;
+ ContentType = MimeTypes.Get(documentFormat);
+ }
+
+ ///
+ /// Initializes a new instance of the MTConnectSampleClient class that is used to perform
+ /// a Sample request from an MTConnect Agent using the MTConnect HTTP REST Api protocol
+ ///
+ ///
+ /// The Hostname of the MTConnect Agent
+ ///
+ ///
+ /// The Port of the MTConnect Agent
+ ///
+ ///
+ /// If present, specifies that only the Equipment Metadata for the piece of equipment represented by the name or uuid will be published.
+ /// If not present, Metadata for all pieces of equipment associated with the Agent will be published.
+ ///
+ /// The XPath expression specifying the components and/or data items to include
+ /// The sequence to retrieve the sample data from
+ /// The sequence to retrieve the sample data to
+ /// The number of sequences to include in the sample data
+ /// Gets or Sets the Document Format to return
+ public MTConnectHttpSampleClient(HttpClient httpClient, string hostname, int port, string device = null, string path = null, long from = -1, long to = -1, long count = -1, string documentFormat = MTConnect.DocumentFormat.XML)
+ {
+ _httpClient = httpClient != null ? httpClient : _defaultHttpClient;
Authority = CreateUri(hostname, port).ToString();
Device = device;
Path = path;