WebSocket 기반 실시간 푸시 알림 시스템 - 서버와 Windows Forms 클라이언트 샘플 프로젝트
이 프로젝트는 WebSocket 기반 양방향 실시간 통신을 구현한 푸시 서버 & 클라이언트 샘플입니다.
- ✅ 실시간 양방향 통신 - WebSocket 기반 즉각적인 메시지 교환
- ✅ 명령 기반 아키텍처 - 확장 가능한 명령 핸들러 시스템
- ✅ 다중 클라이언트 관리 - 세션 기반 사용자/디바이스 관리
- ✅ 손쉬운 테스트 - Windows Forms 기반 그래픽 클라이언트 제공
- ✅ Docker/Kubernetes 지원 - 컨테이너 및 오케스트레이션 지원
- ✅ 모니터링 - Prometheus 메트릭, Health Check
- ✅ Rate Limiting - 클라이언트별 요청 제한
- ✅ Graceful Shutdown - 안전한 서버 종료
| 시나리오 | 설명 |
|---|---|
| 🛵 딜리버리 푸시 | 배달 주문 정보를 Rider 앱으로 실시간 전송 |
| 🏪 포스 연동 | POS 시스템과 외부 디바이스 간 주문 동기화 |
| 📱 모바일 알림 | 실시간 푸시 알림 서비스 백엔드 |
| 💬 채팅 시스템 | 기본 WebSocket 통신 Infrastructure |
| 기술 | 버전 | 용도 |
|---|---|---|
| .NET | 9.0 | 런타임 |
| ASP.NET Core WebSocket | Built-in | WebSocket 서버 |
| Serilog | 8.0.1 | 구조화된 로깅 |
| Swagger | 6.5.0 | API 문서화 |
| prometheus-net | 8.2.1 | 메트릭 수집 |
| 기술 | 버전 | 용도 |
|---|---|---|
| .NET | 9.0 | 런타임 |
| Windows Forms | Built-in | GUI 프레임워크 |
| System.Net.WebSockets | Built-in | WebSocket 클라이언트 |
| Newtonsoft.Json | 13.0.3 | JSON 처리 |
| 도구 | 추천 버전 |
|---|---|
| IDE | Visual Studio 2022+ |
| .NET SDK | 9.0.x |
| Docker | 24.0+ |
| kubectl | 1.28+ |
push-server-client/
│
├── 📂 ws002/ # 🔷 WebSocket Server (.NET 9)
│ ├── Program.cs # Entry point + 미들웨어
│ ├── Middleware/
│ │ ├── RateLimitingMiddleware.cs # Rate Limiting
│ │ └── JwtAuthenticationMiddleware.cs # JWT 인증
│ ├── Services/
│ │ ├── UserService.cs # 세션 관리
│ │ ├── WebSocketSession.cs # WebSocket 세션
│ │ ├── SessionStore.cs # Redis/In-Memory 세션 스토어
│ │ └── EncryptionService.cs # AES-256 암호화
│ ├── Models/ # 데이터 모델
│ ├── appsettings.json # 프로덕션 설정
│ └── ws002.csproj
│
├── 📂 Poscle35/ # 🟢 Windows Forms Client (.NET 9)
│ └── ...
│
├── 📂 k8s/ # ☸️ Kubernetes 매니페스트
│ ├── deployment.yaml # Deployment + Service + HPA
│ ├── configmap.yaml # ConfigMap
│ └── ingress.yaml # Ingress
│
├── 📂 src/
│ └── 📂 PushClient/ # 📦 NuGet SDK (.NET 9/8/Standard 2.1)
│ ├── PushClientSDK.cs # WebSocket 클라이언트 SDK
│ ├── PushClientOptions.cs # 설정 옵션
│ └── Models/ # 요청/응답 모델
│
├── 📄 Dockerfile # Docker 빌드
├── 📄 docker-compose.yml # Docker Compose
├── 📄 README.md # 이 파일
└── 📄 PROJECT_STRUCTURE.md # 상세 아키텍처 문서
- Windows/Linux/macOS
- .NET 9 SDK
- Visual Studio 2022+ (선택)
# 1. 서버 프로젝트로 이동
cd ws002
# 2. NuGet 패키지 복원
dotnet restore
# 3. 서버 실행 (포트 7000)
dotnet run서버가 실행되면 다음 로그가 표시됩니다:
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[]
User profile is available. Using 'C:\Users\...\' for temporary key storage.
info: Microsoft.AspNetCore.Server.Kestrel[]
Start listening on http://0.0.0.0:7000
=== WebSocket Push Server Starting on port 7000 ===
# Visual Studio에서 Poscle35 프로젝트 열기
# F5 또는 Ctrl+F5로 실행# NuGet 패키지 설치
dotnet add package PushServer.Clientusing PushServer.Client;
// 옵션 설정
var options = new PushClientOptions
{
ServerUrl = "ws://localhost:7000/",
DeviceId = "my-device-001",
CompanyId = "demo",
ReceiverCode = "1002",
UseJwtAuth = true,
JwtToken = "your-jwt-token"
};
// SDK 생성
using var client = new PushClientSDK(options);
// 이벤트 구독
client.ConnectionChanged += (sender, connected) =>
Console.WriteLine(connected ? "연결됨!" : "연결 해제됨!");
client.MessageReceived += (sender, message) =>
Console.WriteLine($"수신: {message}");
// 연결 및 등록
client.Connect();
client.ConnectAndRegister();
// 메시지 전송
client.SendMessage("1003", new { OrderId = 12345, Amount = 10000 });# Docker 이미지 빌드
docker build -t push-server:latest .
# 컨테이너 실행
docker run -d -p 7000:7000 --name push-server push-server:latest# 모든 서비스 실행
docker-compose up -d
# 로그 확인
docker-compose logs -f push-server
# 중지
docker-compose down| 변수 | 기본값 | 설명 |
|---|---|---|
ASPNETCORE_ENVIRONMENT |
Production | 실행 환경 |
ASPNETCORE_URLS |
http://+:7000 | 바인딩 URL |
kubectl apply -f k8s/configmap.yamlkubectl apply -f k8s/deployment.yaml
# 상태 확인
kubectl get pods -n push-system
kubectl get svc -n push-system
kubectl get hpa -n push-systemkubectl apply -f k8s/ingress.yaml# Liveness Probe
kubectl exec -it <pod-name> -n push-system -- curl http://localhost:7000/health/live
# Readiness Probe
kubectl exec -it <pod-name> -n push-system -- curl http://localhost:7000/health/ready모든 메시지는 JSON 형식으로 교환됩니다:
{
"Key": "COMMAND_NAME",
"Body": { ... }
}| 명령 | 방향 | 설명 |
|---|---|---|
CON |
C → S | 클라이언트 연결 및 세션 등록 |
connectList |
C → S | 연결된 클라이언트 목록 조회 |
MSG |
C → S | 특정 클라이언트로 메시지 전송 |
noneProc |
C → S | 기본 처리 (로깅용) |
Request:
{
"Key": "CON",
"Body": {
"deviceId": "123456",
"com_id": "demo",
"rct_code": "1002"
}
}Response:
{
"sessionID": "SR_001D7F9E"
}Request:
{
"Key": "connectList",
"Body": {
"deviceId": "123456"
}
}Response:
{
"res": "connectList",
"cnt": 2,
"arr": ["device001", "device002"]
}Request:
{
"Key": "MSG",
"Body": {
"com_id": "demo",
"rct_code": "1002",
"order_info": "{\"AO_ID\": 473449, ...}"
}
}Response:
{
"res": "MSG",
"toSess": "device_id"
}| 엔드포인트 | 설명 |
|---|---|
GET /health |
기본 health check |
GET /health/live |
Liveness probe |
GET /health/ready |
Readiness probe |
응답 예시:
{
"status": "Healthy",
"checks": [
{ "name": "self", "status": "Healthy", "description": "Server is running" },
{ "name": "websocket", "status": "Healthy", "description": "Active connections: 5" }
]
}- URL:
http://localhost:7000/swagger - Interactive API 문서 및 테스트 인터페이스 제공
- URL:
http://localhost:7000/metrics
| 메트릭 | 타입 | 설명 |
|---|---|---|
websocket_connections_active |
Gauge | 활성 연결 수 |
websocket_messages_received_total |
Counter | 수신된 메시지 수 |
websocket_messages_sent_total |
Counter | 전송된 메시지 수 |
websocket_connection_duration_seconds |
Histogram | 연결 시간 |
http_requests_total |
Counter | HTTP 요청 수 |
http_request_duration_seconds |
Histogram | 요청 처리 시간 |
scrape_configs:
- job_name: 'push-server'
static_configs:
- targets: ['push-server:7000']
metrics_path: '/metrics'| 기능 | 설명 |
|---|---|
| 🔌 WebSocket 서버 | 포트 7000에서 다중 클라이언트 연결 수락 |
| 📋 세션 관리 | deviceid, com_id, rct_code 기반 세션 추적 |
| 📨 메시지 라우팅 | com_id + rct_code로 특정 클라이언트寻址 |
| 📊 연결 목록 | 현재 연결된 모든 클라이언트 조회 |
| 📝 로깅 | Serilog + 파일 로깅 (Rolling) |
| 💓 Health Check | Kubernetes 프로브 지원 |
| 📈 메트릭 | Prometheus 메트릭 수집 |
| 🚦 Rate Limiting | IP별 요청 제한 (1000 req/min) |
| 🔄 Graceful Shutdown | 30초 타임아웃 |
| 📚 API 문서화 | Swagger/OpenAPI |
| 🔐 JWT 인증 | 토큰 기반 인증 시스템 |
| 🔒 AES-256 암호화 | 메시지 암호화 지원 |
| 🗄️ Redis 세션 | Redis/In-Memory 세션 스토어 |
| 기능 | 설명 |
|---|---|
| 📦 NuGet SDK | PushServer.Client NuGet 패키지 |
| 🔄 자동 재연결 | 지수 백오프 기반 자동 재연결 |
| 🔐 JWT 지원 | SDK에서 JWT 인증 지원 |
| 🔒 암호화 지원 | SDK에서 AES-256 암호화 지원 |
| 🖥️ GUI 인터페이스 | Windows Forms 기반 직관적인 UI |
| 🔗 연결 관리 | 원-click 연결/연결 해제 |
| 📤 요청 전송 | 미리 정의된 명령 템플릿 전송 |
| 📥 응답 표시 | 요청/응답 로그 별도 표시 |
| 기능 | 설명 |
|---|---|
| 🖥️ GUI 인터페이스 | Windows Forms 기반 직관적인 UI |
| 🔗 연결 관리 | 원-click 연결/연결 해제 |
| 📤 요청 전송 | 미리 정의된 명령 템플릿 전송 |
| 📥 응답 표시 | 요청/응답 로그 별도 표시 |
주문 정보 (order_info):
{
"AO_ID": 473449,
"MEMBER_ID": "1000000000000000",
"MEMBER_NM": "소비자",
"AMT": 8800,
"PAYMENT_TYPE": "11105500",
"DELIVERY_STATUS": "31",
"ORDER_TYPE": "D",
"LAND_ADDRESS": "서울특별시 종로구...",
"ROAD_ADDRESS": "서울특별시 종로구 율곡로...",
"LATITUDE": "37.5768897288",
"LONGITUDE": "126.9889239442",
"MESSAGE": "도착해서 전화 주시면 내려갈게요."
}| 버전 | 날짜 | 변경사항 |
|---|---|---|
| v2.1.0 | 2026-04-16 | 코드 품질 개선 (Health Check, Swagger, Prometheus, Graceful Shutdown) |
| v2.0.0 | 2026-04-16 | .NET 9 마이그레이션 |
| v1.1.1 | 2026-04-16 | UI 개선 |
각 릴리즈에는 Windows x64 실행 파일이 포함되어 있습니다:
ws002-v{x.y.z}-win-x64.zip
| 확장 | 설명 | 버전 |
|---|---|---|
| 🔐 JWT 인증 | 토큰 기반 인증 시스템 | v2.2.0 |
| 🔄 Redis 세션 | 분산 세션 스토어 | v2.2.0 |
| 🔒 메시지 암호화 | AES-256 메시지 암호화 | v2.4.0 |
| 📦 NuGet SDK | .NET 클라이언트 SDK | v2.4.0 |
| 확장 | 설명 | 난이도 |
|---|---|---|
| 🗄️ DB 연동 | MySQL 주문 저장 | ⭐⭐⭐ |
| 📊 모니터링 대시보드 | Grafana 대시보드 템플릿 | ⭐⭐⭐ |
| ☁️ 클라우드 배포 | AWS/Azure 배포 가이드 | ⭐⭐⭐ |
| 문서 | 설명 |
|---|---|
| PROJECT_STRUCTURE.md | 상세 프로젝트 구조 및 아키텍처 |
| ws002/Program.cs | 서버 엔트리포인트 |
| ws002/Services/UserService.cs | 세션 관리 |
| Dockerfile | Docker 빌드 설정 |
| k8s/deployment.yaml | Kubernetes 배포 |
MIT License
Project: push-server-client Version: 2.4.0 Last Updated: 2026-04-17
Built with ❤️ using .NET 9 & WebSocket