简体   繁体   English

发送消息到其他进程

[英]Send Message to other Process

I want to be able to communicate between a Server-Application and a Client-Application. 我希望能够在服务器应用程序和客户端应用程序之间进行通信。 Both applications are written in C#/WPF. 这两个应用程序都是用C#/ WPF编写的。 Interfaces are located in a separate DLL where both applications have a reference to it. 接口位于单独的DLL中,两个应用程序都对其进行引用。

In the interface-dll is the IDataInfo-Interface which looks like: 在interface-dll中是IDataInfo-Interface,看起来像:

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

The Server-Application calls the client by the following code: 服务器应用程序通过以下代码调用客户端:

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

The Client-Applications gets the message from the server by: 客户端应用程序通过以下方式从服务器获取消息:

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

The Serializer-Class is just a generic class which uses the Soap-Formatter to serialize/deserialze. Serializer-Class只是一个通用类,它使用Soap-Formatter进行序列化/反序列化。 The code looks like: 代码如下:

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

Until here everything works fine. 到这里为止,一切正常。 The server creates the client and the client can deserialize it's argument to the IDataInfo -Object. 服务器创建客户端,客户端可以将其参数反序列化到IDataInfo -Object。

Now I want to be able to send a message from the server to a running client. 现在,我希望能够从服务器向正在运行的客户端发送消息。 I Introduced the IClient-Interface in the Interface-DLL with the method void ReceiveMessage(string message); 我用方法void ReceiveMessage(string message);在Interface-DLL中引入了IClient接口void ReceiveMessage(string message);

The MainWindow.xaml.cs is implementing the IClient-Interface. MainWindow.xaml.cs正在实现IClient-Interface。

My Question is now how can I get the IClient-Object in my server, when I just have the Process-Object. 我的问题是,当我只有过程对象时,如何在服务器中获取IClient对象。 I thought about Activator.CreateInstance , but I have no clue how to do this. 我想到了Activator.CreateInstance ,但是我不知道如何执行此操作。 I'm pretty sure that I can get the IClient by the Handle of the Process, but I don't know how. 我很确定我可以通过流程的句柄来获取IClient,但是我不知道如何。

Any idea? 任何想法?

As the other posts mention a common way is to create a service, too keep it more simple I would consider a look at ServiceStack . 正如其他文章提到的,一种常见的方法是创建服务,但也要使其更加简单,所以我考虑考虑一下ServiceStack AFAIK ServiceStack is used on stackoverflow AFAIK ServiceStack用于stackoverflow

There also as course about it on pluralsight 当然也有关于多元观点的课程

ServiceStack is really easy to host in any .net dll (without iis and so on) and doesn't have the configuration complexity of WCF. ServiceStack确实很容易托管在任何.net dll中(没有iis等),并且不具有WCF的配置复杂性。

Also endpoints are available as SOAP and REST without the need to configure anything 端点也可以用作SOAP和REST,而无需进行任何配置

For Example this defines a hello world service 例如,这定义了一个hello world服务

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

Here an example of the client code: 这是客户端代码的示例:

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

You can find more complex examples and walk-throughs at: ServiceStack.Hello 您可以在以下位置找到更复杂的示例和演练: ServiceStack.Hello

Communication that between multi processed have many waies to implement. 多处理之间的通信有很多实现方法。 Like socket, fileMapping, share memory, windows 32 message and so on. 如套接字,文件映射,共享内存,Windows 32消息等。

Maybe sample way is you can use WCF. 也许示例方法是您可以使用WCF。

There are many ways to do inter process communication, 进行进程间通信的方法很多,
but if you are looking for a quick and easy solution you may want to look at ZeroMQ. 但是,如果您正在寻找一种快速简便的解决方案,则可能需要查看ZeroMQ。
WCF is also an option but it might be overkill in your situation. WCF也是一种选择,但是在您所处的环境中它可能会显得过大。

You can find more information about ZeroMQ here: http://www.zeromq.org/ And you can install it into your project using NuGet. 您可以在此处找到有关ZeroMQ的更多信息: http ://www.zeromq.org/并可以使用NuGet将其安装到项目中。

A quick example with a server and a client : 一个带有serverclient简单示例:

The server listens for connections, expects a string, reverses the string and returns it: 服务器侦听连接,期望一个字符串,反转该字符串并返回它:

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

The client connects to the server (in this case the same machine): 客户端连接到服务器(在本例中为同一台计算机):

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

To test it, the program might look like this: 要对其进行测试,该程序可能如下所示:

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

}

It's easy and it gets the job done. 这很容易,并且可以完成工作。

Another alternative is to use named pipes for IPC: http://www.codeproject.com/Tips/492231/Csharp-Async-Named-Pipes 另一种选择是对IPC使用命名管道: http : //www.codeproject.com/Tips/492231/Csharp-Async-Named-Pipes

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 向没有窗口的进程发送 WM_CLOSE 消息 - Send WM_CLOSE message to a process with no window 将消息发送到Windows进程(而不是其主窗口) - Send message to a Windows process (not its main window) 发送命令以停止C#中的其他进程 - Send command to stop other process in C# Zeromq进程内通信 - 如何发送参考消息? - Zeromq in-process communication - how to send a reference-message? Akka.NET:无法向其他ActorSystem发送列表消息 - Akka.NET: can't send a list message to other ActorSystem 需要通过WebSocket向其他用户而非发件人发送消息 - Need to send message to other users, not the sender, over websocket Azure 服务总线每隔一段时间发送消息 - Azure Service Bus send message every other time 如何通过进程 ID 而不是窗口句柄向特定进程发送消息? - How can I send a message to a specific process by process id rather than by window handle? 从主UWP进程终止UWP应用的Win32进程,或向其发送消息 - Terminate the win32 process of UWP app from main UWP process, or send message to it 如何在发送端口上设置一个过滤器,如果由我的业务流程中的早期发送端口处理,则该过滤器不会处理该消息? - How can I set a filter on send port that will not process the message if handled by an earlier send port in my orchestration?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM