IndustrialUpdated 2025-04-01
gRPC Streaming
단방향 단순 호출을 넘어 — 실시간 IoT·로봇 제어를 위한 스트리밍 아키텍처
ESP32-S3PlatformIOFreeRTOS
1. 개념 (Concept)
1.1 gRPC란?
gRPC는 Google이 개발한 고성능 오픈소스 RPC(Remote Procedure Call) 프레임워크다. HTTP/2 + Protocol Buffers를 기반으로 언어 간 타입 안전 통신을 제공한다.
Protocol Buffers (.proto) → 코드 자동 생성 → 타입 안전 RPC 호출
1.2 gRPC vs REST vs MQTT 비교
| 항목 | REST (HTTP/1.1) | MQTT | gRPC (HTTP/2) |
|---|---|---|---|
| 프로토콜 | 텍스트 (JSON) | 바이너리 | 바이너리 (Protobuf) |
| 스트리밍 | 불가 (SSE 제한적) | Pub/Sub | 완전한 양방향 |
| 연결 | 요청마다 재연결 | 영구 연결 | 영구 연결 (멀티플렉싱) |
| 타입 안전 | 없음 | 없음 | 스키마 강제 |
| 브라우저 지원 | 완전 | 불가 | gRPC-Web 필요 |
| MCU 적합성 | 보통 | 최적 | 무거움 |
| 서버간 통신 | 보통 | 보통 | 최적 |
| 지연시간 | 높음 | 낮음 | 매우 낮음 |
1.3 스트리밍 4가지 패턴
2. 상세 내용 (Details)
2.1 HTTP/2 멀티플렉싱 구조
gRPC가 빠른 핵심 이유 — HTTP/1.1의 Head-of-Line Blocking 제거.
2.2 gRPC 프레임 구조 (Wire Format)
┌─────────────────────────────────────────────────────┐
│ gRPC 데이터 프레임 (5-byte 헤더 + Protobuf payload) │
├──────┬──────────────────────────────────────────────┤
│ [0] │ Compressed-Flag (0 = 비압축, 1 = gzip) │
│[1-4] │ Message Length (uint32, big-endian) │
│[5..] │ Protobuf 직렬화 데이터 │
└──────┴──────────────────────────────────────────────┘
2.3 Protocol Buffers 타입 시스템
2.4 CtrlPlus Proto 정의 예시
protobuf
2.5 gRPC-Web 변환 구조 (브라우저 지원)
브라우저는 HTTP/2 Trailer 헤더에 직접 접근 불가 → Envoy가 변환.
2.6 Trailer 인코딩 원리
gRPC-Web Trailer Frame:
[0] = 0x80 (1 << 7 = Trailer flag)
[1-4] = trailer 길이
[5..] = "grpc-status:0\r\ngrpc-message:\r\n"
3. 구조 설명 (Architecture)
3.1 CtrlPlus 전체 통신 아키텍처
3.2 Server Streaming 상세 플로우
3.3 Bidirectional Streaming 상세 플로우
3.4 MQTT-gRPC Bridge 구조
3.5 Interceptor 체인 구조
3.6 Go 서버 상태 머신
3.7 Envoy 설정 구조
4. 응용 (Applications)
4.1 스트리밍 패턴 × CtrlPlus 적용 맵
4.2 시나리오별 스트리밍 선택 기준
4.3 ESP32-S3 ↔ Go Bridge 연동 흐름
4.4 gRPC 오류 코드 대응표
| 코드 | 이름 | 상황 | 대응 |
|---|---|---|---|
| 0 | OK | 성공 | — |
| 1 | CANCELLED | 클라이언트가 취소 | 정상 처리 |
| 2 | UNKNOWN | 알 수 없는 오류 | 서버 로그 확인 |
| 4 | DEADLINE_EXCEEDED | 타임아웃 초과 | 재시도 or 타임아웃 증가 |
| 5 | NOT_FOUND | 리소스 없음 | 디바이스 ID 확인 |
| 7 | PERMISSION_DENIED | 권한 없음 | JWT 권한 확인 |
| 8 | RESOURCE_EXHAUSTED | Rate Limit 초과 | Backoff 재시도 |
| 10 | ABORTED | 트랜잭션 충돌 | 재시도 |
| 13 | INTERNAL | 서버 내부 오류 | 서버 로그 확인 |
| 14 | UNAVAILABLE | 서버 불가 | 재연결 (Backoff) |
| 16 | UNAUTHENTICATED | 인증 실패 | JWT 갱신 |
4.5 Next.js 클라이언트 구현 패턴
typescript
4.6 Go 서버 BiDi 스트리밍 구현 핵심
Go
4.7 배포 구조 (CtrlPlus VPS)
4.8 트러블슈팅 플로우
부록. 빠른 참조
Proto 서비스 패턴 치트시트
// Unary
rpc GetStatus(DeviceId) returns (DeviceStatus);
// Server Streaming
rpc Subscribe(SubscribeReq) returns (stream SensorData);
// Client Streaming
rpc UploadBatch(stream SensorData) returns (BatchResult);
// Bidirectional Streaming
rpc ControlLoop(stream SensorData) returns (stream ControlCommand);
grpcurl 테스트 명령
Bash
스트리밍 타입 × 적합 시나리오
| 패턴 | CtrlFarm | CtrlFactory | CtrlMotion |
|---|---|---|---|
| Unary | 밸브 개폐, 파라미터 설정 | 액추에이터 명령 | 단발 관절 이동 |
| Server Stream | 센서 대시보드, 알람 | 공정 모니터링 | 로봇 상태 시각화 |
| Client Stream | 재연결 버퍼 업로드 | 생산 로그 배치 | 경로 계획 업로드 |
| BiDi Stream | — | 실시간 공정 피드백 | PID 제어 루프 |