2013-07-15 4 views
2

저는 Server-Application과 Client-Application간에 통신 할 수 있기를 원합니다. 두 응용 프로그램 모두 C#/WPF로 작성됩니다. 인터페이스는 두 응용 프로그램 모두에 대한 참조가있는 별도의 DLL에 있습니다.다른 프로세스에 메시지 보내기

Serializer<IDataInfo> serializer = new Serializer<IDataInfo>(); 
IDataInfo dataInfo = new DataInfo(HEADERBYTES, CONTENTBYTES); 
Process clientProcess = Process.Start("Client.exe", serializer.Serialize(dataInfo)); 

클라이언트 응용 프로그램이 가져옵니다

public interface IDataInfo 
    { 
     byte[] Header { get; } 
     byte[] Data { get; } 
    } 

이 서버 응용 프로그램은 다음과 같은 코드로 클라이언트를 호출 인터페이스 - DLL에

처럼 보이는 IDataInfo 인터페이스입니다 서버로부터의 메시지 :

Serializer<IDataInfo> serializer = new Serializer<IDataInfo>(); 
IDataInfo dataInfo = serializer.Deserialize(string.Join(" ", App.Args)); 

Serializer-Class는 단지 일반적인 c입니다. lass는 Soap-Formatter를 사용하여 직렬화/역 직렬 변환을 수행합니다. 코드는 다음과 같습니다.

public class Serializer<T> 
{ 
    private static readonly Encoding encoding = Encoding.Unicode; 

    public string Serialize(T value) 
    { 
     string result; 
     using (MemoryStream memoryStream = new MemoryStream()) 
     { 
      SoapFormatter soapFormatter = new SoapFormatter(); 
      soapFormatter.Serialize(memoryStream, value); 
      result = encoding.GetString(memoryStream.ToArray()); 
      memoryStream.Flush(); 
     } 
     return result; 
    } 

    public T Deserialize(string soap) 
    { 
     T result; 
     using (MemoryStream memoryStream = new MemoryStream(encoding.GetBytes(soap))) 
     { 
      SoapFormatter soapFormatter = new SoapFormatter(); 
      result = (T)soapFormatter.Deserialize(memoryStream); 
     } 
     return result; 
    } 
} 

여기까지 모든 것이 정상적으로 작동합니다. 서버는 클라이언트를 생성하고 클라이언트는 IDataInfo -Object에 대한 인수를 deserialize 할 수 있습니다.

이제 서버에서 실행중인 클라이언트로 메시지를 보내고 싶습니다. Interface DLL에 IClient-Interface를 도입했습니다. void ReceiveMessage(string message);

MainWindow.xaml.cs가 IClient-Interface를 구현하고 있습니다.

내 질문 이제 프로세스 개체가있을 때 내 서버에서 IClient 개체를 가져올 수 있습니다. 내가 Activator.CreateInstance에 대해 생각했지만, 나는 이것을 수행하는 방법을 모른다. 나는 IClient를 Process of Handle으로 얻을 수 있다고 확신하지만, 어떻게해야할지 모르겠다.

아이디어가 있으십니까?

+0

어떤 종류의 의사 소통 체계를 사용해야합니다. WCF에서 읽으십시오. –

답변

4

다른 게시물 일반적인 방법은 서비스를 만드는 것입니다 언급으로, 도 더 간단 내가 ServiceStack을 살펴 고려할 유지한다. AFAIK ServiceStack이 pluralsight

ServiceStack에 대해

이 또한 물론 유래에 사용됩니다 (IIS없이 등) 모든 .NET DLL에 호스트로 정말 쉽고 WCF의 구성의 복잡성이 없습니다 .

또한 엔드 포인트 아무것도를 구성 할 필요없이 SOAP과 REST로 사용할 수 있습니다

이 여기에 안녕하세요 세계 서비스

public class HelloService : IService<Hello> 
{ 
    public object Execute(Hello request) 
    { 
     return new HelloResponse { Result = "Hello, " + request.Name }; 
    } 
} 

클라이언트 코드의 예를 정의 예를 들어

:

var response = client.Send<HelloResponse>(new Hello { Name = "World!" }); 
Console.WriteLine(response.Result); // => Hello, World 

더 복잡한사례와 워크 스루는 ServiceStack.Hello

에서 찾을 수 있습니다.
1

다중 처리 사이의 통신에는 많은 처리가 필요합니다. 소켓, fileMapping, 메모리 공유, windows 32 메시지 등과 같습니다.

아마도 샘플 방식으로 WCF를 사용할 수 있습니다.

0

프로세스 간 통신을 수행하는 방법은 여러 가지가 있지만
입니다. 그러나 빠르고 쉬운 해결책을 찾고있는 경우 ZeroMQ를 살펴보아야 할 수 있습니다.
WCF도 옵션이지만 상황에 따라 과용 될 수 있습니다.

여기에 ZeroMQ에 대한 자세한 정보가 있습니다. http://www.zeromq.org/ 그리고 NuGet을 사용하여 프로젝트에 설치할 수 있습니다.

serverclient와 빠른 예 :

서버는 연결을 수신하는 문자열을 기대하고, 문자열을 반전하고 반환

public class Server 
{ 
    public Server() 
    { 

    } 

    public void Listen() 
    { 
     Task.Run(() => 
     { 
      using (var context = new Context()) 
      { 
       //Open a socket to reply 
       using (var socket = context.Socket(SocketType.REP)) 
       { 
        socket.Bind("tcp://127.0.0.1:32500"); 
        while (true) 
        { 
         //Again you could also receive binary data if you want 
         var request = socket.Recv(Encoding.UTF8); 
         var response = ReverseString(request); 
         socket.Send(response, Encoding.UTF8); 
        } 
       } 
      } 
     }); 
    } 

    private string ReverseString(string request) 
    { 
     var chars = request.ToCharArray(); 
     Array.Reverse(chars); 
     return new string(chars); 
    } 
} 

클라이언트가 서버에 연결 (에 이 경우 동일한 시스템) :

public class Client 
{ 
    public Client() 
    { 

    } 

    public string ReverseString(string message) 
    { 
     using (var context = new Context()) 
     { 
      //Open a socket to request data 
      using (var socket = context.Socket(SocketType.REQ)) 
      { 
       socket.Connect("tcp://127.0.0.1:32500"); 

       //Send a string, you can send a byte[] as well, for example protobuf encoded data 
       socket.Send(message, Encoding.UTF8); 

       //Get the response from the server 
       return socket.Recv(Encoding.UTF8); 
      } 
     } 
    } 
} 

그것을 테스트하려면, 프로그램은 다음과 같습니다

public class Program 
{ 
    public static void Main() 
    { 
     new Program(); 
    } 

    public Program() 
    { 
     var server = new Server(); 
     server.Listen(); 

     var client = new Client(); 

     var input = String.Empty; 

     while (input != "/quit") 
     { 
      input = Console.ReadLine(); 
      Console.WriteLine(client.ReverseString(input)); 
     } 
    } 

} 

쉽고 완료되었습니다.

또 다른 대안은 IPC에 대한 명명 된 파이프를 사용하는 것입니다 http://www.codeproject.com/Tips/492231/Csharp-Async-Named-Pipes

관련 문제