Search code examples
c#wpfinter-process-communicat

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. Interfaces are located in a separate DLL where both applications have a reference to it.

In the interface-dll is the IDataInfo-Interface which looks like:

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. 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.

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

The MainWindow.xaml.cs is implementing the IClient-Interface.

My Question is now how can I get the IClient-Object in my server, when I just have the Process-Object. I thought about Activator.CreateInstance, but I have no clue how to do this. I'm pretty sure that I can get the IClient by the Handle of the Process, but I don't know how.

Any idea?


Solution

  • 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. AFAIK ServiceStack is used on 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.

    Also endpoints are available as SOAP and REST without the need to configure anything

    For Example this defines a hello world service

    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