|
Dreamine.Communication.Sockets 1.0.2
Dreamine.Communication.Sockets 통신 기능과 관련 API를 제공합니다.
|
Dreamine.Communication.Sockets는 Dreamine Communication 계열 패키지의 일부입니다.
이 패키지는 TCP 및 UDP 소켓 기반 전송 구현체를 제공하며, 소켓 연결 관련 책임을 애플리케이션 계층 및 다른 전송 패키지와 분리합니다.
➡️ English Version
Dreamine Communication을 위한 TCP/UDP 소켓 전송 패키지입니다. TcpClientTransport, TcpServerTransport, UdpTransport 구현체를 제공하며, 선택된 프로토콜 어댑터와 (TCP의 경우) 프레임 코덱을 통해 MessageEnvelope를 송수신합니다.
Sockets는 구체적인 TCP 통신 경계만 담당합니다.
이 패키지는 UI 상태, 애플리케이션 명령 규칙, 비즈니스 라우팅 정책, Serial Port 로직, RabbitMQ 연결 로직, WPF 전용 로직을 소유하면 안 됩니다.
| 타입 | 역할 |
|---|---|
| TcpClientTransport | TCP Client 연결을 위한 IMessageTransport 구현체입니다. |
| TcpServerTransport | TCP Server Listener 및 연결된 Client 처리를 위한 IMessageTransport 구현체입니다. |
| UdpTransport | UDP Datagram Peer-to-Peer 통신을 위한 IMessageTransport 구현체입니다. |
| TcpClientTransportOptions | TCP Client 연결 설정 모델입니다. |
| TcpServerTransportOptions | TCP Server Listener 설정 모델입니다. |
| UdpTransportOptions | UDP Local/Remote 엔드포인트 설정 모델입니다. |
| SocketCommunicationException | 소켓 통신 전용 예외 타입입니다. |
TcpClientTransport는 공통 IMessageTransport 계약을 구현합니다.
기본 생성자 동작:
이 기본값은 Dreamine 간 TCP 통신에 적합합니다. 외부 툴, TCP 터미널, PLC Gateway 소프트웨어, 검사 장비, Raw 문자열 테스트에는 프로토콜 어댑터와 프레임 코덱을 명시적으로 전달해야 합니다.
Raw Text Client 예시:
TcpServerTransport는 공통 IMessageTransport 계약을 구현합니다.
기본 생성자 동작:
Server는 TcpListener를 시작하고, 여러 TCP Client를 Accept하며, Client별 수신 루프를 생성합니다. 송신 메시지는 현재 연결된 모든 Client에게 Broadcast됩니다.
Raw Text Server 예시:
| 옵션 | 기본값 | 의미 |
|---|---|---|
| Host | 127.0.0.1 | 연결할 TCP Server Host입니다. |
| Port | 0 | 연결할 TCP Server Port입니다. 연결 전 1~65535 범위여야 합니다. |
| ReceiveBufferSize | 8192 | TCP 수신 버퍼 크기입니다. |
| SendBufferSize | 8192 | TCP 송신 버퍼 크기입니다. |
| ConnectTimeoutMs | 5000 | TCP 연결 타임아웃(ms)입니다. |
| 옵션 | 기본값 | 의미 |
|---|---|---|
| Host | 0.0.0.0 | 바인딩할 IP 주소입니다. 0.0.0.0은 모든 네트워크 인터페이스를 의미합니다. |
| Port | 5000 | TCP 수신 대기 Port입니다. 1~65535 범위여야 합니다. |
| Backlog | 100 | TCP Listener backlog 값입니다. |
| ReceiveBufferSize | 8192 | Accept된 Client에 적용할 수신 버퍼 크기입니다. |
| SendBufferSize | 8192 | Accept된 Client에 적용할 송신 버퍼 크기입니다. |
Server Host 파싱은 현재 다음 값을 지원합니다.
외부 공개 서비스는 0.0.0.0 또는 특정 로컬 인터페이스 IP에 바인딩합니다. 로컬 테스트는 127.0.0.1을 사용합니다.
TCP는 스트림 기반입니다. 애플리케이션 메시지 경계를 보존하지 않습니다. 그래서 메시지 의미와 메시지 경계 처리를 의도적으로 분리합니다.
| 책임 | 타입 |
|---|---|
| Byte와 MessageEnvelope 상호 변환 | IMessageProtocolAdapter |
| 스트림에서 메시지 경계 판단 | IMessageFrameCodec |
| TCP Socket 열기, 닫기, 송신, 수신 | TcpClientTransport / TcpServerTransport |
| 시나리오 | Protocol Adapter | Frame Codec |
|---|---|---|
| Dreamine 간 TCP 통신 | DreamineEnvelopeProtocolAdapter | LengthPrefixedMessageFrameCodec |
| 각 메시지가 CRLF 또는 LF로 끝나는 Text Protocol | PlainTextProtocolAdapter | DelimiterMessageFrameCodec |
| 단순 TCP 테스트 툴이 구분자 없이 Raw Text 전송 | PlainTextProtocolAdapter | RawAvailableMessageFrameCodec |
| 줄 끝이 있는 JSON Text Protocol | RawJsonProtocolAdapter | DelimiterMessageFrameCodec |
| Custom Binary TCP Protocol | Custom Protocol Adapter | Custom Frame Codec |
RawAvailableMessageFrameCodec은 이 패키지가 아니라 Dreamine.Communication.Core에 정의됩니다. 그래도 TcpClientTransport와 TcpServerTransport는 모든 IMessageFrameCodec을 받을 수 있으므로 그대로 사용할 수 있습니다.
이 모드는 TCP 툴 또는 외부 장비가 다음처럼 단순 값을 보낼 때 유용합니다.
위 값에 다음 항목이 없어도 수신 처리가 가능합니다.
설정 예시:
이 조합을 사용하면 Hercules 같은 수동 TCP 테스트 툴에서 단순 문자열을 보내도 MessageReceived가 발생합니다.
TCP는 Byte Stream입니다. RawAvailableMessageFrameCodec은 한 번의 Stream Read에서 반환된 Byte를 하나의 메시지로 처리합니다.
수동 테스트에는 편하지만, 엄격한 메시지 경계 규칙은 아닙니다. 타이밍과 버퍼 상태에 따라 여러 번의 송신이 합쳐지거나, 한 번의 송신이 쪼개질 수 있습니다.
가능한 수신 결과 예시:
또는:
운영용 TCP Protocol에는 아래 방식 중 하나를 권장합니다.
RawAvailableMessageFrameCodec은 호환성, 디버깅, 수동 테스트, 명확한 프레이밍 규칙이 없는 툴 대응용으로 사용하는 것이 맞습니다.
두 Socket Transport는 공통 ConnectionState enum을 통해 상태를 제공합니다.
| 상태 | TcpClientTransport | TcpServerTransport |
|---|---|---|
| Disconnected | Client 연결이 끊긴 상태입니다. | Listener가 중지된 상태입니다. |
| Connecting | Client 연결 중입니다. | Server Listener 시작 중입니다. |
| Connected | Client가 연결되었고 수신 루프가 동작 중입니다. | Listener와 Accept Loop가 동작 중입니다. |
| Disconnecting | Client 연결 종료 중입니다. | Server 중지 및 Client 정리 중입니다. |
| Faulted | 연결 또는 수신 루프 오류가 발생했습니다. | Listener, Accept Loop 또는 Socket 작업 오류가 발생했습니다. |
TcpClientTransport.SendAsync는 연결된 Server로 인코딩된 Frame 하나를 전송합니다.
TcpServerTransport.SendAsync는 현재 연결된 모든 Client에게 인코딩된 Frame 하나를 Broadcast합니다. 송신 중 Client 연결이 끊겼거나 오류가 발생하면 해당 Client는 Server 연결 목록에서 제거됩니다.
Transport는 Socket을 열기 전에 Options를 검증합니다. 잘못된 설정은 조기에 실패합니다.
예시:
런타임 Socket 오류는 Transport 상태를 Faulted로 변경할 수 있습니다. 애플리케이션 레벨 복구는 Transport를 Dispose 또는 Disconnect한 뒤, Socket 조건을 수정하고 다시 연결하거나 Server를 재시작하는 방식으로 처리합니다.
Dreamine.Communication.Sockets는 UDP Peer 방식 Transport도 제공합니다. UDP는 Datagram 기반이므로 LengthPrefixedMessageFrameCodec, DelimiterMessageFrameCodec, RawAvailableMessageFrameCodec 같은 Stream Frame Codec을 사용하지 않습니다.
권장 UDP 구조는 다음과 같습니다.
샘플은 로컬 Loopback 테스트를 위해 두 개의 UDP Peer를 사용합니다.
Dreamine 내부 Peer 간 테스트는 Start Loopback을 사용합니다. Hercules 같은 외부 UDP 툴과 테스트할 때는 로컬 포트 충돌을 피하기 위해 Peer 하나만 연결합니다.
Hercules 테스트 예시는 다음과 같습니다.
이 경우 Dreamine 샘플에서는 Connect A 후 Send Peer A를 누릅니다.
Loopback 로컬 테스트는 LocalPort와 RemotePort를 서로 맞바꾼 두 번째 UdpTransport(Peer B)를 함께 생성하여 사용합니다.
TCP와 UDP는 UTF-8을 사용하지 않는 외부 툴 또는 장비와 통신할 수 있습니다. 따라서 샘플에서는 외부 Text 계열 모드에 대해 Encoding 선택 기능을 제공합니다.
| Encoding | 권장 용도 |
|---|---|
| UTF-8 | 현대 시스템 및 Dreamine ↔ Dreamine 통신 기본값 |
| CP949 | 레거시 한글 Windows 툴, Hercules 한글 테스트, 오래된 장비 프로토콜 |
Encoding 선택은 Protocol Adapter 경계에서 적용됩니다. TcpClientTransport, TcpServerTransport, UdpTransport의 책임이 아닙니다.
이 프로젝트는 MIT 라이선스를 따릅니다.