Files
2026-04-17 14:55:32 -04:00

12 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
Common/DTS.Common.IConnection/EthernetConnection/RESTConnection.cs
Common/DTS.Common.IConnection/EthernetConnection/EthernetConnection.cs
2026-04-16T11:48:39.886921+00:00 zai-org/GLM-5-FP8 1 21dfcca726b35e5d

Documentation: IConnection Implementations

1. Purpose

This module provides two implementations of the IConnection interface for network communication within the DTS system. EthernetConnection is a full TCP socket wrapper that manages asynchronous socket operations, connection lifecycle, and keep-alive configuration for hardware devices. RESTConnection is a stub/skeleton implementation that immediately completes all operations without actual network I/O, designed to satisfy the IConnection interface contract for scenarios where REST-based communication replaces traditional socket connections.


2. Public Interface

EthernetConnection (DTS.Common)

Properties

Signature Description
bool IsSoftDisconnected { get; private set; } Returns true if the connection has been soft-disconnected.
bool RequiresKeepAliveReset { get; set; } When true, SoftConnect() performs additional handshake on command port 8200 before connecting.
Socket Sock The underlying System.Net.Sockets.Socket instance. Publicly accessible.
bool Connected Returns Sock != null && Sock.Connected.
string ConnectString Returns the connection string (format: "host:port").
SocketFlags Flags { get; set; } Socket flags used for send/receive operations.

Events

Signature Description
event EventHandler OnDisconnected Raised when KeepAliveErrorReceived() is invoked, indicating connection loss.

Methods

Signature Description
void Create(string connectString, string hostIPAddress) Creates and configures the underlying socket with keep-alive settings. Stores connection parameters.
Socket CreateSock(string connectString, string hostIPAddress) Factory method that creates a configured Socket with TCP NoDelay, KeepAlive, and buffer sizes from DFConstantsAndEnums. Binds to hostIPAddress if provided.
void SoftDisconnect() If HardwareConstants.AllowSoftDisconnects is true, disconnects and disposes the socket, sets IsSoftDisconnected = true.
void SoftConnect() Reconnects a soft-disconnected socket. Optionally performs keep-alive reset via port 8200 if RequiresKeepAliveReset is true. Retries connection up to 3 times.
void KeepAliveErrorReceived() Shuts down, closes, and disposes the socket; invokes OnDisconnected event.
string GetConnectionData() Returns a string with local and remote endpoints, or empty string if unavailable.
IAsyncResult BeginConnect(AsyncCallback cb, object state) Begins asynchronous connection. Throws if socket is null, Connect_String is empty/malformed, or port is invalid.
void EndConnect(IAsyncResult ar) Completes the connection. Logs success with endpoints.
IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback cb, object state) Begins asynchronous disconnect. Throws SocketException(WSAEISCONN) if socket is not connected.
void EndDisconnect(IAsyncResult asyncResult) Completes the disconnect operation.
IAsyncResult BeginAccept(AsyncCallback callback, object state) Begins asynchronous accept for incoming connections.
IConnection EndAccept(IAsyncResult asyncResult) Returns a new EthernetConnection wrapping the accepted socket.
IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state) Begins asynchronous send. Throws if socket is null, callback is null, or socket is not connected.
int EndSend(IAsyncResult ar) Completes the send; returns bytes sent. Sets Sock = null on exception.
Task<int> SendAsync(byte[] sendBuffer, int bufferStartOffset, int bufferSizeToSend) Task-based async wrapper over BeginSend/EndSend.
IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state) Begins asynchronous receive. Throws if socket is null or callback is null.
int EndReceive(IAsyncResult ar) Completes the receive; returns bytes received.
void Bind(int port) Binds socket to local endpoint resolved via DNS.
void Listen(int backlog) Starts listening for incoming connections.
void Dispose() Disposes the socket and resources.

RESTConnection (DTS.DASLib.Connection)

Properties

Signature Description
bool IConnection.IsSoftDisconnected Always returns false.
SocketFlags IConnection.Flags { get; set; } Stored value, defaults to SocketFlags.None.
string IConnection.ConnectString Returns the stored _ConnectString.
bool IConnection.Connected Returns _bConnected (set by BeginConnect/BeginDisconnect).

Events

Signature Description
event EventHandler OnDisconnected Defined but never invoked in the source.

Methods

Signature Description
void IConnection.Create(string connectString) Stores connectString in _ConnectString.
void IConnection.Create(string connectString, string hostIPAddress) Stores both parameters in private fields.
IAsyncResult IConnection.BeginConnect(AsyncCallback callback, object callbackObject) Sets _bConnected = true; returns an already-completed AsyncNoResult.
void IConnection.EndConnect(IAsyncResult ar) No-op.
IAsyncResult IConnection.BeginDisconnect(bool reuseSocket, AsyncCallback callback, object state) Sets _bConnected = false; returns an already-completed AsyncNoResult.
void IConnection.EndDisconnect(IAsyncResult asyncResult) No-op.
IAsyncResult IConnection.BeginAccept(AsyncCallback callback, object state) Returns an already-completed AsyncNoResult.
IConnection IConnection.EndAccept(IAsyncResult asyncResult) Returns this.
IAsyncResult IConnection.BeginSend(byte[] sendBuffer, int bufferStartOffset, int bufferSizeToSend, AsyncCallback callback, object callbackObject) Returns an already-completed AsyncNoResult.
int IConnection.EndSend(IAsyncResult ar) Returns 0.
IAsyncResult IConnection.BeginReceive(byte[] receiveBuffer, int bufferStartOffset, int maxSizeToReceive, AsyncCallback callback, object callbackObject) Returns an already-completed AsyncNoResult.
int IConnection.EndReceive(IAsyncResult ar) Returns 0.
Task<int> IConnection.SendAsync(byte[] sendBuffer, int bufferStartOffset, int bufferSizeToSend) Task wrapper over BeginSend/EndSend.
void IConnection.Bind(int port) No-op (commented as "not really needed").
void IConnection.Listen(int backlog) No-op.
void IConnection.KeepAliveErrorReceived() No-op.
void IConnection.SoftConnect() No-op.
void IConnection.SoftDisconnect() No-op.
string IConnection.GetConnectionData() Returns "$(_ConnectString) - $(_hostIPAddress)".
void Dispose() Standard dispose pattern; no actual resource cleanup.

Internal Class: AsyncNoResult

An IAsyncResult implementation used to represent immediately-completed operations.

Member Description
bool IsCompleted Returns true if _executionState != PENDING.
WaitHandle AsyncWaitHandle Lazily-created ManualResetEvent.
object AsyncState Returns the state object passed to constructor.
bool CompletedSynchronously Returns true if _executionState == COMPLETED_SYNC.
void SetCompleted(bool completedSync) Transitions from PENDING to COMPLETED_SYNC or COMPLETED_ASYNC; invokes callback. Throws InvalidOperationException if already completed.

3. Invariants

EthernetConnection

  • Connect string format: Must be "hostname:port" where port is a valid integer. Validated in BeginConnect.
  • Socket creation prerequisite: Sock must be created via Create() before calling BeginConnect, BeginSend, BeginReceive, BeginAccept, BeginDisconnect, Bind, or Listen. All these methods throw if Sock is null.
  • Connection state for send: BeginSend throws if Sock.Connected is false.
  • Connection state for disconnect: BeginDisconnect throws SocketException(DFConstantsAndEnums.WSAEISCONN) if Sock.Connected is false.
  • Callback requirement: BeginSend and BeginReceive throw if callback is null.
  • Soft disconnect gate: SoftDisconnect() and SoftConnect() do nothing if HardwareConstants.AllowSoftDisconnects is false.
  • Keep-alive configuration: All sockets created via CreateSock have keep-alive enabled with values from DFConstantsAndEnums.LocalKeepAliveTimeOutMS and DFConstantsAndEnums.LocalKeepAliveRetryIntervalMS.

RESTConnection

  • No actual I/O: All Begin* methods return immediately with CompletedSynchronously = true.
  • Send/Receive return zero: EndSend and EndReceive always return 0.
  • IsSoftDisconnected: Always false.
  • AsyncNoResult state machine: SetCompleted can only be called once; subsequent calls throw InvalidOperationException.

4. Dependencies

EthernetConnection depends on:

  • DTS.Common.Interface.Connection.IConnection - Interface being implemented.
  • DTS.Common.Utilities.Logging.APILogger - Used for logging throughout.
  • DTS.Common.DASResource.DFConstantsAndEnums - Provides SendBufferSizeBytes, ReceiveBufferSizeBytes, LocalKeepAliveTimeOutMS, LocalKeepAliveRetryIntervalMS, WSAEISCONN.
  • DTS.Common.Enums.DASFactory - Namespace imported but no direct usage visible in source.
  • DTS.Common.Enums.Hardware.HardwareConstants.AllowSoftDisconnects - Controls soft disconnect behavior.
  • System.Net.Sockets.Socket - Core socket functionality.
  • System.Net.Dns, System.Net.IPEndPoint, System.Net.IPAddress - Network addressing.

RESTConnection depends on:

  • DTS.Common.Interface.Connection.IConnection - Interface being implemented.
  • DTS.Common.Utilities.Logging - Namespace imported but no direct usage visible in source.
  • System.Net.Sockets.SocketFlags - Used for the Flags property.
  • System.Threading - ManualResetEvent, Interlocked, Thread.VolatileRead.

What depends on these modules:

  • Unclear from source alone. Both implement IConnection, suggesting consumers depend on that interface rather than concrete types directly.

5. Gotchas

EthernetConnection

  1. Dead code in Create(string connectString): The single-parameter overload contains a commented-out recursive call with the comment "this is recursive!". The method body is effectively empty and does nothing.

  2. Counterintuitive error code in BeginDisconnect: When the socket is not connected, BeginDisconnect throws SocketException(WSAEISCONN). The constant name suggests "is connected" which is the opposite of the actual condition being checked.

  3. SoftConnect has hardcoded command port logic: When RequiresKeepAliveReset is true, SoftConnect() connects to port 8200 and sends <60,5,4> before connecting to the actual target port. This appears to be device-specific protocol behavior embedded in the connection class.

  4. Socket is public and mutable: The Sock field is public, allowing external code to modify or replace it, potentially bypassing the class's invariants.

  5. EndSend nullifies socket on exception: If EndSend throws, it sets Sock = null before re-throwing. This is not documented and could surprise callers.

  6. Thread.Sleep in SoftConnect/SoftDisconnect: Both methods use Thread.Sleep (50ms and 100ms/1000ms respectively), which blocks the calling thread.

RESTConnection

  1. No-op implementations: Most methods do nothing or return immediately. This is by design but could cause confusion if developers expect actual network behavior.

  2. OnDisconnected never raised: The event is declared but never invoked anywhere in the class.

  3. Namespace mismatch: The file path suggests DTS.Common.IConnection but the namespace is DTS.DASLib.Connection. This may indicate a historical refactoring or organizational inconsistency.

  4. Unused imports: System.CodeDom, System.Collections.Specialized, System.Runtime.Remoting.Messaging are imported but not used in the source.