■ JSON 압축 스트리밍 데이터를 구하는 방법을 보여준다.
[TestServer 프로젝트]
▶ IDataService.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 |
using System.IO; using System.ServiceModel; namespace TestServer { /// <summary> /// 데이터 서비스 인터페이스 /// </summary> [ServiceContract] public interface IDataService { //////////////////////////////////////////////////////////////////////////////////////////////////// Method #region 데이터 구하기 - GetData(dataID, conditionData) /// <summary> /// 데이터 구하기 /// </summary> /// <param name="dataID">데이터 ID</param> /// <param name="conditionData">조건 데이터</param> /// <returns>데이터</returns> [OperationContract] Stream GetData(string dataID, string conditionData); #endregion } } |
▶ DataService.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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.ServiceModel; using TestCommon; namespace TestServer { /// <summary> /// 데이터 서비스 /// </summary> public class DataService : IDataService { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 임시 디렉토리 경로 /// </summary> private const string TEMPORARY_DIRECTORY_PATH = "d:\\temporary_server"; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 데이터 구하기 - GetData(dataID, conditionData) /// <summary> /// 데이터 구하기 /// </summary> /// <param name="dataID">데이터 ID</param> /// <param name="conditionData">조건 데이터</param> /// <returns>데이터</returns> public Stream GetData(string dataID, string conditionData) { WriteMessage("START GET DATA"); WriteMessage("DATA ID : {0}", dataID); WriteMessage("CONDITION DATA"); WriteMessage("--------------------------------------------------"); WriteMessage(conditionData); WriteMessage("--------------------------------------------------"); string transactionID = GUIDHelper.GetGUID(); if(!Directory.Exists(TEMPORARY_DIRECTORY_PATH)) { Directory.CreateDirectory(TEMPORARY_DIRECTORY_PATH); } ////////////////////////////////////////////////// int dataCount = JSONHelper.Deserialize<int>(conditionData); List<Student> list = Student.GetData(dataCount); ////////////////////////////////////////////////// WriteMessage("START CREATE TRANSACTION FILE"); string transactionFilePath = Path.Combine(TEMPORARY_DIRECTORY_PATH, string.Format("{0}.dat", transactionID)); using(FileStream fileStream = new FileStream(transactionFilePath, FileMode.Create, FileAccess.Write)) { using(GZipStream gZipStream = new GZipStream(fileStream, CompressionMode.Compress)) { JSONHelper.Serialize(list, gZipStream); } } WriteMessage("END CREATE TRANSACTION FILE"); Stream stream = null; try { stream = File.Open(transactionFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); } catch { } OperationContext operationContext = OperationContext.Current; operationContext.OperationCompleted += delegate(object sender, EventArgs e) { try { File.Delete(transactionFilePath); } catch { } }; WriteMessage("END GET DATA"); return stream; } #endregion ////////////////////////////////////////////////////////////////////////////////////////// Private #region 메시지 쓰기 - WriteMessage(format, parameterArray) /// <summary> /// 메시지 쓰기 /// </summary> /// <param name="format">포맷 문자열</param> /// <param name="parameterArray">매개 변수 배열</param> private void WriteMessage(string format, params object[] parameterArray) { string message; if(parameterArray.Length == 0) { message = format; } else { message = string.Format(format, parameterArray); } Console.WriteLine(string.Format("[{0}] {1}", DateTime.Now.ToString("HH:mm:ss"), message)); } #endregion } } |
▶ 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 |
using System; using System.ServiceModel; namespace TestServer { /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { using(ServiceHost serviceHost = new ServiceHost(typeof(DataService))) { serviceHost.Open(); Console.WriteLine("서버가 시작되었습니다 : " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); Console.ReadKey(true); } } #endregion } } |
▶ App.config
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 |
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="mexBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> <bindings> <basicHttpBinding> <binding name="basicHttp" sendTimeout="00:10:00" receiveTimeout="00:10:00" maxReceivedMessageSize="1262485504" transferMode="Streamed" /> </basicHttpBinding> <netTcpBinding> <binding name="netTcp" sendTimeout="00:10:00" receiveTimeout="00:10:00" maxReceivedMessageSize="1262485504" transferMode="Streamed" /> </netTcpBinding> </bindings> <services> <service name="TestServer.DataService" behaviorConfiguration="mexBehavior"> <endpoint address="DataService" binding="basicHttpBinding" bindingConfiguration="basicHttp" contract="TestServer.IDataService" /> <endpoint address="DataService" binding="netTcpBinding" bindingConfiguration="netTcp" contract="TestServer.IDataService" /> <host> <baseAddresses> <add baseAddress="http://localhost:8080" /> <add baseAddress="net.tcp://localhost:8090" /> </baseAddresses> </host> </service> </services> </system.serviceModel> </configuration> |
[TestClient 프로젝트]
▶ MainForm.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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Windows.Forms; using TestCommon; using TestClient.DataService; namespace TestClient { /// <summary> /// 메인 폼 /// </summary> public partial class MainForm : Form { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 임시 디렉토리 경로 /// </summary> private const string TEMPORARY_DIRECTORY_PATH = "d:\\temporary_client"; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainForm() /// <summary> /// 생성자 /// </summary> public MainForm() { InitializeComponent(); this.getHTTPDataButton.Click += getHTTPDataButton_Click; this.getTCPDataButton.Click += getTCPDataButton_Click; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private //////////////////////////////////////////////////////////////////////////////// Event #region HTTP 데이터 구하기 버튼 클릭시 처리하기 - getHTTPDataButton_Click(sender, e) /// <summary> /// HTTP 데이터 구하기 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void getHTTPDataButton_Click(object sender, EventArgs e) { WriteMessage("START GET HTTP DATA"); string dataID = "0001"; string conditionData = JSONHelper.Serialize((int)1000000); List<Student> list = GetData<List<Student>>("BasicHttpBinding_IDataService", dataID, conditionData); string message; if(list != null) { message = list.Count.ToString(); } else { message = "데이터가 없습니다."; } WriteMessage("END GET HTTP DATA"); MessageBox.Show(message); } #endregion #region TCP 데이터 구하기 버튼 클릭시 처리하기 - getTCPDataButton_Click(sender, e) /// <summary> /// TCP 데이터 구하기 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void getTCPDataButton_Click(object sender, EventArgs e) { WriteMessage("START GET TCP DATA"); string dataID = "0001"; string conditionData = JSONHelper.Serialize((int)1000000); List<Student> list = GetData<List<Student>>("NetTcpBinding_IDataService", dataID, conditionData); string message; if(list != null) { message = list.Count.ToString(); } else { message = "데이터가 없습니다."; } WriteMessage("END GET TCP DATA"); MessageBox.Show(message); } #endregion //////////////////////////////////////////////////////////////////////////////// Function #region 데이터 구하기 - GetData<TResult>(endpointConfigurationName, dataID, conditionData) /// <summary> /// 데이터 구하기 /// </summary> /// <typeparam name="TResult">결과 타입</typeparam> /// <param name="endpointConfigurationName">종점 구성명</param> /// <param name="dataID">데이터 ID</param> /// <param name="conditionData">조건 데이터</param> /// <returns>데이터</returns> private TResult GetData<TResult>(string endpointConfigurationName, string dataID, string conditionData) { string transactionID = GUIDHelper.GetGUID(); if(!Directory.Exists(TEMPORARY_DIRECTORY_PATH)) { Directory.CreateDirectory(TEMPORARY_DIRECTORY_PATH); } string transactionFilePath = Path.Combine(TEMPORARY_DIRECTORY_PATH, string.Format("{0}.dat", transactionID)); try { using(DataServiceClient client = new DataServiceClient(endpointConfigurationName)) { using(FileStream fileStream = new FileStream(transactionFilePath, FileMode.Create, FileAccess.Write)) { using(Stream stream = client.GetData(dataID, conditionData)) { stream.CopyTo(fileStream); } } } TResult result = default(TResult); using(FileStream fileStream = new FileStream(transactionFilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using(GZipStream gZipStream = new GZipStream(fileStream, CompressionMode.Decompress)) { result = JSONHelper.Deserialize<TResult>(gZipStream); } } return result; } finally { try { File.Delete(transactionFilePath); } catch { } } } #endregion #region 메시지 쓰기 - WriteMessage(format, parameterArray) /// <summary> /// 메시지 쓰기 /// </summary> /// <param name="format">포맷 문자열</param> /// <param name="parameterArray">매개 변수 배열</param> private void WriteMessage(string format, params object[] parameterArray) { string message; if(parameterArray.Length == 0) { message = format; } else { message = string.Format(format, parameterArray); } this.listBox.Items.Add(string.Format("[{0}] {1}", DateTime.Now.ToString("HH:mm:ss"), message)); this.listBox.Update(); } #endregion } } |
▶ App.config
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 |
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IDataService" sendTimeout="00:10:00" receiveTimeout="00:10:00" maxReceivedMessageSize="1262485504" transferMode="Streamed" /> </basicHttpBinding> <netTcpBinding> <binding name="NetTcpBinding_IDataService" sendTimeout="00:10:00" receiveTimeout="00:10:00" maxReceivedMessageSize="1262485504" transferMode="Streamed" /> </netTcpBinding> </bindings> <client> <endpoint name="BasicHttpBinding_IDataService" address="http://localhost:8080/DataService" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDataService" contract="DataService.IDataService" /> <endpoint name="NetTcpBinding_IDataService" address="net.tcp://localhost:8090/DataService" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IDataService" contract="DataService.IDataService" /> </client> </system.serviceModel> </configuration> |