2016-01-11 4 views
0

У меня возникла проблема при попытке использовать серверную версию MessagePack RPC. Я написал одну реализацию для клиента и одну для сервера на основе кода Python, предоставленного клиентом моей компании.MessagePack RPC C# - сторона сервера

Реализация сервера должна потребляться Python, но, насколько я вижу, это не будет проблемой.

реализация сервера: реализация

public class Program 
{ 

    static void Main(string[] args) 
    { 
     try 
     { 
      DefaultServiceTypeLocator def = new DefaultServiceTypeLocator(); 
      ServiceTypeLocator ser = def; 

      def.AddService(new Methods().GetType()); 
      var services = ser.FindServices(); 

      var configuration = new RpcServerConfiguration(); 

      IPAddress ipAddress = GetIp(); 
      configuration.BindingEndPoint = new IPEndPoint(ipAddress, 8089); 
      Console.WriteLine(new IPEndPoint(ipAddress, 8089).ToString()); 
      using (var server = new RpcServer(configuration)) 
      { 
       server.Start(); 

       Console.ReadKey(); 
      } 
     } 
     catch (Exception ex) 
     { 

      Console.Write(ex); 
      Console.ReadKey(); 
     } 
} 
[MessagePackRpcServiceContractAttribute] 
public class Methods 
{ 
    [MessagePackRpcMethodAttribute] 
    public int hello0() 
    { 
     Console.WriteLine("hello0"); 
     return 0; 
    } 
} 

Клиент:

public class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      var configuration = new RpcClientConfiguration(); 
      IPAddress ipAddress = GetIp(); 

      using (dynamic proxy = new DynamicRpcProxy(new IPEndPoint(ipAddress, 8089), configuration)) 
      { 
       dynamic res = proxy.hello0(); 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex); 
      Console.ReadKey(); 
     } 
    } 

    private static IPAddress GetIp() 
    { 
     string myHost = System.Net.Dns.GetHostName(); 
     IPAddress myIP = null; 

     for (int i = 0; i <= System.Net.Dns.GetHostEntry(myHost).AddressList.Length - 1; i++) 
     { 
      if (System.Net.Dns.GetHostEntry(myHost).AddressList[i].IsIPv6LinkLocal == false) 
      { 
       if (System.Net.Dns.GetHostEntry(myHost).AddressList[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) 
        myIP = System.Net.Dns.GetHostEntry(myHost).AddressList[i]; 
      } 
     } 
     return myIP; 
    } 

} 

Мой клиент не может подключиться к серверу, он не может видеть методы там. Ошибка: «операция не существует».

У кого-нибудь есть ключ?

спасибо !!

+1

Вам необходимо настроить ServiceTypeLocator с помощью 'DefaultServiceTypeLocator'. Добавьте класс, который вы хотите открыть, используя '.AddService()' – Caramiriel

+0

Hi @Caramiriel, Спасибо за ваш комментарий! Я сделал то, что вы сказали (я думаю), и я также добавил атрибуты метода и класса, но все равно не мог этого сделать = ( –

+1

@MarianePinheiro, пожалуйста, после внесения изменений в свой код, предоставьте обновление, чтобы мы могли понять, что именно был изменен – DAG

ответ

1

После многих попыток и много помощи от друзей я, наконец, смог исправить эту проблему. Прежде всего, вы должны загрузить Message Pack RPC решение here и создать свой новый проект (сервер или клиент) внутри этого решения. В моем случае сервер не работал, когда я создал новое решение и ссылался на DLL, только внутри всего проекта. Клиент работал только с ссылкой на DLL.

Реализация на стороне сервера :

internal class Program 
{ 
    public static void Main(string[] args1) 
    { 
     var config = new RpcServerConfiguration(); 

     config.BindingEndPoint = new IPEndPoint(IPAddress.Loopback, 8089); 

     config.PreferIPv4 = true; 

     config.IsDebugMode = true; 
//UseFullMethodName is a property that if it is false allows you in the CLIENT to call the   methods only by it's name, check example further. 
     config.UseFullMethodName = false; 

     var defaultServiceTypeLocator = new DefaultServiceTypeLocator(); 

     //Methods is the class I created with all the methods to be called. 
     defaultServiceTypeLocator.AddService(typeof(Methods)); 

     config.ServiceTypeLocatorProvider = conf => defaultServiceTypeLocator; 

     using (var server = new RpcServer(config)) 
     { 
      server.Start(); 
      Console.ReadKey(); 
     } 
} 

[MessagePackRpcServiceContract] //Define the contract to be used 
public class Methods 
{ 
    [MessagePackRpcMethod] //Define the methods that are going to be exposed 
    public string Hello() 
    { 
     return "Hello"; 
    } 
    [MessagePackRpcMethod] 
    public string HelloParam(string i) 
    { 
     return "Hello " + i; 
    } 
} 

Реализация для стороне клиента:

static void Main(string[] args) 
    { 

     using (var target = CreateClient()) 
     { 

      //var result1 = target.Call("Hello:Methods:0", null); /*if in the server the property UseFullMethodName is true, or not defined as false (default is true) you have to call the method on the server using *methodname:class:version**/ 
      var result2 = target.Call("Hello", null); //Parameter is null 
      var result3 = target.Call("HelloParam", “Mariane”);//Method with parameter 
     } 

    } 

    public static RpcClient CreateClient() 
    { 
     return new RpcClient(new IPEndPoint(IPAddress.Loopback, 8089), new RpcClientConfiguration() { PreferIPv4 = true }); 
    } 

Я надеюсь, что это ясно и поможет вам, ребята, чтобы это исправить. Не забудьте установить методы как общедоступные на сервере. Спасибо https://github.com/yfakariya /msgpack-rpc-cli/issues/6, который ответил на мой вопрос. Действительно, особая благодарность @DanielGroh, которая провела некоторое время со мной, пытаясь исправить это, и Gilmar Pereira, у которой нет профиля здесь, но является отличным разработчиком и очень помог мне (https: // www. Facebook .com/gilmarps? Fref = ts).

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