BeetleX之XRPC远程委托调用

BeetleX.XRPC是基于接口的远程通讯组件,它不仅可以把接口提供客户端调用,同样也支持服务端创建客户端的接口实例并主动调用客户端的方法.接口有着非常的规范性和约束性,但前提你是必须制定相应的接口并实现才行;为了让通讯在.NET平台使用变得更简便,在新版中组件支持远程委托调用.这功能不仅可以让客户端调用服务端的委托,同样也可以让服务端调用客户端的委托.

简介

组件支持任何委托的定义和调用包括框架集成的Action<T...>,Fun<T...,Result>和自定义委托.为了更好地满足通讯上的需求还是有一些简单的规则约束;主要限制有:参数暂不支持refout,参数类型不能为Object因为无法进行反序列化处理.返回值必须是Task,Task<T>Void;为了在IO处理上更好地配合async/await来提高性能,组件要求返回值必须是TaskTask<T>,之所以支持Void主要是用于一些特别的场景,当委托为Void时是不会理会对端处理的情况(即发送后不管模式).还有组件对委托的参数也有限制,最大不能超过10个参数.

注册委托

组件提供了一致的方式来进行委托注册,方法如下:

AddDelegate<T>(T handler) where T : Delegate

注册方法是可以任意委托类型和对应的方法

//客户端
mClient = new XRPCClient("localhost", 9090);
mClient.Options.ParameterFormater = new JsonPacket();
mClient.AddDelegate<Action<DateTime>>(SetTime);
//服务端
mServer.AddDelegate<ListEmployees>(() => Task.FromResult(DataHelper.Defalut.Employees));
mServer.AddDelegate<ListCustomers>(() => Task.FromResult(DataHelper.Defalut.Customers));

在绑定委托可以指定类函数也可以是匿名函数;当注册委托后对端就可以使用相同类型的Delegate进行代理和调用.

创建委托并调用

组件同样提供一致的方式来创建代理和调用

//客户端
mClient.Delegate<ListEmployees>()();
//服务端
mServer.Delegate<Action<DateTime>>(session)(DateTime.Now);

组件通过Delegate方法来创建相应委托代理,不过服务端在创建的时候必须指定客户端的session对象,创建建委托后就可以直接调用.

完整示例

接下来做一个完全的数据查询示例来展示一下基于远程委托调用的便利性,为了满足这个示例的要求自定义了以下三个委托:

    public delegate Task<List<Order>> ListOrders(int employee, string employeeid);public delegate Task<List<Employee>> ListEmployees();public delegate Task<List<Customer>> ListCustomers();

这三个委托分别是:雇员,客户和订单查询.接下来就定义一个WPF的客户端程序通过调用这三个委托来进行数据查询的操作:

public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();}XRPCClient mClient;private async void Window_Loaded(object sender, RoutedEventArgs e){mClient = new XRPCClient("localhost", 9090);mClient.Options.ParameterFormater = new JsonPacket();mClient.AddDelegate<Action<DateTime>>(SetTime);comboEmployees.ItemsSource = from a in await mClient.Delegate<ListEmployees>()() select new { a.EmployeeID, Name = $"{a.FirstName} {a.LastName}" };comboxCustomer.ItemsSource = await mClient.Delegate<ListCustomers>()();lstOrders.ItemsSource = await mClient.Delegate<ListOrders>()(0, null);}private void SetTime(DateTime time){this.Dispatcher.BeginInvoke(new Action<DateTime>(t =>{this.txtTime.Content = t.ToString();}), time);}private async void CmdSearch_Click(object sender, RoutedEventArgs e){lstOrders.ItemsSource = await mClient.Delegate<ListOrders>()(comboEmployees.SelectedValue != null ? (int)comboEmployees.SelectedValue : 0,comboxCustomer.SelectedValue != null ? (string)comboxCustomer.SelectedValue : null);}
}

为了展示服务端远程调客户端的,这里注册了一个Action<DateTime>用于服务端主动设置客户端时间的方法.

static void Main(string[] args)
{var builder = new HostBuilder().ConfigureServices((hostContext, services) =>{services.UseXRPC(s =>{s.ServerOptions.LogLevel = LogType.Warring;s.RPCOptions.ParameterFormater = new JsonPacket();},c => {c.AddDelegate<ListEmployees>(() => Task.FromResult(DataHelper.Defalut.Employees));c.AddDelegate<ListCustomers>(() => Task.FromResult(DataHelper.Defalut.Customers));c.AddDelegate<ListOrders>((emp, cust) =>{Func<Order, bool> filter = (o) => (emp == 0 || o.EmployeeID == emp) && (String.IsNullOrEmpty(cust) || o.CustomerID == cust);return Task.FromResult((from a in DataHelper.Defalut.Orders where filter(a) select a).ToList());});Task.Run(() =>{while (true){foreach (var item in c.Server.GetOnlines()){c.Delegate<Action<DateTime>>(item)(DateTime.Now);System.Threading.Thread.Sleep(1000);}}});},typeof(Program).Assembly);});builder.Build().Run();
}

以上是服务端的代码,注册了对应数据查询的委托,并开启一个简单的定时任务每秒中向所有客户端发送当前时间信息.接下来可以启动服务端和客户端运行结果如下:

从以上示例中可以发现,如果简单的数据传输处理,那用委托进行一个约束使用起的确是简便一些,毕竟.Net内置了一些委托类型可供使用无须自己定义,不过从应用规范上来说定义具体名称的委托或用接口来制定调用规范还是很有必要的. 如果你想获取完全示例可以访问: https://github.com/IKende/BeetleX-Samples/tree/master/XRPC.DelegateInvoke

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/311312.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常用决策树模型ID3、C4.5、CART算法

决策树概述 决策树&#xff08;decision tree&#xff09;&#xff1a;是一种基本的分类与回归方法&#xff0c;下面提到的ID3、C4.5、CART主要讨论分类的决策树。 在分类问题中&#xff0c;表示基于特征对实例进行分类的过程&#xff0c;可以认为是if-then的集合&#xff0c…

android webview卡顿检测_Android webview隐藏后跳转新页面input输入卡顿与白屏渲染慢的问题说明及修复方案...

关于此问题的说明:Android System WebView 内核的bug&#xff1a;当webview页面中存在持续渲染(如跑马灯效果。banner轮播等)。页面被隐藏后会导致JS阻塞影响页面渲染效率。从66.0.3359.126版本到最新都存在此问题。注意&#xff1a;此问题必须是页面隐藏hide后&#xff0c;并且…

hdu4841 圆桌问题-vector容器模拟

Problem Description 圆桌上围坐着2n个人。其中n个人是好人&#xff0c;另外n个人是坏人。如果从第一个人开始数数&#xff0c;数到第m个人&#xff0c;则立即处死该人&#xff1b;然后从被处死的人之后开始数数&#xff0c;再将数到的第m个人处死……依此方法不断处死围坐在圆…

五分钟了解Consul

Hi&#xff0c;大家好&#xff0c;我叫consul&#xff0c;翻译成中文叫做“领事”&#xff0c;其实我更喜欢叫自己为中介&#xff0c;因为我觉得自己做的事情和房产中介非常像。比如说想要卖房的房东到我这边登记&#xff0c;我将房屋信息登录到我的表格中&#xff08;服务注册…

决策树可视化保姆级教程

决策树可视化指南 决策树是机器学习的一种经典的模型&#xff0c;因其泛化性能好&#xff0c;可解释性强而被广泛应用到实际商业预测中。通常在我们完成决策树模型搭建后&#xff0c;我们会进一步研究分析我们搭建好的模型&#xff0c;这时候模型的可视化就显得尤为重要。下面…

ubtunu打开firefox_ubuntu中火狐浏览器问题(也许是)

带宽2M&#xff0c;虽然不多&#xff0c;但是看个网页还是够的在ubuntu中使用火狐浏览器经常会出现以下情况打开某网页&#xff0c;一直都打不开&#xff0c;下方显示正在链接到 某某网页很久之后也许还没连上&#xff0c;接着会有不能上网的提示&#xff0c;然后刷新下大部分…

如何运用领域驱动设计 - 领域事件

开篇距离发布上一篇该系列的文章好像已经过了快一个半月了&#xff0c;好吧&#xff0c;我托更了????。一晃就已经到了3月份&#xff0c;在这樱花????盛开的季节&#xff0c;终于得重新连载该系列了。在停更的期间时不时会收到大家关于DDD的留言和问题&#xff0c;一旦…

滑动窗口最大值-leetcode 239题

给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回滑动窗口中的最大值。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;htt…

hdu1276 士兵队列训练问题-list容器

Problem Description 某部队进行新兵队列训练&#xff0c;将新兵从一开始按顺序依次编号&#xff0c;并排成一行横队&#xff0c;训练的规则如下&#xff1a;从头开始一至二报数&#xff0c;凡报到二的出列&#xff0c;剩下的向小序号方向靠拢&#xff0c;再从头开始进行一至三…

diff git 指定时间,git diff日期?

Im accustomed to running a git comparison that will allow comparison with local git revs like:git diff HEAD HEAD~110 -- some/file/path/file.extIs it possible to use the date instead? And if so, how? I would like to be able insert in place of the "11…

一文读懂 Copyleft 开源许可证

开源组件已改变了我们开发软件的方式。来自开源社区的现成库&#xff08;ready-made libraries&#xff09;使忙碌的开发者们能专注于他们的秘密武器&#xff0c;这些秘密武器或将成为未来令人兴奋的新软件产品。而且不需要付费。下载开源组件不需要你提供信用卡号码&#xff0…

常用决策树集成模型Random Forest、Adaboost、GBDT详解

常用的集成学习策略 在之前的文章我有介绍过常用的基本决策树模型ID3、C4.5、CART算法&#xff0c;其中提到了一个关于基本决策树模型的缺点&#xff0c;那就是决策树模型学习一棵最优的决策树被认为是NP-Complete问题。实际中的决策树是基于启发式的贪心算法建立的&#xff0…

hdu1213 How Many Tables-并查集

Problem Description Today is Ignatius’ birthday. He invites a lot of friends. Now it’s dinner time. Ignatius wants to know how many tables he needs at least. You have to notice that not all the friends know each other, and all the friends do not want to …

redis spring 切面缓存_今日份学习: Spring中使用AOP并实现redis缓存?

笔记在Spring中如何使用AOP?Spring是如何切换JDK动态代理和CGLIB的&#xff1f;spring.aop.proxy-target-classtrue (在下方第二个链接中&#xff0c;原生doc中提到过)Aspect生命切面BeforeAfterAroundRedis广泛使用的内存缓存常见的数据结构:StringListSetHashZSetRedis为什么…

开源网站云查杀方案,搭建自己的云杀毒。

最近公司的一个客户被勒索病毒攻击了&#xff0c;可悲的是&#xff0c;客户的文件附件太多而且大&#xff0c;没有做双机热备的功能。当客户发现病毒后&#xff0c;还第一时间格式化了服务器。那叫一个惨&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;初步分析…

下一个更大元素 leetcode-496

给你两个 没有重复元素 的数组 nums1 和 nums2 &#xff0c;其中nums1 是 nums2 的子集。 请你找出 nums1 中每个元素在 nums2 中的下一个比其大的值。 nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在&#xff0c;对应位…

最简单的并查集模板

代码如下&#xff1a; #include <iostream> using namespace std; const int N 1010; int a[N];void init_set() { //初始化for (int i 1; i < N; i)a[i] i; }int find_set(int x) { //查找return x a[x] ? x : find_set(a[x]); }void union_set(int x, int y) …

linux关机方法有哪些?有何区别_Linux下判断是否正常关机的一个简单方法

思想&#xff1a;系统启动的时候生成一个文件&#xff0c;正常关机的时候则删除这个文件&#xff0c;则可以根据系统开机时有没有那个文件来判断是不是非正常关机。步骤&#xff1a;在/etc/rc.d/init.d/下编程脚本。判断是否正常关机&#xff0c;和生成文件的脚本&#xff1a;t…

二叉树的遍历—广度优先(BFS)和深度优先(DFS)python实现

二叉树 二叉树&#xff08;Binary tree&#xff09;是树形结构的一个重要类型。对于二叉树的基础知识这里不做过多介绍&#xff0c;下面我们直接介绍二叉树的遍历方式和如何用python代码去实现二叉树的遍历。 二叉树的遍历&#xff08;重点&#xff09; “前”、“中”、“后…

五分钟了解数据库事务隔离

前言什么是事务隔离呢&#xff1f;们知道&#xff0c;关系型数据基本都支持事务&#xff0c;事务具备四个特性&#xff0c;分别是&#xff1a;原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&#xff09;、…