2016-01-11 59 views
0

嘗試使用服務器實現MessagePack RPC時遇到問題。我根據我公司客戶提供的Python代碼爲客戶端和服務器編寫了一個實現。MessagePack RPC C# - 服務器端

服務器實現應該由Python使用,但據我所知,這不會是一個問題。

Server實現:

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

您必須使用'DefaultServiceTypeLocator'設置ServiceTypeLocator。使用'.AddService()'添加你想暴露的類' – Caramiriel

+0

Hi @Caramiriel,謝謝你的評論!我做了你所說的(我認爲),我也添加了方法和類屬性,但仍然不能這樣做=( –

+1

@MarianePinheiro請在對代碼進行更改後提供更新,以便我們可以得知究竟是什麼已被更改 – DAG

回答

1

好多次嘗試和朋友的幫助後,我終於設法解決這個問題。 首先,您必須下載消息包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 )。