c# 예제 - 두 .Net 응용 프로그램 간의 효율적인 통신




2 Answers

성능에 대해 걱정할 필요가 없습니다. wcf가 올바르게 구성되어 있으면 처리량이 매우 높아질 수 있습니다. 이벤트에 콜백을 사용하십시오. http://www.switchonthecode.com/tutorials/wcf-tutorial-events-and-callbacks

만들기 이벤트

저는 현재 C #에서 .Net 응용 프로그램을 작성 중이며 두 가지 주요 구성 요소가 있습니다.

  1. DataGenerator - 많은 양의 데이터를 생성하는 구성 요소
  2. 뷰어 - 생성기에서 생성 한 데이터를 시각화 할 수있는 WPF 응용 프로그램

이 두 구성 요소는 현재 내 솔루션에서 두 개의 개별 프로젝트입니다. 또한 PRISM 4.0 프레임 워크를 사용하여 해당 구성 요소에서 모듈을 만들었습니다.

본질적으로 DataGenerator는 많은 양의 데이터를 생성하고 PRISM의 EventAggregator 를 사용하여 이벤트를 전송하며 뷰어는 이러한 이벤트를 구독하고 사용자가 사용할 수있는 데이터를 표시합니다.

이제 나의 요구 사항이 약간 변경되었고 두 구성 요소가 이제 자신의 응용 프로그램에서 실행됩니다 (그러나 동일한 컴퓨터에서 실행). 나는 여전히 모든 커뮤니케이션을 이벤트 중심으로하고 싶습니다. 그리고 저는 여전히 PRISM 프레임 워크를 사용하고 싶습니다.

내 첫 번째 생각은 두 응용 프로그램 간의 통신을 위해 WCF 를 사용하는 것이 었습니다. 그러나 인생을 조금 더 어렵게 만드는 한 가지가 있습니다.

  1. DataGenerator는 뷰어에 대한 지식 이 전혀 없으며 ( 종속성이 없음 )
  2. 뷰어를 열지 않았거나 뷰어 응용 프로그램을 닫을 경우 DataGenerator는 여전히 완벽하게 작동해야합니다.
  3. 현재 EventAggregator를 사용하여 DataGenerator에서 많은 이벤트가 발생하고 있습니다. WCF는 매우 짧은 시간에 많은 이벤트를 처리 할만큼 효율적입니까?

기본적으로 모든 이벤트가 수행하는 데이터는 매우 간단한 문자열, 정수 및 부울입니다. WCF없이이 작업을 수행하는 데 좀 더 가벼운 방법이있을 수 있습니까?

마지막으로, DataGenerator가 이러한 이벤트를 보낼 수 있고 둘 이상의 어플리케이션이 잠재적으로 하나 이상의 어플리케이션을 등록 할 수 있다면 좋을 것입니다.

모든 제안 및 힌트를 높이 평가합니다.

감사! 신자

EDIT 1

나는 이제 WCF와 콜백을 사용하여 두 개의 간단한 콘솔 응용 프로그램 (하나는 서비스 호스팅 및 메시지 전송, 다른 하나는 메시지 수신)을 작성하고 있습니다 (제안 된대로). 이 코드가 작동하자마자 작업 코드를 추가 할 것입니다.

2 번 수정

좋아요 - 간단한 프로그램 실행을 관리했습니다! :) 도와 줘서 고마워! 다음은 클래스와 클래스의 코드 및 그림입니다.

발신자부터 시작하겠습니다.

내 응용 프로그램에서는 보낸 사람이 서비스 인터페이스와 해당 구현을 포함합니다.

IMessageCallback은 콜백 인터페이스입니다.

namespace WCFSender
{
    interface IMessageCallback
    {
        [OperationContract(IsOneWay = true)]
        void OnMessageAdded(string message, DateTime timestamp);
    }
}

ISimpleService는 서비스 계약입니다.

namespace WCFSender
{
    [ServiceContract(CallbackContract = typeof(IMessageCallback))]
    public interface ISimpleService
    {
        [OperationContract]
        void SendMessage(string message);

        [OperationContract]
        bool Subscribe();

        [OperationContract]
        bool Unsubscribe();
    }
}

SimpleService는 ISimpleService를 구현 한 것입니다.

public class SimpleService : ISimpleService
    {
        private static readonly List<IMessageCallback> subscribers = new List<IMessageCallback>();

        public void SendMessage(string message)
        {
            subscribers.ForEach(delegate(IMessageCallback callback)
            {
                if (((ICommunicationObject)callback).State == CommunicationState.Opened)
                {
                    callback.OnMessageAdded(message, DateTime.Now);
                }
                else
                {
                    subscribers.Remove(callback);
                }
            });
        }

        public bool Subscribe()
        {
            try
            {
                IMessageCallback callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
                if (!subscribers.Contains(callback))
                    subscribers.Add(callback);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool Unsubscribe()
        {
            try
            {
                IMessageCallback callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
                if (!subscribers.Contains(callback))
                    subscribers.Remove(callback);
                return true;
            }
            catch
            {
                return false;
            }
        }
    }

Program.cs (보낸 사람 쪽)에서 서비스가 호스팅되고 메시지가 보내집니다.

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
    class Program : SimpleServiceReference.ISimpleServiceCallback, IDisposable
    {
        private SimpleServiceClient client;

        static void Main(string[] args)
        {
            ServiceHost myService = new ServiceHost(typeof(SimpleService));
            myService.Open();
            Program p = new Program();
            p.start();

            Console.ReadLine();
        }

        public void start()
        {
            InstanceContext context = new InstanceContext(this);

            client = new SimpleServiceReference.SimpleServiceClient(context, "WSDualHttpBinding_ISimpleService");

            for (int i = 0; i < 100; i++)
            {
                client.SendMessage("message " + i);
                Console.WriteLine("sending message" + i);
                Thread.Sleep(600);
            }
        }

        public void OnMessageAdded(string message, DateTime timestamp)
        {
            throw new NotImplementedException();
        }

        public void Dispose()
        {
            client.Close();
        }
    }

또한 서비스 참조가 Sender 프로젝트에 추가되었습니다.

이제 수신자 측에 도달 할 수 있습니다.

Sender에서 이미 수행 된 것처럼, 나는 Service Reference를 프로젝트에 추가했다.

Program.cs 클래스는 하나뿐입니다.

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
    class Program : SimpleServiceReference.ISimpleServiceCallback, IDisposable
    {
        private SimpleServiceClient client;

        static void Main(string[] args)
        {
            Program p = new Program();
            p.start();
            Console.ReadLine();
            p.Dispose();
        }

        public void start()
        {
            InstanceContext context = new InstanceContext(this);

            client = new SimpleServiceReference.SimpleServiceClient(context, "WSDualHttpBinding_ISimpleService");
            client.Subscribe();
        }

        public void OnMessageAdded(string message, DateTime timestamp)
        {
            Console.WriteLine(message + " " + timestamp.ToString());
        }

        public void Dispose()
        {
            client.Unsubscribe();
            client.Close();
        }
    }

마지막으로 남아있는 것은 app.config 파일입니다. 클라이언트 측에서는 서비스 참조를 추가하여 app.config가 자동으로 생성됩니다. 서버 측에서는 config를 약간 변경했지만 일부는 서비스 참조를 추가하여 자동 생성됩니다. 서비스 참조를 추가하기 전에 변경 작업을 수행해야합니다.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <wsDualHttpBinding>
                <binding name="WSDualHttpBinding_ISimpleService" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00" />
                    <security mode="Message">
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" />
                    </security>
                </binding>
            </wsDualHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8732/Design_Time_Addresses/WCFSender/SimpleService/"
                binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_ISimpleService"
                contract="SimpleServiceReference.ISimpleService" name="WSDualHttpBinding_ISimpleService">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
        </client>
        <behaviors>
            <serviceBehaviors>
                <behavior name="MessageBehavior">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service name="WCFSender.SimpleService" behaviorConfiguration="MessageBehavior">
                <endpoint address="" binding="wsDualHttpBinding" contract="WCFSender.ISimpleService">
                    <identity>
                        <dns value="localhost" />
                    </identity>
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8732/Design_Time_Addresses/WCFSender/SimpleService/" />
                    </baseAddresses>
                </host>
            </service>
        </services>
    </system.serviceModel>
</configuration>

중요 : 튜토리얼을 사용하여이 두 개의 매우 간단한 애플리케이션을 구현할 수있었습니다. 위의 코드는 저에게 효과적이며 다른 사람들이 WCF 콜백을 이해할 수 있도록 도와줍니다. 그것은 매우 잘 작성된 코드가 아니며 전적으로 사용되어서는 안됩니다! 그것은 단순한 예제 응용 프로그램입니다.




Microsoft StreamInsight 1.2를 사용하십시오. 사용 사례는 응용 프로그램, WCF 서비스 또는 둘 다에 포함 할 수 있음을 설명합니다.

MSDN 문서보기 abou StreamInsight 1.2 :

Microsoft® StreamInsight는 Microsoft의 복잡한 이벤트 처리 기술로 기업이 이벤트 기반 응용 프로그램을 만들고 여러 소스의 이벤트 스트림을 거의 제로 대기 시간과 연관시켜 더 나은 통찰력을 이끌어 낼 수 있도록 지원합니다.

Microsoft StreamInsight ™는 복잡한 이벤트 처리 (CEP) 응용 프로그램을 개발하고 배포하는 데 사용할 수있는 강력한 플랫폼입니다. 처리량이 많은 스트림 처리 아키텍처와 Microsoft .NET Framework 기반 개발 플랫폼을 사용하면 견고하고 효율적인 이벤트 처리 응용 프로그램을 신속하게 구현할 수 있습니다. 이벤트 스트림 소스에는 일반적으로 제조 응용 프로그램, 금융 거래 응용 프로그램, 웹 분석 및 운영 분석의 데이터가 포함됩니다. StreamInsight를 사용하면 데이터 추출, 분석 및 상관 비용을 줄임으로써이 원시 데이터에서 즉각적인 비즈니스 가치를 창출하는 CEP 응용 프로그램을 개발할 수 있습니다. 상황, 기회 및 결함에 대한 데이터를 거의 즉시 모니터링, 관리 및 마이닝 할 수 있습니다.

StreamInsight를 사용하여 CEP 응용 프로그램을 개발하면 비즈니스에 다음과 같은 전략적 목표를 달성 할 수 있습니다.

  • 의미있는 패턴, 추세, 예외 및 기회를 위해 여러 소스에서 데이터를 모니터링하십시오.

  • 데이터가 진행되는 동안, 즉 처음 저장하지 않고 데이터를 점진적으로 분석하고 상호 연관시켜 매우 낮은 대기 시간을 제공합니다. 여러 소스의 관련없는 이벤트를 집계하고 시간이 지남에 따라 매우 복잡한 분석을 수행합니다.

  • 이벤트에 대한 대기 시간이 짧은 분석을 수행하고 비즈니스 핵심 성과 지표 (KPI)에 정의 된 대응 조치를 트리거하여 비즈니스를 관리하십시오.

  • KPI 정의를 CEP 응용 프로그램의 논리에 통합하여 기회 또는 위협 영역에 신속하게 대응함으로써 운영 효율성과 비즈니스 기회에 신속하게 대응할 수있는 능력을 향상시킵니다.

  • 새로운 비즈니스 KPI에 대한 내 이벤트.

  • 기록 데이터를 마이닝하여 예측 비즈니스 모델로 이동하여 KPI 정의를 지속적으로 구체화하고 향상시킵니다.

CodePlex 에서 추가 정보 및 샘플을 찾을 수 있습니다.




Related

c# .net wcf prism