🔎 유용한 정보
1. 강의 개요
이번 강의에서는 WebSocket을 활용하여 실시간 양방향 통신 애플리케이션을 제작합니다.
WebSocket은 클라이언트와 서버 간에 지속적인 연결을 유지하면서 데이터를 실시간으로 주고받는 프로토콜입니다.
이를 통해 채팅 애플리케이션과 같은 실시간 데이터를 다루는 프로그램을 구현할 수 있습니다.
2. 학습 목표
- WebSocket 클라이언트를 사용해 서버와 실시간 통신 구현
- 서버에서 전송된 데이터를 실시간으로 수신 및 처리
- 클라이언트가 서버로 데이터를 전송하는 기능 구현
- UI를 활용해 메시지를 송수신하는 애플리케이션 제작
3. 기능 요구사항
필수 기능
1️⃣ WebSocket 연결 관리:
- 서버에 연결 및 연결 종료
2️⃣ 데이터 송신:
- 사용자가 입력한 메시지를 서버로 전송
3️⃣ 데이터 수신:
- 서버에서 수신된 메시지를 UI에 실시간으로 표시
4️⃣ UI 응답성 유지:
- WebSocket 작업 중에도 다른 UI 작업 가능
4. 실습: WebSocket 클라이언트 애플리케이션 제작
1️⃣ 폼 구성
- 폼(Form) 이름: Form1
- 컨트롤 배치
컨트롤 타입 이름 위치 크기
TextBox | txtServerUrl | 폼 상단 왼쪽 | (300 x 30) |
Button | btnConnect | 폼 상단 오른쪽 | (100 x 30) |
ListBox | lstMessages | 폼 중앙 | (400 x 300) |
TextBox | txtMessage | 폼 하단 왼쪽 | (300 x 30) |
Button | btnSend | 폼 하단 오른쪽 | (100 x 30) |
📌 폼 디자인 예시:
--------------------------------------------------
| [Server URL: TextBox] [Connect 버튼] |
--------------------------------------------------
| [ListBox - 수신 메시지 표시] |
--------------------------------------------------
| [Message: TextBox] [Send 버튼] |
--------------------------------------------------
2️⃣ 코드 작성
(1) WebSocket 클라이언트 구현
using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp_WebSocket
{
public partial class Form1 : Form
{
private ClientWebSocket _webSocket;
private CancellationTokenSource _cancellationTokenSource;
public Form1()
{
InitializeComponent();
}
// WebSocket 서버 연결
private async void btnConnect_Click(object sender, EventArgs e)
{
string serverUrl = txtServerUrl.Text.Trim();
if (string.IsNullOrEmpty(serverUrl))
{
MessageBox.Show("서버 URL을 입력하세요.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_webSocket = new ClientWebSocket();
_cancellationTokenSource = new CancellationTokenSource();
try
{
await _webSocket.ConnectAsync(new Uri(serverUrl), _cancellationTokenSource.Token);
lstMessages.Items.Add("서버에 연결되었습니다.");
// 서버로부터 메시지 수신
_ = Task.Run(() => ReceiveMessagesAsync(_cancellationTokenSource.Token));
}
catch (Exception ex)
{
MessageBox.Show($"연결 실패: {ex.Message}", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// WebSocket 메시지 수신
private async Task ReceiveMessagesAsync(CancellationToken cancellationToken)
{
var buffer = new byte[1024];
try
{
while (_webSocket.State == WebSocketState.Open)
{
var result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken);
if (result.MessageType == WebSocketMessageType.Close)
{
lstMessages.Invoke(new Action(() => lstMessages.Items.Add("서버가 연결을 종료했습니다.")));
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationToken);
break;
}
var message = Encoding.UTF8.GetString(buffer, 0, result.Count);
lstMessages.Invoke(new Action(() => lstMessages.Items.Add($"서버: {message}")));
}
}
catch (Exception ex)
{
lstMessages.Invoke(new Action(() => lstMessages.Items.Add($"수신 오류: {ex.Message}")));
}
}
}
}
(2) WebSocket 메시지 송신 구현
// WebSocket 메시지 송신
private async void btnSend_Click(object sender, EventArgs e)
{
string message = txtMessage.Text.Trim();
if (string.IsNullOrEmpty(message))
{
MessageBox.Show("보낼 메시지를 입력하세요.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (_webSocket == null || _webSocket.State != WebSocketState.Open)
{
MessageBox.Show("서버와 연결되지 않았습니다.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
var messageBytes = Encoding.UTF8.GetBytes(message);
try
{
await _webSocket.SendAsync(new ArraySegment<byte>(messageBytes), WebSocketMessageType.Text, true, CancellationToken.None);
lstMessages.Items.Add($"클라이언트: {message}");
txtMessage.Clear();
}
catch (Exception ex)
{
MessageBox.Show($"메시지 전송 실패: {ex.Message}", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
(3) Designer 코드
private void InitializeComponent()
{
this.txtServerUrl = new TextBox();
this.btnConnect = new Button();
this.lstMessages = new ListBox();
this.txtMessage = new TextBox();
this.btnSend = new Button();
// Server URL TextBox 설정
this.txtServerUrl.Location = new System.Drawing.Point(10, 10);
this.txtServerUrl.Size = new System.Drawing.Size(300, 30);
// Connect Button 설정
this.btnConnect.Location = new System.Drawing.Point(320, 10);
this.btnConnect.Size = new System.Drawing.Size(100, 30);
this.btnConnect.Text = "Connect";
this.btnConnect.Click += new EventHandler(this.btnConnect_Click);
// ListBox 설정
this.lstMessages.Location = new System.Drawing.Point(10, 50);
this.lstMessages.Size = new System.Drawing.Size(400, 300);
// Message TextBox 설정
this.txtMessage.Location = new System.Drawing.Point(10, 360);
this.txtMessage.Size = new System.Drawing.Size(300, 30);
// Send Button 설정
this.btnSend.Location = new System.Drawing.Point(320, 360);
this.btnSend.Size = new System.Drawing.Size(100, 30);
this.btnSend.Text = "Send";
this.btnSend.Click += new EventHandler(this.btnSend_Click);
// Form 설정
this.ClientSize = new System.Drawing.Size(450, 400);
this.Controls.Add(this.txtServerUrl);
this.Controls.Add(this.btnConnect);
this.Controls.Add(this.lstMessages);
this.Controls.Add(this.txtMessage);
this.Controls.Add(this.btnSend);
this.Text = "WebSocket 클라이언트 애플리케이션";
}
3️⃣ 실행 결과
1️⃣ WebSocket 연결
- 서버 URL 입력 후 "Connect" 버튼 클릭 → 서버 연결 성공
2️⃣ 메시지 송신
- 텍스트 입력 후 "Send" 버튼 클릭 → 메시지가 서버로 전송
3️⃣ 메시지 수신
- 서버에서 수신된 메시지가 ListBox에 실시간으로 표시
5. 주요 개념 요약
- ClientWebSocket: 클라이언트 WebSocket 구현을 위한 클래스
- ReceiveAsync & SendAsync: WebSocket 데이터 송수신 비동기 메서드
- CancellationToken: 작업 취소 관리를 위한 토큰
- UTF-8 인코딩: 텍스트 데이터를 바이너리로 변환
📌 #CSharp #WindowsForms #WebSocket #양방향통신 #실시간통신 #ClientWebSocket
'Study > C#' 카테고리의 다른 글
C# Windows Forms 강의 73편: SignalR 클라이언트를 활용한 실시간 채팅 애플리케이션 제작 (0) | 2025.04.17 |
---|---|
C# Windows Forms 강의 73편: SignalR 클라이언트를 활용한 실시간 채팅 애플리케이션 제작 (0) | 2025.04.16 |
C# Windows Forms 강의 71편: 비동기 네트워크 통신 - HTTP 요청 및 응답 처리 (0) | 2025.04.14 |
C# Windows Forms 강의 70편: Task와 BackgroundWorker를 활용한 비동기 파일 처리 (0) | 2025.04.13 |
C# Windows Forms 강의 69편: 파일 탐색기 애플리케이션 제작 (TreeView와 ListView 활용) (0) | 2025.04.12 |
🔎 유용한 정보