2013-07-15 174 views
2

我希望能夠在服務器應用程序和客戶端應用程序之間進行通信。這兩個應用程序都是用C#/ WPF編寫的。接口位於一個單獨的DLL中,兩個應用程序都有一個對它的引用。發送消息到其他進程

在接口DLL是IDataInfo接口看起來像:

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

服務器應用程序通過下面的代碼調用客戶端來自服務器的消息:

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

Serializer-Class只是一個通用的c使用Soap-Formatter序列化/反序列化的lass。該代碼看起來像:

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。

現在我想能夠從服務器發送消息到正在運行的客戶端。我在Interface-DLL中引入了IClient接口,方法爲void ReceiveMessage(string message);

MainWindow.xaml.cs正在實現IClient接口。

我的問題是現在我怎麼才能在我的服務器中獲得IClient對象,當我只有Process-Object時。我想過Activator.CreateInstance,但我不知道如何做到這一點。我很確定我可以通過處理流程獲得IClient,但我不知道如何。

有什麼想法?

+0

你需要使用某種通信方案。閱讀WCF。 –

回答

4

正如其他職位提到的常用方法是創建一個服務, 也保持它更加簡單,我會考慮看看ServiceStack。據我所知ServiceStack是

還有當然使用計算器上關於它的pluralsight

ServiceStack是很容易在任何.NET的DLL到主機(沒有IIS等),並沒有WCF的配置複雜度。

也端點可作爲SOAP和REST,而無需進行任何配置

例如,這定義了一個Hello World服務

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

多處理之間的通信有很多實現的缺陷。 像socket,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