■ 이중 메시지 교환 패턴을 사용하는 방법을 보여준다.
[TestServer 프로젝트]
▶ IReportService.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 |
using System.ServiceModel; namespace TestServer { /// <summary> /// 리포트 서비스 /// </summary> [ServiceContract(CallbackContract = typeof(IReportServiceCallback))] public interface IReportService { //////////////////////////////////////////////////////////////////////////////////////////////////// Method #region 리포트 처리하기 - ProcessReport() /// <summary> /// 리포트 처리하기 /// </summary> [OperationContract] void ProcessReport(); #endregion } } |
▶ IReportServiceCallback.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 |
using System.ServiceModel; namespace TestServer { /// <summary> /// 리포트 서비스 콜백 인터페이스 /// </summary> public interface IReportServiceCallback { //////////////////////////////////////////////////////////////////////////////////////////////////// Method #region 진행하기 - Progress(percentage) /// <summary> /// 진행하기 /// </summary> /// <param name="percentage">백분율</param> [OperationContract] void Progress(int percentage); #endregion } } |
▶ ReportService.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 |
using System.ServiceModel; using System.Threading; namespace TestServer { /// <summary> /// 리포트 서비스 /// </summary> [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)] public class ReportService : IReportService { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 리포트 처리하기 - ProcessReport() /// <summary> /// 리포트 처리하기 /// </summary> public void ProcessReport() { for(int i = 1; i <= 100; i++) { Thread.Sleep(100); OperationContext.Current.GetCallbackChannel<IReportServiceCallback>().Progress(i); } } #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(ReportService))) { 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 |
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="mexBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="mexBehavior" name="TestServer.ReportService"> <endpoint address="ReportService" binding="netTcpBinding" contract="TestServer.IReportService" /> <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 |
using System; using System.Windows.Forms; using System.ServiceModel; using TestClient.ReportService; namespace TestClient { /// <summary> /// 메인 폼 /// </summary> [CallbackBehavior(UseSynchronizationContext = false)] public partial class MainForm : Form, IReportServiceCallback { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainForm() /// <summary> /// 생성자 /// </summary> public MainForm() { InitializeComponent(); this.processReportButton.Click += processReportButton_Click; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 진행하기 - Progress(percentage) /// <summary> /// 진행하기 /// </summary> /// <param name="percentage">백분율</param> public void Progress(int percentage) { this.progressTextBox.Text = percentage.ToString() + " % 완료"; } #endregion ////////////////////////////////////////////////////////////////////////////////////////// Private #region 리포트 처리하기 버튼 클릭시 처리하기 - processReportButton_Click(sender, e) /// <summary> /// 리포트 처리하기 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void processReportButton_Click(object sender, EventArgs e) { InstanceContext instanceContext = new InstanceContext(this); ReportServiceClient client = new ReportServiceClient(instanceContext, "NetTcpBinding_IReportService"); client.ProcessReport(); } #endregion } } |