发送消息到其他进程

问题描述:

我希望能够在服务器应用程序和客户端应用程序之间进行通信。这两个应用程序都是用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。 –

正如其他职位提到的常用方法是创建一个服务, 也保持它更加简单,我会考虑看看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

多处理之间的通信有很多实现的缺陷。 像socket,fileMapping,共享内存,Windows 32消息等。

也许样本方式是你可以使用WCF。

有很多方法可以进行进程间通信,
但是如果您正在寻找一个快速简单的解决方案,您可能需要查看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