2013-07-15 3 views
2

Я хочу иметь возможность связываться между серверным приложением и клиентским приложением. Оба приложения написаны на C#/WPF. Интерфейсы расположены в отдельной DLL, где оба приложения имеют ссылку на нее.Отправить сообщение другому процессу

В интерфейсной-DLL является IDataInfo-интерфейс, который выглядит следующим образом:

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

Сервер-приложений вызывает клиент следующим кодом:

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

Клиентские-Applications Получает сообщение с сервера:

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

Сериализатор-класс - это всего лишь универсальный класс whi ch использует мыло-форматирование для сериализации/десериала. Код выглядит так:

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.

Теперь я хочу иметь возможность отправлять сообщение с сервера на работающего клиента. I Введен интерфейс IClient в интерфейсе DLL со способом void ReceiveMessage(string message);

MainWindow.xaml.cs реализует интерфейс IClient.

Вопрос: Как я могу получить объект IClient-Object на моем сервере, когда у меня есть только Process-Object. Я думал о Activator.CreateInstance, но я понятия не имею, как это сделать. Я уверен, что могу получить IClient с помощью Handle of Process, но я не знаю, как это сделать.

Есть идеи?

+0

Вам нужно использовать какую-то схему связи. Читайте в WCF. –

ответ

4

Как другие должности упомянуть общий способ создать службу, слишком держать его более простым, я бы рассмотреть взгляд на ServiceStack. AFAIK ServiceStack используется на StackOverflow

Там также, как курс об этом на pluralsight

ServiceStack очень легко разместить в любой DLL .net (без IIS и так далее) и не имеет сложности конфигурации WCF ,

Также конечные точки доступны как SOAP и REST без необходимости ничего настраивать

Для примера это определяет привет мир службы

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

Коммуникация между обработанной обработкой имеет много вариантов для реализации. Как сокет, fileMapping, общая память, сообщения Windows 32 и т. Д.

Возможно, образцовым способом является использование WCF.

0

Существует много способов взаимодействия между процессами,
, но если вы ищете быстрое и простое решение, вы можете посмотреть на ZeroMQ.
WCF также является вариантом, но в вашей ситуации это может быть излишним.

Дополнительную информацию о ZeroMQ можно найти здесь: http://www.zeromq.org/ И вы можете установить его в свой проект с помощью NuGet.

Быстрый пример с server и client:

Сервер прослушивает соединения, ожидает строку, переворачивает строку и возвращает его:

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

} 

Это очень легко, и он выполняет свою работу.

Другой альтернативой является использование именованных каналов для МПК: http://www.codeproject.com/Tips/492231/Csharp-Async-Named-Pipes

Смежные вопросы