简体   繁体   中英

MessagePack RPC C# - Server side

I have a problem when trying to consume a server implementation of MessagePack RPC . I wrote one implementation for client and one for server based on a Python code provided by my company's client.

The server implementation should be consumed by Python, but as far as I see that won't be a problem.

Server implementation:

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

Client implementation:

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

}

My client can't connect to my server, it can't see the methods over there. The error is: "operation does not exist".

Anyone has any clue?

Thank you!!

Well after many tries and many help from friends, I finally managed to fix the issue. First of all you have to download the Message Pack RPC solution here and create your new project (server or client) inside this solution. In my case the server didn't work when I created a new solution and referenced the dlls, only inside the whole project. The client worked only referencing the dlls.

Implementation for the Server Side :

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

Implementation for the Client Side :

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

I hope this is clear and help you guys to fix it. Don't forget to set the methods as public on the server. Thanks to https://github.com/yfakariya /msgpack-rpc-cli/issues/6 that answered my question. Really special thanks to @DanielGroh that spent some time with me trying to fix it and Gilmar Pereira which has no profile here but is a great developer and helped me a lot (https:// www. facebook .com/ gilmarps?fref=ts).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM