C# 向其他进程发送消息

C# 向其他进程发送消息,c#,wpf,inter-process-communicat,C#,Wpf,Inter Process Communicat,我希望能够在服务器应用程序和客户端应用程序之间进行通信。这两个应用程序都是用C#/WPF编写的。接口位于一个单独的DLL中,两个应用程序都有对它的引用 接口dll中的IDataInfo接口如下所示: public interface IDataInfo { byte[] Header { get; } byte[] Data { get; } } public class Serializer<T> { private sta

我希望能够在服务器应用程序和客户端应用程序之间进行通信。这两个应用程序都是用C#/WPF编写的。接口位于一个单独的DLL中,两个应用程序都有对它的引用

接口dll中的IDataInfo接口如下所示:

public interface IDataInfo
    {
        byte[] Header { get; }
        byte[] Data { get; }
    }
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;
    }
}
服务器应用程序通过以下代码调用客户端:

Serializer<IDataInfo> serializer = new Serializer<IDataInfo>();
IDataInfo dataInfo = new DataInfo(HEADERBYTES, CONTENTBYTES);
Process clientProcess = Process.Start("Client.exe", serializer.Serialize(dataInfo));
Serializer Serializer=new Serializer();
IDataInfo dataInfo=新数据信息(HEADERBYTES,CONTENTBYTES);
Process clientProcess=Process.Start(“Client.exe”,serializer.Serialize(dataInfo));
客户端应用程序通过以下方式从服务器获取消息:

Serializer<IDataInfo> serializer = new Serializer<IDataInfo>();
IDataInfo dataInfo = serializer.Deserialize(string.Join(" ", App.Args));
Serializer Serializer=new Serializer();
IDataInfo dataInfo=serializer.Deserialize(string.Join(“,App.Args));
Serializer类只是一个泛型类,它使用Soap格式化程序进行序列化/反序列化。代码如下所示:

public interface IDataInfo
    {
        byte[] Header { get; }
        byte[] Data { get; }
    }
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;
    }
}
公共类序列化程序
{
私有静态只读编码=Encoding.Unicode;
公共字符串序列化(T值)
{
字符串结果;
使用(MemoryStream MemoryStream=new MemoryStream())
{
SoapFormatter SoapFormatter=新的SoapFormatter();
序列化(memoryStream,value);
结果=encoding.GetString(memoryStream.ToArray());
memoryStream.Flush();
}
返回结果;
}
公共T反序列化(字符串soap)
{
T结果;
使用(MemoryStream MemoryStream=newmemoryStream(encoding.GetBytes(soap)))
{
SoapFormatter SoapFormatter=新的SoapFormatter();
结果=(T)soapFormatter.Deserialize(memoryStream);
}
返回结果;
}
}
在这之前一切都很好。服务器创建客户机,客户机可以将其参数反序列化为
IDataInfo
-对象

现在,我希望能够从服务器向正在运行的客户端发送消息。我使用方法
void ReceiveMessage(string message)在接口DLL中引入了IClient接口

MainWindow.xaml.cs正在实现IClient接口

我现在的问题是,当我只有Process对象时,如何在服务器中获取IClient对象。我考虑过
Activator.CreateInstance
,但我不知道该怎么做。我很确定我可以通过处理这个过程来获得IClient,但我不知道怎么做


有什么想法吗?

多处理器之间的通信需要实现许多WAIE。 像套接字、文件映射、共享内存、Windows32消息等等


可能示例方法是您可以使用WCF。

有许多方法可以进行进程间通信,
但是,如果您正在寻找一种快速简便的解决方案,您可能需要查看ZeroMQ。
WCF也是一种选择,但在您的情况下,它可能会有些过头

您可以在此处找到有关ZeroMQ的更多信息: 您可以使用NuGet将其安装到项目中

一个带有
服务器
客户端
的快速示例:

服务器侦听连接,需要字符串,反转字符串并返回:

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 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使用命名管道:

,因为其他帖子提到一种常见的方法是创建服务, 太简单了,我会考虑一下。AFAIK ServiceStack用于stackoverflow

也有关于它的课程

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 };
    }
}
public类HelloService:IService
{
公共对象执行(Hello请求)
{
返回新的HelloResponse{Result=“Hello,”+request.Name};
}
}
下面是客户机代码的示例:

var response = client.Send<HelloResponse>(new Hello { Name = "World!" });
Console.WriteLine(response.Result); // => Hello, World
var response=client.Send(newhello{Name=“World!”);
Console.WriteLine(response.Result);//=>你好,世界
你可以找到更多
复杂的示例和演练:

您需要使用某种通信方案。阅读WCF。