Dreamine.Communication.Wpf
Dreamine.Communication.Wpf는 Dreamine Communication 계열 패키지의 일부입니다.
이 패키지는 Dreamine Communication을 위한 WPF 전용 모니터링 및 진단 컴포넌트를 제공합니다.
Core 통신 패키지들이 UI에 종속되지 않도록 기본 Dreamine.Communication.FullKit 패키지와 분리되어 있습니다.
설명
Dreamine Communication을 위한 WPF 모니터링 및 진단 컴포넌트입니다.
주요 기능
- WPF 통신 모니터
UserControl - 통신 채널 상태 표시
- 메시지 송신/수신 로그 표시
- 연결 상태 시각 표시
- 기본 진단 ViewModel 기반 구조
주요 구성 요소
Views
CommunicationMonitorView
ViewModels
CommunicationMonitorViewModel
Models
CommunicationChannelViewItemCommunicationMessageLogItem
Converters
ConnectionStateBrushConverter
Commands
DelegateCommand
사용 방법
모니터는 세 부분으로 구성됩니다.
| 구성 | 역할 |
|---|---|
CommunicationMonitorViewModel |
채널과 로그를 보관합니다. 애플리케이션 코드는 AddChannel, UpdateChannelState, AddSendLog, AddReceiveLog를 호출합니다. |
CommunicationMonitorView |
채널 상태와 송수신 로그를 렌더링하는 WPF UserControl입니다. DataContext에 CommunicationMonitorViewModel을 바인딩합니다. |
ConnectionStateBrushConverter |
채널 상태 표시용 ConnectionState → Brush 변환기입니다. View가 내부적으로 사용합니다. |
View에 모니터 배치
<UserControl x:Class="MyApp.Pages.CommunicationPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:commViews="clr-namespace:Dreamine.Communication.Wpf.Views;assembly=Dreamine.Communication.Wpf">
<Grid>
<commViews:CommunicationMonitorView
DataContext="{Binding Monitor}" />
</Grid>
</UserControl>
호스트 ViewModel은 CommunicationMonitorViewModel 인스턴스를 Monitor 속성으로 노출합니다.
Transport와 연동
using Dreamine.Communication.Abstractions.Enums;
using Dreamine.Communication.Abstractions.Models;
using Dreamine.Communication.Sockets.Clients;
using Dreamine.Communication.Sockets.Options;
using Dreamine.Communication.Wpf.ViewModels;
public sealed class CommunicationContext
{
private readonly TcpClientTransport _client;
public CommunicationMonitorViewModel Monitor { get; } = new();
public CommunicationContext()
{
const string channelName = "TCP-Client";
Monitor.AddChannel(
channelName,
TransportKind.Tcp,
"TCP client to 127.0.0.1:15001.");
_client = new TcpClientTransport(
new TcpClientTransportOptions
{
Host = "127.0.0.1",
Port = 15001
});
_client.MessageReceived += (_, message) =>
{
Monitor.AddReceiveLog(channelName, TransportKind.Tcp, message);
};
}
public async Task ConnectAsync()
{
const string channelName = "TCP-Client";
await _client.ConnectAsync();
Monitor.UpdateChannelState(channelName, ConnectionState.Connected);
}
public async Task SendAsync(MessageEnvelope message)
{
const string channelName = "TCP-Client";
Monitor.AddSendLog(channelName, TransportKind.Tcp, message);
await _client.SendAsync(message);
}
}
스레드 주의사항
CommunicationMonitorViewModel은 내부적으로 ObservableCollection<T>을 사용합니다. Transport 콜백은 보통 백그라운드 스레드에서 실행되므로, MessageReceived 이벤트 핸들러 같은 곳에서 AddReceiveLog, AddSendLog, UpdateChannelState를 호출할 때는 UI 스레드로 마샬링이 필요합니다 (예: Application.Current.Dispatcher.Invoke).
설계 원칙
- WPF UI 컴포넌트를 Core 통신 로직과 분리합니다.
- Sockets, Serial, RabbitMQ 같은 구체 전송 패키지를 직접 참조하지 않습니다.
Dreamine.Communication.Abstractions와Dreamine.Communication.Core에만 의존합니다.- 단방향 의존성 흐름을 유지합니다.
- 이 패키지는 모니터링 및 진단 UI에만 집중합니다.
패키지 역할
Dreamine.Communication.Abstractions
↑
Dreamine.Communication.Core
↑
Dreamine.Communication.Wpf
의존성
Dreamine.Communication.AbstractionsDreamine.Communication.Core
대상 프레임워크
net8.0-windows
참고
이 패키지는 net8.0-windows를 대상으로 하며 WPF를 사용합니다.
기본 Dreamine.Communication.FullKit 패키지에는 의도적으로 포함하지 않습니다.
관련 패키지
Dreamine.Communication.AbstractionsDreamine.Communication.CoreDreamine.Communication.SocketsDreamine.Communication.SerialDreamine.Communication.RabbitMQDreamine.Communication.FullKit
라이선스
이 프로젝트는 MIT 라이선스를 따릅니다.
구조 다이어그램
classDiagram
class ConnectionStatusIndicator {
+bool IsConnected
+string StatusText
+IRelayCommand ConnectCommand
+IRelayCommand DisconnectCommand
}
class MessageLogView {
+ObservableCollection~string~ Messages
+bool AutoScroll
+int MaxMessages
+Clear() void
}
class NetworkMonitorViewModel {
+IConnectionClient Client
+bool IsConnected
+double BytesSentPerSec
+double BytesReceivedPerSec
+DateTime LastActivity
+StartMonitoring() void
}
class SerialPortSelectorView {
+IEnumerable~string~ AvailablePorts
+string SelectedPort
+int SelectedBaudRate
+IRelayCommand RefreshCommand
}
UserControl <|-- ConnectionStatusIndicator
UserControl <|-- MessageLogView
UserControl <|-- SerialPortSelectorView
NetworkMonitorViewModel --> ConnectionStatusIndicatorAPI 문서
타입
\if KO WPF 화면에 표시할 통신 채널의 이름, 전송 방식, 상태 및 설명을 보관합니다. \endif \if EN Stores the name, transport kind, state, and description of a communication channel for WPF display. \endif
\if KO WPF 화면에 표시할 통신 메시지 로그의 메타데이터와 페이로드 미리보기를 보관합니다. \endif \if EN Stores communication-message log metadata and a payload preview for WPF display. \endif
\if KO Dreamine 통신 채널 상태와 메시지 로그를 표시하는 WPF 사용자 컨트롤입니다. \endif \if EN Provides a WPF user control that displays Dreamine communication channel states and message logs. \endif
\if KO 통신 채널 상태와 송수신 메시지 로그를 WPF 바인딩에 제공하는 ViewModel입니다. \endif \if EN Provides communication channel states and sent/received message logs for WPF binding. \endif
\if KO 통신 연결 상태를 WPF 상태 표시 색상 Brush로 변환합니다. \endif \if EN Converts communication connection states into WPF status brushes. \endif
\if KO 실행 및 선택적 실행 가능 조건 대리자로 구성되는 WPF 명령입니다. \endif \if EN Provides a WPF command backed by execution and optional can-execute delegates. \endif
CommunicationChannelViewItem
\if KO 값이 실제로 변경된 경우에만 저장소를 갱신하고 속성 변경 이벤트를 발생시킵니다. \endif \if EN Updates storage and raises property change only when the value actually changes. \endif
storage— \if KO 속성의 후방 저장소입니다. \endif \if EN The property backing storage. \endifvalue— \if KO 설정할 새 값입니다. \endif \if EN The new value to set. \endifpropertyName— \if KO 변경된 속성 이름입니다. \endif \if EN The changed property name. \endif\if KO 채널 설명을 가져오거나 설정합니다. \endif \if EN Gets or sets the channel description. \endif
\if KO 채널의 전송 방식을 가져오거나 설정합니다. \endif \if EN Gets or sets the channel transport kind. \endif
\if KO 채널 표시 이름을 가져오거나 설정합니다. \endif \if EN Gets or sets the channel display name. \endif
\if KO 채널의 현재 연결 상태를 가져오거나 설정합니다. \endif \if EN Gets or sets the current channel connection state. \endif
\if KO description 값을 보관합니다. \endif \if EN Stores the description value. \endif
\if KO kind 값을 보관합니다. \endif \if EN Stores the kind value. \endif
\if KO name 값을 보관합니다. \endif \if EN Stores the name value. \endif
\if KO state 값을 보관합니다. \endif \if EN Stores the state value. \endif
\if KO 바인딩된 속성 값이 변경될 때 발생합니다. \endif \if EN Occurs when a bound property value changes. \endif
CommunicationMessageLogItem
\if KO 메시지를 송수신한 채널 이름을 가져옵니다. \endif \if EN Gets the name of the channel that sent or received the message. \endif
\if KO 로그가 생성된 로컬 시각을 가져옵니다. \endif \if EN Gets the local time at which the log was created. \endif
\if KO 송신 또는 수신 방향 표시를 가져옵니다. \endif \if EN Gets the send-or-receive direction label. \endif
\if KO 메시지의 전송 방식을 가져옵니다. \endif \if EN Gets the message transport kind. \endif
\if KO 메시지의 논리적 이름을 가져옵니다. \endif \if EN Gets the logical message name. \endif
\if KO 페이로드 크기(바이트)를 가져옵니다. \endif \if EN Gets the payload size in bytes. \endif
\if KO 화면 표시용 페이로드 미리보기를 가져옵니다. \endif \if EN Gets the payload preview for display. \endif
\if KO 메시지 라우트를 가져옵니다. \endif \if EN Gets the message route. \endif
CommunicationMonitorView
\if KO XAML 구성 요소를 로드하여 통신 모니터 View를 초기화합니다. \endif \if EN Initializes the communication monitor view by loading its XAML components. \endif
InitializeComponent
CommunicationMonitorViewModel
\if KO 로그 삭제 명령과 빈 채널·로그 컬렉션으로 ViewModel을 초기화합니다. \endif \if EN Initializes the view model with a clear-logs command and empty channel and log collections. \endif
\if KO 같은 이름이 없는 경우 새 통신 채널을 추가합니다. \endif \if EN Adds a communication channel when no channel with the same name exists. \endif
name— \if KO 고유한 채널 이름입니다. \endif \if EN The unique channel name. \endifkind— \if KO 채널 전송 방식입니다. \endif \if EN The channel transport kind. \endifdescription— \if KO 선택적 채널 설명입니다. \endif \if EN The optional channel description. \endif\if KO 메시지 메타데이터와 UTF-8 미리보기를 생성해 로그 컬렉션 앞에 삽입합니다. \endif \if EN Creates message metadata and a UTF-8 preview and inserts the log at the front. \endif
channelName— \if KO 채널 이름입니다. \endif \if EN The channel name. \endifkind— \if KO 전송 방식입니다. \endif \if EN The transport kind. \endifdirection— \if KO 송수신 방향 표시입니다. \endif \if EN The send-or-receive direction label. \endifmessage— \if KO 로그로 변환할 메시지입니다. \endif \if EN The message to convert into a log entry. \endif\if KO 수신 방향의 메시지 로그를 컬렉션 앞에 추가합니다. \endif \if EN Adds a received-message log to the front of the collection. \endif
channelName— \if KO 수신 채널 이름입니다. \endif \if EN The receiving channel name. \endifkind— \if KO 전송 방식입니다. \endif \if EN The transport kind. \endifmessage— \if KO 기록할 수신 메시지입니다. \endif \if EN The received message to log. \endif\if KO 송신 방향의 메시지 로그를 컬렉션 앞에 추가합니다. \endif \if EN Adds a sent-message log to the front of the collection. \endif
channelName— \if KO 송신 채널 이름입니다. \endif \if EN The sending channel name. \endifkind— \if KO 전송 방식입니다. \endif \if EN The transport kind. \endifmessage— \if KO 기록할 송신 메시지입니다. \endif \if EN The sent message to log. \endif\if KO 메시지 로그 컬렉션의 모든 항목을 삭제합니다. \endif \if EN Removes every entry from the message-log collection. \endif
\if KO UTF-8 페이로드를 최대 120자로 잘라 화면 표시용 미리보기를 생성합니다. \endif \if EN Creates a display preview by decoding UTF-8 payload and truncating it to 120 characters. \endif
payload— \if KO 미리보기로 변환할 바이트입니다. \endif \if EN The bytes to convert into a preview. \endif반환: \if KO 비어 있거나 잘린 UTF-8 문자열입니다. \endif \if EN An empty or truncated UTF-8 string. \endif
\if KO 값이 변경된 경우에만 저장소를 갱신하고 속성 변경 이벤트를 발생시킵니다. \endif \if EN Updates storage and raises property change only when the value changes. \endif
storage— \if KO 후방 저장소입니다. \endif \if EN The backing storage. \endifvalue— \if KO 새 값입니다. \endif \if EN The new value. \endifpropertyName— \if KO 변경된 속성 이름입니다. \endif \if EN The changed property name. \endif\if KO 지정한 이름의 채널이 있으면 설명을 갱신합니다. \endif \if EN Updates the description when a channel with the specified name exists. \endif
name— \if KO 찾을 채널 이름입니다. \endif \if EN The channel name to find. \endifdescription— \if KO 설정할 설명이며 이면 빈 문자열입니다. \endif \if EN The description to set; becomes an empty string. \endif\if KO 지정한 이름의 채널이 있으면 연결 상태를 갱신합니다. \endif \if EN Updates the connection state when a channel with the specified name exists. \endif
name— \if KO 찾을 채널 이름입니다. \endif \if EN The channel name to find. \endifstate— \if KO 설정할 연결 상태입니다. \endif \if EN The connection state to set. \endif\if KO 화면에 표시할 통신 채널 컬렉션을 가져옵니다. \endif \if EN Gets the communication-channel collection displayed by the view. \endif
\if KO 모든 메시지 로그를 삭제하는 명령을 가져옵니다. \endif \if EN Gets the command that clears all message logs. \endif
\if KO 최신 항목이 앞에 배치되는 메시지 로그 컬렉션을 가져옵니다. \endif \if EN Gets the message-log collection with newest entries first. \endif
\if KO 현재 선택된 통신 채널을 가져오거나 설정합니다. \endif \if EN Gets or sets the currently selected communication channel. \endif
\if KO selected Channel 값을 보관합니다. \endif \if EN Stores the selected channel value. \endif
\if KO 바인딩된 속성 값이 변경될 때 발생합니다. \endif \if EN Occurs when a bound property value changes. \endif
ConnectionStateBrushConverter
\if KO 연결 상태를 의미에 맞는 WPF Brush로 변환합니다. \endif \if EN Converts a connection state to a semantically appropriate WPF brush. \endif
value— \if KO 변환할 연결 상태 값입니다. \endif \if EN The connection-state value to convert. \endiftargetType— \if KO 바인딩 대상 형식이며 이 구현에서는 사용하지 않습니다. \endif \if EN The binding target type; it is not used. \endifparameter— \if KO 선택적 변환 매개변수이며 사용하지 않습니다. \endif \if EN The optional converter parameter; it is not used. \endifculture— \if KO 변환 문화권이며 사용하지 않습니다. \endif \if EN The conversion culture; it is not used. \endif반환: \if KO 상태 표시용 Brush이며, 알 수 없는 값은 회색입니다. \endif \if EN A status brush; unknown values produce gray. \endif
\if KO 역변환을 지원하지 않고 바인딩 무시 결과를 반환합니다. \endif \if EN Does not support reverse conversion and returns the binding no-op result. \endif
value— \if KO 역변환 입력이며 사용하지 않습니다. \endif \if EN The reverse-conversion input; it is not used. \endiftargetType— \if KO 대상 형식이며 사용하지 않습니다. \endif \if EN The target type; it is not used. \endifparameter— \if KO 변환 매개변수이며 사용하지 않습니다. \endif \if EN The converter parameter; it is not used. \endifculture— \if KO 문화권이며 사용하지 않습니다. \endif \if EN The culture; it is not used. \endif반환: \if KO 입니다. \endif \if EN . \endif
DelegateCommand
\if KO 실행 대리자와 선택적 실행 가능 조건으로 명령을 초기화합니다. \endif \if EN Initializes the command with an execution delegate and optional can-execute predicate. \endif
execute— \if KO 명령 호출 시 실행할 동작입니다. \endif \if EN The action invoked when the command executes. \endifcanExecute— \if KO 현재 매개변수로 실행 가능한지 판단할 조건이며, 이면 항상 가능합니다. \endif \if EN The predicate that determines whether the command can execute; always permits execution. \endif\if KO 선택적 조건 대리자를 사용해 현재 명령 실행 가능 여부를 확인합니다. \endif \if EN Determines whether the command can execute by evaluating the optional predicate. \endif
parameter— \if KO 조건에 전달할 명령 매개변수입니다. \endif \if EN The command parameter passed to the predicate. \endif반환: \if KO 실행 가능하면 입니다. \endif \if EN when the command can execute. \endif
\if KO 구성된 실행 대리자를 호출합니다. \endif \if EN Invokes the configured execution delegate. \endif
parameter— \if KO 실행 대리자에 전달할 명령 매개변수입니다. \endif \if EN The command parameter passed to the execution delegate. \endif\if KO 명령 소비자가 실행 가능 상태를 다시 평가하도록 이벤트를 발생시킵니다. \endif \if EN Raises the event so command consumers reevaluate can-execute state. \endif
\if KO can Execute 값을 보관합니다. \endif \if EN Stores the can execute value. \endif
\if KO execute 값을 보관합니다. \endif \if EN Stores the execute value. \endif
\if KO 명령 실행 가능 상태를 다시 평가해야 할 때 발생합니다. \endif \if EN Occurs when the command's ability to execute should be reevaluated. \endif