Caffeine.Client API
Caffeine Framework 클라이언트 SDK API 레퍼런스입니다.
개요
Caffeine.Client는 Caffeine 플랫폼에 접근하기 위한 클라이언트 SDK로, gRPC, GraphQL, SignalR 등 다양한 프로토콜을 지원합니다.
네임스페이스: Caffeine.Client
어셈블리: Caffeine.Client.dll
.NET 버전: .NET 10.0
주요 클래스
CaffeineClient
Caffeine 플랫폼에 연결하기 위한 메인 클라이언트 클래스입니다.
네임스페이스: Caffeine.Client
생성자
public CaffeineClient(CaffeineClientOptions options)
매개변수:
options(CaffeineClientOptions): 클라이언트 설정
주요 메서드
ConnectAsync()
Caffeine 서버에 비동기로 연결합니다.
Task<bool> ConnectAsync(CancellationToken cancellationToken = default);
반환값: Task<bool> - 연결 성공 시 true
사용 예시:
var options = new CaffeineClientOptions
{
ServerUrl = "https://localhost:5001",
ApiKey = "your-api-key"
};
var client = new CaffeineClient(options);
bool connected = await client.ConnectAsync();
if (connected)
{
Console.WriteLine("서버 연결 성공");
}
ReadTagAsync()
태그 값을 비동기로 읽습니다.
Task<TagValue?> ReadTagAsync(string tagName, CancellationToken cancellationToken = default);
매개변수:
tagName(string): 태그 이름cancellationToken(CancellationToken): 취소 토큰
반환값: Task<TagValue?> - 태그 값
사용 예시:
var temperature = await client.ReadTagAsync("Equipment1.Temperature");
if (temperature != null)
{
Console.WriteLine($"현재 온도: {temperature.Value}°C");
}
ReadTagsAsync()
여러 태그를 한 번에 읽습니다.
Task<Dictionary<string, TagValue>> ReadTagsAsync(string[] tagNames, CancellationToken cancellationToken = default);
매개변수:
tagNames(string[]): 태그 이름 배열cancellationToken(CancellationToken): 취소 토큰
반환값: Task<Dictionary<string, TagValue>> - 태그 이름과 값의 딕셔너리
사용 예시:
var tagNames = new[] { "Equipment1.Temperature", "Equipment1.Pressure", "Equipment1.Flow" };
var values = await client.ReadTagsAsync(tagNames);
foreach (var (name, value) in values)
{
Console.WriteLine($"{name}: {value.Value}");
}
WriteTagAsync()
태그에 값을 씁니다.
Task<bool> WriteTagAsync(string tagName, object value, CancellationToken cancellationToken = default);
매개변수:
tagName(string): 태그 이름value(object): 쓸 값cancellationToken(CancellationToken): 취소 토큰
반환값: Task<bool> - 쓰기 성공 시 true
사용 예시:
bool success = await client.WriteTagAsync("Equipment1.SetPoint", 75.0);
if (success)
{
Console.WriteLine("설정값 변경 완료");
}
SubscribeTagAsync()
태그 변경 사항을 실시간으로 구독합니다 (SignalR).
Task SubscribeTagAsync(string tagName, Action<TagValue> onTagChanged, CancellationToken cancellationToken = default);
매개변수:
tagName(string): 구독할 태그 이름onTagChanged(Action<TagValue>): 태그 변경 시 호출될 콜백cancellationToken(CancellationToken): 취소 토큰
사용 예시:
await client.SubscribeTagAsync("Equipment1.Temperature", (tagValue) =>
{
Console.WriteLine($"온도 변경: {tagValue.Value}°C at {tagValue.Timestamp}");
if (tagValue.Value is double temp && temp > 80)
{
Console.WriteLine("⚠️ 고온 경고!");
}
});
UnsubscribeTagAsync()
태그 구독을 해제합니다.
Task UnsubscribeTagAsync(string tagName);
사용 예시:
await client.UnsubscribeTagAsync("Equipment1.Temperature");
Console.WriteLine("구독 해제 완료");
CaffeineClientOptions
클라이언트 설정 옵션 클래스입니다.
네임스페이스: Caffeine.Client
속성
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
ServerUrl | string | - | Caffeine 서버 URL (필수) |
ApiKey | string? | null | API 키 (인증용) |
Timeout | TimeSpan | 30s | 요청 타임아웃 |
RetryCount | int | 3 | 재시도 횟수 |
UseSignalR | bool | true | SignalR 사용 여부 |
UseGrpc | bool | false | gRPC 사용 여부 |
사용 예시
var options = new CaffeineClientOptions
{
ServerUrl = "https://caffeine.example.com",
ApiKey = "sk_live_abc123xyz",
Timeout = TimeSpan.FromSeconds(60),
RetryCount = 5,
UseSignalR = true
};
var client = new CaffeineClient(options);
프로토콜별 클라이언트
GraphQLClient
GraphQL API를 통해 Caffeine에 접근합니다.
네임스페이스: Caffeine.Client.GraphQL
주요 메서드
QueryAsync()
GraphQL 쿼리를 실행합니다.
Task<TResult> QueryAsync<TResult>(string query, object? variables = null);
사용 예시:
var graphqlClient = new GraphQLClient("https://localhost:5001/graphql");
var query = @"
query GetTags($equipmentId: String!) {
tags(equipmentId: $equipmentId) {
tagName
value
timestamp
}
}
";
var variables = new { equipmentId = "Equipment1" };
var result = await graphqlClient.QueryAsync<TagsResult>(query, variables);
foreach (var tag in result.Tags)
{
Console.WriteLine($"{tag.TagName}: {tag.Value}");
}
SignalRClient
SignalR을 통한 실시간 통신 클라이언트입니다.
네임스페이스: Caffeine.Client.SignalR
주요 메서드
StartAsync()
SignalR 연결을 시작합니다.
Task StartAsync(CancellationToken cancellationToken = default);
On()
서버 이벤트를 수신합니다.
void On<T>(string eventName, Action<T> handler);
사용 예시:
var signalRClient = new SignalRClient("https://localhost:5001/hubs/tags");
// 이벤트 핸들러 등록
signalRClient.On<TagValue>("TagChanged", (tagValue) =>
{
Console.WriteLine($"태그 변경: {tagValue.TagName} = {tagValue.Value}");
});
// 연결 시작
await signalRClient.StartAsync();
// 태그 구독
await signalRClient.InvokeAsync("SubscribeTag", "Equipment1.Temperature");
예제
기본 사용법
using Caffeine.Client;
class Program
{
static async Task Main(string[] args)
{
// 1. 클라이언트 생성
var options = new CaffeineClientOptions
{
ServerUrl = "https://localhost:5001",
ApiKey = "your-api-key"
};
var client = new CaffeineClient(options);
// 2. 연결
await client.ConnectAsync();
// 3. 태그 읽기
var temperature = await client.ReadTagAsync("Equipment1.Temperature");
Console.WriteLine($"온도: {temperature?.Value}");
// 4. 태그 쓰기
await client.WriteTagAsync("Equipment1.SetPoint", 75.0);
// 5. 연결 해제
await client.DisconnectAsync();
}
}
실시간 모니터링
using Caffeine.Client;
public class RealtimeMonitor
{
private readonly CaffeineClient _client;
public RealtimeMonitor(string serverUrl)
{
var options = new CaffeineClientOptions
{
ServerUrl = serverUrl,
UseSignalR = true
};
_client = new CaffeineClient(options);
}
public async Task StartMonitoringAsync(string[] tagNames, CancellationToken cancellationToken)
{
await _client.ConnectAsync(cancellationToken);
// 각 태그 구독
foreach (var tagName in tagNames)
{
await _client.SubscribeTagAsync(tagName, OnTagChanged, cancellationToken);
}
Console.WriteLine($"{tagNames.Length}개 태그 모니터링 시작");
// 취소될 때까지 대기
await Task.Delay(Timeout.Infinite, cancellationToken);
}
private void OnTagChanged(TagValue tagValue)
{
Console.WriteLine($"[{tagValue.Timestamp:HH:mm:ss}] {tagValue.TagName}: {tagValue.Value}");
// 알람 로직
if (tagValue.TagName.Contains("Temperature") && tagValue.Value is double temp)
{
if (temp > 80)
{
Console.WriteLine($"⚠️ 고온 경고: {temp}°C");
}
else if (temp < 10)
{
Console.WriteLine($"⚠️ 저온 경고: {temp}°C");
}
}
}
}
// 사용
var monitor = new RealtimeMonitor("https://localhost:5001");
var tags = new[] { "Equipment1.Temperature", "Equipment1.Pressure" };
using var cts = new CancellationTokenSource();
Console.CancelKeyPress += (s, e) =>
{
e.Cancel = true;
cts.Cancel();
};
await monitor.StartMonitoringAsync(tags, cts.Token);
배치 데이터 수집
using Caffeine.Client;
public class BatchDataCollector
{
private readonly CaffeineClient _client;
private readonly List<TagValue> _buffer = new();
public BatchDataCollector(CaffeineClient client)
{
_client = client;
}
public async Task CollectDataAsync(string[] tagNames, int intervalMs, int batchSize)
{
while (true)
{
// 모든 태그 읽기
var values = await _client.ReadTagsAsync(tagNames);
foreach (var (name, value) in values)
{
_buffer.Add(value);
// 버퍼가 가득 차면 저장
if (_buffer.Count >= batchSize)
{
await SaveToDatabase(_buffer);
_buffer.Clear();
}
}
await Task.Delay(intervalMs);
}
}
private async Task SaveToDatabase(List<TagValue> data)
{
Console.WriteLine($"{data.Count}개 데이터 저장 중...");
// 데이터베이스 저장 로직
await Task.Delay(100);
Console.WriteLine("저장 완료");
}
}
에러 처리
연결 실패 처리
try
{
await client.ConnectAsync();
}
catch (HttpRequestException ex)
{
Console.WriteLine($"서버 연결 실패: {ex.Message}");
}
catch (TimeoutException ex)
{
Console.WriteLine($"연결 시간 초과: {ex.Message}");
}
재시도 로직
public async Task<TagValue?> ReadTagWithRetryAsync(string tagName, int maxRetries = 3)
{
for (int i = 0; i < maxRetries; i++)
{
try
{
return await client.ReadTagAsync(tagName);
}
catch (Exception ex)
{
if (i == maxRetries - 1) throw;
Console.WriteLine($"재시도 {i + 1}/{maxRetries}: {ex.Message}");
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, i))); // 지수 백오프
}
}
return null;
}
참고 항목
- Caffeine.Core API - 핵심 API
- Caffeine.Infrastructure API - 인프라 서비스
- 데이터 수집 가이드
- 엣지 애플리케이션 개발
네임스페이스: Caffeine.Client
어셈블리: Caffeine.Client.dll (v2.0.6)
.NET 플랫폼: .NET 10.0