Xamarin使XRPC实现接口/委托远程调用

佐手、 提交于 2021-01-10 12:36:14

        在之前的文章中已经介绍如何使用Beetlex.XRCP组件进行接口/委托远程调用;由于组件BeetleX.XRPC.Clients支持.NETStandard2,因此Xamarin同样可以使用它来实现基于接口/委托的数据交互通讯。

        接下来通过Xamarin实现一个简单的移动程序,并通过XRPC的功能基于远程接口调用的方式登陆到服务端,然后再通过委托远程调用的方式来相互获取对方的系统和时间信息。

服务端定义

        服务主要定义一个用户接口并实现登陆方法,然后注册一个委托用于返回服务信息和时间给客户端。

class Program
{
    static void Main(string[] args)
    {
        var builder = new HostBuilder()
        .ConfigureServices((hostContext, services) =>
        {
            //开
            services.UseXRPC(
                s =>
                {
                    s.ServerOptions.LogLevel = BeetleX.EventArgs.LogType.Info;
                    s.ServerOptions.DefaultListen.Port = 9090;
                    s.ServerOptions.DefaultListen.SSL = true;//开启SSL
                    s.ServerOptions.DefaultListen.CertificateFile = "test.pfx";
                    s.ServerOptions.DefaultListen.CertificatePassword = "123456";
                    s.RPCOptions.ParameterFormater = new JsonPacket();//default messagepack
                },
                s =>
                {
                    //绑定一个委托
                    s.AddDelegate<Func<Task<string>>>(() =>
                    {
                        return Task.FromResult($"{Environment.OSVersion} {DateTime.Now}");
                    });
                }
                , typeof(Program).Assembly);
        });
        builder.Build().Run();
    }
}
//定义登陆接口
public interface IUser
{
    Task<string> Login(string name, string pwd);
}


[Service(typeof(IUser))]
public class HelloImpl : IUser
{
    //实现登陆方法
    public Task<string> Login(string name, string pwd)
    {
        var context = XRPCServer.EventToken;
        GetClientTime(context.Server, context.Session);
        Console.WriteLine($"{name} login at {context.Session.RemoteEndPoint}");
        return $"{name} login {DateTime.Now}".ToTask();
    }
    //定时从登陆客户端获取系统和时间信息并打印
    private async Task GetClientTime(XRPCServer server, BeetleX.ISession session)
    {
        //创建对应session的远程委托代理
        var action = server.Delegate<Func<Task<string>>>(session);
        while (true)
        {
            //调用委托
            var result = await action();
            Console.WriteLine($"{result}@{session.RemoteEndPoint}");
            await Task.Delay(1000);
        }
    }
}

以上服务使用了TLS作为基础安全通讯。启动服务后会显示以下日志

客户端定义

        Xamarin下使用XRPC只需要引用BeetleX.XRPC.Clients即可,引用完成后可以定义XRPCClient对象来进行通讯。

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        //定义XRPC客户端
        mClient = new BeetleX.XRPC.Clients.XRPCClient("192.168.1.18", 9090, "beetlex");
        mClient.CertificateValidationCallback = (s, certificate, chain, sslPolicyErrors) => true;
        mClient.Options.ParameterFormater = new JsonPacket();
        //创建接口远程接口代理
        mUser = mClient.Create<IUser>();
        //定义委托给服务端调用
        mClient.AddDelegate<Func<Task<string>>>(() =>
        {
            return Task.FromResult($"{Environment.OSVersion} {DateTime.Now}");
        });
        //创建对应服务端的远程委托代理
        mGetTime = mClient.Delegate<Func<Task<string>>>();
    }


    private Func<Task<string>> mGetTime;


    private static IUser mUser;


    private static BeetleX.XRPC.Clients.XRPCClient mClient;


    private async void Button_Clicked(object sender, EventArgs e)
    {
        try
        {
            if (string.IsNullOrEmpty(userName.Text))
            {
                await DisplayAlert("Error", "Enter you name!", "OK");
                return;
            }
            //登陆
            var result = await mUser.Login(userName.Text, userPwd.Text);
            this.layoutGrid.IsVisible = false;
            this.cmdLogin.IsVisible = false;
            OnGetTime();
        }
        catch (Exception e_)
        {
            await DisplayAlert("Error", e_.Message, "OK");
        }
    }


    private async Task OnGetTime()
    {
        try
        {
            //定时获取服务和时间信息
            while (true)
            {
                var result = await mGetTime();
                txtResult.Text = result;
                await Task.Delay(1000);
            }
        }
        catch (Exception e_)
        {
            await DisplayAlert("Error", e_.Message, "OK");
            this.layoutGrid.IsVisible = true;
            this.cmdLogin.IsVisible = true;
        }


    }
}

BeetleX

开源跨平台通讯框架(支持TLS)
轻松实现高性能:tcp、http、websocket、redis、rpc和网关等服务应用

https://beetlex.io

如果你想了解某方面的知识或文章可以把想法发送到

henryfan@msn.com|admin@beetlex.io

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!