■ 대용량 데이터를 스트리밍 방식으로 전달받는 방법을 보여준다.
[TestClient 프로젝트]
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
using System; using System.Collections.Generic; using System.IO; using System.Net.Http; using System.Net.Http.Headers; using Newtonsoft.Json; namespace TestClient { /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { Console.Title = "대용량 데이터를 스트리밍 방식으로 전달받기"; Console.WriteLine("PRESS ANY KEY TO CONTINUE..."); Console.ReadKey(true); foreach(ValueModel value in GetValueEnumerable()) { Console.WriteLine("{0}\t{1}", value.SequenceID, value.Data); } Console.WriteLine("PRESS ANY KEY TO EXIT..."); Console.ReadKey(true); } #endregion #region 값 열거 가능형 구하기 - GetValueEnumerable() /// <summary> /// 값 열거 가능형 구하기 /// </summary> /// <returns>값 열거 가능형</returns> private static IEnumerable<ValueModel> GetValueEnumerable() { JsonSerializer serializer = new JsonSerializer(); HttpClient client = new HttpClient(); MediaTypeWithQualityHeaderValue headerValue = new MediaTypeWithQualityHeaderValue("application/json"); client.DefaultRequestHeaders.Accept.Add(headerValue); using(Stream stream = client.GetStreamAsync("http://localhost:63025/api/value").Result) { using(StreamReader streamReader = new StreamReader(stream)) { using(JsonTextReader jsonTextReader = new JsonTextReader(streamReader)) { while(jsonTextReader.Read()) { if(jsonTextReader.TokenType != JsonToken.StartArray && jsonTextReader.TokenType != JsonToken.EndArray) { yield return serializer.Deserialize<ValueModel>(jsonTextReader); } } } } } } #endregion } } |
[TestServer 프로젝트]
▶ Models/ValueModel.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
using System.Runtime.Serialization; namespace TestServer.Models { /// <summary> /// 값 모델 /// </summary> [DataContract] public class ValueModel { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 시퀀스 ID - Sequence /// <summary> /// 시퀀스 ID /// </summary> [DataMember] public int SequenceID { get; set; } #endregion #region 데이터 - Data /// <summary> /// 데이터 /// </summary> [DataMember] public string Data { get; set; } #endregion } } |
▶ Handlers/ValueHandler.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
using System.Net.Http; using System.Threading; using System.Threading.Tasks; namespace TestServer.Handlers { /// <summary> /// 값 핸들러 /// </summary> public class ValueHandler : DelegatingHandler { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Protected #region 비동기 송신하기 - SendAsync(requestMessage, cancellationToken) /// <summary> /// 비동기 송신하기 /// </summary> /// <param name="requestMessage">HTTP 요청 메시지</param> /// <param name="cancellationToken">취소 토큰</param> /// <returns>HTTP 응답 메시지 태스크</returns> protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage requestMessage, CancellationToken cancellationToken) { Task<HttpResponseMessage> responseMessageTask = base.SendAsync(requestMessage, cancellationToken); responseMessageTask.Result.Headers.TransferEncodingChunked = true; return responseMessageTask; } #endregion } } |
▶ Controllers/ValueController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
using System; using System.Collections.Generic; using System.Linq; using System.Web.Http; using TestServer.Models; namespace TestServer.Controllers { /// <summary> /// 값 컨트롤러 /// </summary> public class ValueController : ApiController { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region GET 처리하기 - Get() /// <summary> /// GET 처리하기 /// </summary> /// <returns>값 열거 가능형</returns> [HttpGet] public IEnumerable<ValueModel> Get() { foreach(int i in Enumerable.Range(0, 10000)) { yield return new ValueModel() { SequenceID = i, Data = Guid.NewGuid().ToString() }; } } #endregion } } |
▶ App_Start/WebAPIConfiguration.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
using System.Web.Http; using TestServer.Handlers; namespace TestServer { /// <summary> /// 웹 API 구성 /// </summary> public static class WebAPIConfiguration { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 등록하기 - Register(configuration) /// <summary> /// 등록하기 /// </summary> /// <param name="configuration">HTTP 구성</param> public static void Register(HttpConfiguration configuration) { configuration.MapHttpAttributeRoutes(); configuration.MessageHandlers.Add(new ValueHandler()); configuration.Routes.MapHttpRoute ( name : "DefaultApi", routeTemplate : "api/{controller}/{id}", defaults : new { id = RouteParameter.Optional } ); } #endregion } } |
▶ Global.asax.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
using System.Web; using System.Web.Http; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; namespace TestServer { /// <summary> /// 웹 API 애플리케이션 /// </summary> public class WebApiApplication : HttpApplication { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 애플리케이션 시작시 처리하기 - Application_Start() /// <summary> /// 애플리케이션 시작시 처리하기 /// </summary> protected void Application_Start() { GlobalConfiguration.Configure(WebAPIConfiguration.Register); FilterConfiguration.RegisterGlobalFilterCollection(GlobalFilters.Filters); RouteConfiguration.RegisterRouteCollection(RouteTable.Routes); BundleConfiguration.RegisterBundleCollection(BundleTable.Bundles); } #endregion } } |