public interface IAsyncDecorator
{
UniTask<ResponseContext> SendAsync(RequestContext context, CancellationToken cancellationToken, Func<RequestContext, CancellationToken, UniTask<ResponseContext>> next);
}
public class SetupHeaderDecorator : IAsyncDecorator
{
public async UniTask<ResponseContext> SendAsync(RequestContext context, CancellationToken cancellationToken, Func<RequestContext, CancellationToken, UniTask<ResponseContext>> next)
{
//Request 호출 전
context.RequestHeaders["x-app-timestamp"] = context.Timestamp.ToString();
context.RequestHeaders["x-user-id"] = UserProfile.Id;
context.RequestHeaders["x-access-token"] = UserProfile.Token;
//Request 호출
var respsonse = await next(context, cancellationToken); // call next decorator
//Request 호출 후
var nextToken = respsonse.ResponseHeaders["token"];
UserProfile.Token = nextToken;
return respsonse;
}
}
LoggingDecorator - Request 전후 로그 출력, Exception 로그 출력
MockDecorator - 테스트 및 서버 측 구현이 준비 되기전 클라이언트 더미 패킷 테스트
AppendTokenDecorator - 토큰이 유효하지 않을 때 토큰을 얻고, 패킷 다시 전달
QueueRequestDecorator - 순차 처리 강제(Queue)
사용하기
// create decorated client(store to field)
var client = new NetworkClient("http://localhost", TimeSpan.FromSeconds(10),
new QueueRequestDecorator(),
new LoggingDecorator(),
new AppendTokenDecorator(),
new SetupHeaderDecorator());
// for example, call like this
var result = await client.PostAsync("/User/Register", new { Id = 100 });
QueueRequest -> Logging -> AppendToken -> SetupHeader -> NetworkClient -> SetupHeader -> AppendToken -> Logging -> QueueRequest
IAsyncDecorator, RequestContext, ResponseContext, NetworkClient
핵심 프로세스 - IAsyncDecorator들의 호출
UniTask<ResponseContext> InvokeRecursive(RequestContext context, CancellationToken cancellationToken)
{
context.decoratorIndex++;
return decorators[context.decoratorIndex].SendAsync(context, cancellationToken, InvokeRecursive);
}