첨부 소스 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestSolution.zip
다운로드

[TestLibrary 프로젝트]

▶ ValueModel.cs

namespace TestLibrary
{
    /// <summary>
    /// 값 모델
    /// </summary>
    public class ValueModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region ID - ID

        /// <summary>
        /// ID
        /// </summary>
        public int ID { get; set; }

        #endregion
        #region 데이터 - Data

        /// <summary>
        /// 데이터
        /// </summary>
        public string Data { get; set; }

        #endregion
        #region 태그 - Tag

        /// <summary>
        /// 태그
        /// </summary>
        public string Tag { get; set; }

        #endregion
    }
}

 

300x250

 

[TestClient 프로젝트]

▶ Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

using Newtonsoft.Json;

using TestLibrary;

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);

            //TestPOSTData1();
            //TestPOSTData2();
            TestGETData();

            Console.WriteLine("PRESS ANY KEY TO EXIT...");

            Console.ReadKey(true);
        }

        #endregion

        #region POST 데이터 구하기 1 - GetPOSTData1<TResultItem>(url, source)

        /// <summary>
        /// POST 데이터 구하기 1
        /// </summary>
        /// <typeparam name="TResultItem">결과 항목 타입</typeparam>
        /// <param name="url">URL</param>
        /// <param name="source">소스 객체</param>
        /// <returns>결과 항목 타입 열거 가능형</returns>
        private static IEnumerable<TResultItem> GetPOSTData1<TResultItem>(string url, object source)
        {
            string sourceJSON = JsonConvert.SerializeObject(source);

            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, url);

            requestMessage.Content = new StringContent(sourceJSON, Encoding.UTF8, "application/json");

            requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpClient client = new HttpClient();

            HttpResponseMessage responseMessage = client.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead).Result;

            responseMessage.EnsureSuccessStatusCode();

            using(Stream stream = responseMessage.Content.ReadAsStreamAsync().Result)
            {
                using(StreamReader streamReader = new StreamReader(stream))
                {
                    JsonSerializer serializer = new JsonSerializer();

                    using(JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
                    {
                        while(jsonTextReader.Read())
                        {
                            if(jsonTextReader.TokenType != JsonToken.StartArray && jsonTextReader.TokenType != JsonToken.EndArray)
                            {
                                yield return serializer.Deserialize<TResultItem>(jsonTextReader);
                            }
                        }
                    }
                }
            }
        }

        #endregion
        #region POST 데이터 테스트하기 1 - TestPOSTData1()

        /// <summary>
        /// POST 데이터 테스트하기 1
        /// </summary>
        private static void TestPOSTData1()
        {
            string url = "http://localhost:5569/api/test/postdata";
            
            ValueModel source = new ValueModel();
            
            source.ID   = -1;
            source.Data = "NODATA";
            source.Tag  = "POST3";
            
            foreach(ValueModel value in GetPOSTData1<ValueModel>(url, source))
            {
                Console.WriteLine("{0} {1} {2}", value.ID, value.Data.Length, value.Tag);
            }
        }

        #endregion

        #region POST 스트림 구하기 - POSTGetStream(serverURL, contentType, encoding, argument, timeOut)

        /// <summary>
        /// POST 스트림 구하기
        /// </summary>
        /// <param name="serverURL">서버 URL</param>
        /// <param name="contentType">컨텐츠 타입</param>
        /// <param name="encoding">인코딩</param>
        /// <param name="argument">인자 문자열</param>
        /// <param name="timeOut">타임 아웃</param>
        /// <returns>POST 스트림</returns>
        private static Stream POSTGetStream(string serverURL, string contentType, Encoding encoding, string argument, int? timeOut = null)
        {
            byte[] argumentArray = encoding.GetBytes(argument);
            
            HttpWebRequest request = WebRequest.Create(serverURL) as HttpWebRequest;

            request.ProtocolVersion           = HttpVersion.Version11;
            request.AllowAutoRedirect         = true;
            request.AllowWriteStreamBuffering = true;
            request.Method                    = WebRequestMethods.Http.Post;
            request.ContentType               = contentType;
            request.ContentLength             = argumentArray.Length;

            if(timeOut.HasValue)
            {
                request.Timeout = timeOut.Value;
            }

            using(Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(argumentArray, 0, argumentArray.Length);
            }

            HttpWebResponse response = request.GetResponse() as HttpWebResponse;

            Stream responseStream = response.GetResponseStream();

            return responseStream;
        }

        #endregion
        #region POST 데이터 구하기 2 - GetPOSTData2<TResultItem>(url, source)

        /// <summary>
        /// POST 데이터 구하기 2
        /// </summary>
        /// <typeparam name="TResultItem">결과 항목 타입</typeparam>
        /// <param name="url">URL</param>
        /// <param name="source">소스 객체</param>
        /// <returns>결과 항목 타입 열거 가능형</returns>
        private static IEnumerable<TResultItem> GetPOSTData2<TResultItem>(string url, object source)
        {
            string sourceJSON = JsonConvert.SerializeObject(source);

            using(Stream stream = POSTGetStream(url, "application/json; charset=utf-8", Encoding.UTF8, sourceJSON))
            {
                using(StreamReader streamReader = new StreamReader(stream))
                {
                    using(JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
                    {
                        JsonSerializer serializer = new JsonSerializer();

                        while(jsonTextReader.Read())
                        {
                            if(jsonTextReader.TokenType != JsonToken.StartArray && jsonTextReader.TokenType != JsonToken.EndArray)
                            {
                                yield return serializer.Deserialize<TResultItem>(jsonTextReader);
                            }
                        }
                    }
                }
            }
        }

        #endregion
        #region POST 데이터 테스트하기 2 - TestPOSTData2()

        /// <summary>
        /// POST 데이터 테스트하기 2
        /// </summary>
        private static void TestPOSTData2()
        {
            string url = "http://localhost:5569/api/test/postdata";
            
            ValueModel source = new ValueModel();
            
            source.ID   = -1;
            source.Data = "NODATA";
            source.Tag  = "POST3";
            
            foreach(ValueModel value in GetPOSTData2<ValueModel>(url, source))
            {
                Console.WriteLine("{0} {1} {2}", value.ID, value.Data.Length, value.Tag);
            }
        }

        #endregion

        #region GET 데이터 구하기 - GetGETData<TResultItem>(url)

        /// <summary>
        /// GET 데이터 구하기
        /// </summary>
        /// <typeparam name="TResultItem">결과 항목 타입</typeparam>
        /// <param name="url">URL</param>
        /// <returns>결과 항목 열거 가능형</returns>
        private static IEnumerable<TResultItem> GetGETData<TResultItem>(string url)
        {
            HttpClient client = new HttpClient();

            MediaTypeWithQualityHeaderValue headerValue = new MediaTypeWithQualityHeaderValue("application/json");

            client.DefaultRequestHeaders.Accept.Add(headerValue);

            using(Stream stream = client.GetStreamAsync(url).Result)
            {
                using(StreamReader streamReader = new StreamReader(stream))
                {
                    JsonSerializer serializer = new JsonSerializer();

                    using(JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
                    {
                        while(jsonTextReader.Read())
                        {
                            if(jsonTextReader.TokenType != JsonToken.StartArray && jsonTextReader.TokenType != JsonToken.EndArray)
                            {
                                yield return serializer.Deserialize<TResultItem>(jsonTextReader);
                            }
                        }
                    }
                }
            }
        }

        #endregion
        #region GET 데이터 테스트하기 - TestGETData()

        /// <summary>
        /// GET 데이터 테스트하기
        /// </summary>
        private static void TestGETData()
        {
            string url = "http://localhost:5569/api/test/getdata?tag=GET";
            
            foreach(ValueModel value in GetGETData<ValueModel>(url))
            {
                Console.WriteLine("{0} {1} {2}", value.ID, value.Data.Length, value.Tag);
            }
        }

        #endregion
    }
}

 

728x90

 

[TestServer 프로젝트]

▶ Controllers/TestController.cs

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using TestLibrary;

namespace TestServer.Controllers
{
    /// <summary>
    /// 테스트 컨트롤러
    /// </summary>
    [Route("api/[controller]")]
    public class TestController : Controller
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 샘플 데이터
        /// </summary>
        private static string _sampleData;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Static

        #region 생성자 - TestController()

        /// <summary>
        /// 생성자
        /// </summary>
        static TestController()
        {
            StringBuilder stringBuilder = new StringBuilder();

            for(int i = 0; i < 100; i++)
            {
                stringBuilder.Append("ABCDEFGHIJABCDEFGHIJ");
                stringBuilder.Append("ABCDEFGHIJABCDEFGHIJ");
                stringBuilder.Append("ABCDEFGHIJABCDEFGHIJ");
                stringBuilder.Append("ABCDEFGHIJABCDEFGHIJ");
                stringBuilder.Append("ABCDEFGHIJABCDEFGHIJ");
            }

            _sampleData = stringBuilder.ToString();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region GET 데이터 구하기 - GetData(tag)

        /// <summary>
        /// GET 데이터 구하기
        /// </summary>
        /// <param name="tag">태그</param>
        /// <returns>값 열거 가능형</returns>
        [HttpGet]
        [Route("GetData")]
        public IEnumerable<ValueModel> GetData(string tag)
        {
            foreach(int i in Enumerable.Range(1, 1000000))
            {
                yield return new ValueModel()
                {
                    ID   = i,
                    Data = _sampleData,
                    Tag  = tag
                };
            }
        }

        #endregion
        #region POST 데이터 구하기 - PostData(source)

        /// <summary>
        /// POST 데이터 구하기
        /// </summary>
        /// <param name="source">소스 값</param>
        /// <returns>값 열거 가능형</returns>
        [HttpPost]
        [Route("PostData")]
        public IEnumerable<ValueModel> PostData([FromBody] ValueModel source)
        {
            foreach(int i in Enumerable.Range(1, 1000000))
            {
                yield return new ValueModel()
                {
                    ID   = i,
                    Data = _sampleData,
                    Tag  = source.Tag
                };
            }
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요