解析大型.NET ERP系统 分布式应用模式设计与实现
C/S架构的应用程序,将一些复杂的计算逻辑由客户端转移到服务器端可以改善性能,同时也为了其它方面的控制。.NET Remoting在局域网内调用的性能相当不错。ERP系统中基于.NET Remoting和WCF构建一个应用程序服务器(Application Server)。
分布式应用设计目标:
1 客户端的连接,服务器要能控制。服务器根据授权许可文件的内容,控制客户端并发数。
2 服务器崩溃,客户端要得到通知,挂起当前数据输入操作,当服务器可用时,客户端可自动重新连接 。
3 支持数据加密,对敏感的数据可用加密的端口和通道传输。
4 支持数据压缩,改善数据传输效率,因为要做一个压缩与解压缩动作,性能有所降低。
5 安全控制,应用程序服务器阻止未授权的或未签名的应用程序的连接。
6 客户端向服务器传送大文件,传送图片需要时性能优化
7 服务器端发现错误时,支持堆栈传回客户端以诊断原因。
8 开发和部署简单方便。
先设计服务器与客户端通信的接口,一个简单销售合同数据表的访问接口代码如下所示。
public interface ISalesContractManager{SalesContractEntity GetSalesContract(Guid sessionId, String ContractNo);SalesContractEntity GetSalesContract(Guid sessionId, String ContractNo, IPrefetchPath2 prefetchPath);SalesContractEntity GetSalesContract(Guid sessionId, String ContractNo, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList fieldList);EntityCollection GetSalesContractCollection(Guid sessionId, IRelationPredicateBucket filterBucket);EntityCollection GetSalesContractCollection(Guid sessionId, IRelationPredicateBucket filterBucket, ISortExpression sortExpression);EntityCollection GetSalesContractCollection(Guid sessionId, IRelationPredicateBucket filterBucket, ISortExpression sortExpression, IPrefetchPath2 prefetchPath);EntityCollection GetSalesContractCollection(Guid sessionId, IRelationPredicateBucket filterBucket, ISortExpression sortExpression, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList fieldList);SalesContractEntity SaveSalesContract(Guid sessionId, SalesContractEntity salesContractEntity);SalesContractEntity SaveSalesContract(Guid sessionId, SalesContractEntity salesContractEntity, EntityCollection entitiesToDelete);SalesContractEntity SaveSalesContract(Guid sessionId, SalesContractEntity salesContractEntity, EntityCollection entitiesToDelete, string seriesCode);void DeleteSalesContract(Guid sessionId, SalesContractEntity salesContractEntity);bool IsSalesContractExist(Guid sessionId, String ContractNo);bool IsSalesContractExist(Guid sessionId, IRelationPredicateBucket filterBucket);int GetSalesContractCount(Guid sessionId, IRelationPredicateBucket filterBucket);SalesContractEntity CloneSalesContract(Guid sessionId, String ContractNo);void PostSalesContract(Guid sessionId, String ContractNo);void PostSalesContract(Guid sessionId, SalesContractEntity salesContractEntity);}
再设计服务实现SalesContractManager,实现上面的接口。
[CommunicationService("SalesContractManager")]public class SalesContractManager : ManagerBase, ISalesContractManager{public SalesContractEntity GetSalesContract(Guid sessionId, String ContractNo){return GetSalesContract(sessionId, ContractNo, null);}public SalesContractEntity GetSalesContract(Guid sessionId, String ContractNo, IPrefetchPath2 prefetchPath){return GetSalesContract(sessionId, ContractNo, prefetchPath, null);}
注意到上面给上面的实现类添加了CommunicationService特性,也就是声明实现类是一个服务。
先来回顾一下最简单的.NET Remoting 客户端与服务器端代码设计模式。
服务器端的设计:
int port = Convert.ToInt32(ConfigurationManager.AppSettings["Port"]);
BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"] = port;
TcpChannel channel = new TcpChannel(props, null, provider);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(ERP.BusinessLogic.SalesContractManager), "RemotingService", WellKnownObjectMode.SingleCall);
这里是用代码写死服务类,可以用配置文件增加服务类,也可用以反射的方法增加服务类。
客户端调用的代码如下:
ISalesContractManager salesContractManager =(IPdmServer)Activator.GetObject(typeof(ISalesContractManager),string.Format("{0}RemotingService", ApplicationServerUrl));
if (salesContractManager == null)throw new AppException("Sever configuration error");
salesContractManager.SaveSalesContract(guid, salesContract);
改善服务器端代码,让服务器主动搜索系统中打上CommunicationService特性的服务类。当新增加服务类型时,框架可自动识别并加载服务类型:
Assembly assembly = typeof(Manager).Assembly;
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{if (type.Namespace == "ERP.BusinessLogic.Managers"){string serviceName = string.Empty;object[] attributes = type.GetCustomAttributes(typeof(CommunicationService), true);if (attributes.Length > 0)serviceName = type.Name;if (!string.IsNullOrEmpty(serviceName)){if (clientActivatedServices.Contains(serviceName)){RemotingConfiguration.RegisterActivatedServiceType(type);}else if (singletonServices.Contains(serviceName)){RemotingConfiguration.RegisterWellKnownServiceType(type, serviceName + ".rem", WellKnownObjectMode.Singleton);}else{RemotingConfiguration.RegisterWellKnownServiceType(type, serviceName + ".rem", WellKnownObjectMode.SingleCall);}}
这样节省了开发人员的服务发布时间。客户端主要方法如下:
instance = ReflectionHelper.CreateObjectInstance<T>(type);
.NET Remoting可识别当前服务类型是否注册过,如果有则会创建一个远程代理,实现向服务器发送请求。
控制客户端并发数:
.NET Remoting支持单件调用模式,客户端不论调用次数,服务器端都只会是相同的一份对象,这样可实现会话Session控制。ERP系统用户登入时,检查服务器登入会话表(Session,本质上是一个DataTable),判断是否已经登入。同时也可以实现并发用户控制,当登入的用户数超过授权许可规定的用户数,可阻止登入。
服务器崩溃,客户端要得到通知,挂起当前数据输入操作,当服务器可用时,客户端可自动重新连接:
.NET Remoting支持客户端服务器订阅模式,服务器端可向客户端发送消息。当服务器进程崩溃,或是无法连接到数据库等原因发生时,需要及时向订阅过的客户端发送消息通知,客户端界面收到通知后需要立即挂起ERP主界面,不允许任何操作。这样可避免用户辛苦的输入数据后,点击保存却连接不上服务器,只好关闭重新输入。
安全控制,应用程序服务器阻止未授权的或未签名的应用程序的连接:
服务器控制客户端的连接调用,在客户端登入时,需要传入当前客户端程序集的版本,签名标识Token,还有系统参数等,服务器端会将这些参数整合在一起,用MD5计算出一个哈希值。只有客户端传入的参数值经过MD5运算后,与服务器中这些相同的参数值MD5运算之后的值,完全相同。服务器端才允许客户端继续登入。
服务器端发现错误时,支持堆栈传回客户端以诊断原因:
上面创建服务器端的代码中,有以下两句是为了实现服务器端堆栈回传到客户端的,参考下面的代码:
BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Full;
支持数据加密和数据压缩:
使用自定义的GTCP信道(Channel)通信,此通道支持加密传输和数据压缩传输。
开发和部署简单方便:
Code Smith 6.5的模板会帮助生成ISalesContractManager和SalesContractManager两个类型的源代码,通过上面的讲解知道,只需要给SalesContractManager加上CommunicationService特性即实现服务类的部署。
客户端向服务器传送大文件性能:
为了改善性能,对于文件传输类服务,单独开放一个端口用于文件传输。
转载于:https://www.cnblogs.com/JamesLi2015/p/4706341.html
解析大型.NET ERP系统 分布式应用模式设计与实现相关推荐
- 解析大型.NET ERP系统:十三种界面设计模式
成熟的ERP系统的界面应该都是从模板中拷贝出来的,各类功能的界面有规律可遵循.软件界面设计模式化或是艺术性的创作,我认可前者,模式化的界面客户容易举一反三,降低学习门槛.除了一些小部分的功能界面设计特 ...
- 解析大型.NET ERP系统架构设计 Framework+ Application 设计模式
我对大型系统的理解,从数量上面来讲,源代码超过百万行以上,系统有超过300个以上的功能,从质量上来讲系统应该具备良好的可扩展性和可维护性,系统中的功能紧密关联.除去业务上的复杂性,如何设计这样的一个协 ...
- 解析大型.NET ERP系统 设计异常处理模块
异常处理模块是大型系统必备的一个组件,精心设计的异常处理模块可提高系统的健壮性.下面从我理解的角度,谈谈异常处理的方方面面.我的设计仅仅限定于Windows Forms,供参考. 1 定义异常类型 . ...
- 解析大型.NET ERP系统 高质量.NET代码设计模式
1 缓存 Cache 系统中大量的用到缓存设计模式,对系统登入之后不变的数据进行缓存,不从数据库中直接读取.耗费一些内存,相比从SQL Server中再次读取数据要划算得多.缓存的基本设计模式参考下面 ...
- 解析大型.NET ERP系统 20条数据库设计规范
数据库设计规范是个技术含量相对低的话题,只需要对标准和规范的坚持即可做到.当系统越来越庞大,严格控制数据库的设计人员,并且有一份规范书供执行参考.在程序框架中,也有一份强制性的约定,当不遵守规范时报错 ...
- 解析大型.NET ERP系统 设计通用Microsoft Excel导入功能
做企业管理软件很难避免与Microsoft Excel打交道,常常是软件做好了,客户要求说再做一个Excel导入功能.导入Excel数据的功能的难度不大,从Excel列数据栏位的取值,验证值,再导入到 ...
- 解析大型.NET ERP系统 多国语言实现
实现多国语言有许多种实现方案,无外乎是一种字符串替换技术,将界面控件的文本标签替换成相应语言的文字..NET Windows Forms实现多国语言的方法有以下几种: 1 .NET的方案,使用资源文件 ...
- 单出口双防火墙双核心冗余_大型自动化物流系统之冗余设计
文|红云红河烟草(集团)有限责任公司 徐跃明.王磊 昆明昆船物流信息产业有限公司 姚正亚.王响雷 昆明船舶设备集团有限公司 曾学 冗余设计是提升自动化物流系统可靠性.可用性的主要方法之一,本文通过对大 ...
- 新零售分销系统开发模式设计
新零售分销系统开发,新零售分销系统开发模式,新零售分销系统开发设计. 1.新零售系统解决开店时间较短,周期慢,十多分钟就可以开一家店,极力推荐,扫二维码这种方法.简单,方便快捷,便捷. 2.新零售系统 ...
- 基于Jeecgboot前后端分离的ERP系统开发数据库设计(二)
-- ---------------------------- -- Table structure for erp_goods -- ---------------------------- DRO ...
最新文章
- python实现glove,gensim.word2vec模型训练实例
- linux oracle io 查看,Linux上Oracle是否使用异步io的诊断
- python的用途-python“ with”语句的用途是什么?
- 您对无法重新创建的表进行了更改或者启用了“阻止保存要求重新创建表的更改”选项...
- 全栈溯源、mAPM、金融性能、Oracle VS. MySQL:看APM技术专场有哪些干货
- 跟我学习dubbo-ZooKeeper注册中心安装(2)
- LeetCode-11-Container With Most Water
- 计算机学科 集体备课记录,信息技术学科组集体备课活动记录.pdf
- java题库管理考试管理源码,基于jsp的题库管理系统-JavaEE实现题库管理系统 - java项目源码...
- 入门级蛋白质结构查看PyMol的使用——PyMol常用命令
- 红帽子linux管理
- 5月25日------疯狂猜成语-----四周第七次站立会议 参会人员:杨霏,袁雪,胡潇丹,郭林林,尹亚男,赵静娜...
- 游戏的现实规则和非现实规则
- 世纪互联加入云计算专委会 推动应用进程
- C++实现复数矩阵求逆 matlab inv
- 深大校园网掉线/Drcom掉线/使校园网保持在线V2.0+Linux端Drcom登录方法(宿舍区教学区)
- 爬虫利器BeautifulSoup之CSS选择器的基本使用
- linux下route路由设置命令详解
- 基于深度学习的人工林地面激光扫描点云立木特征参数提取方法
- 用手机怎么查看网页的源代码0
热门文章
- VS编译NPAPI:jref类型出错
- 管理感悟:给自己编程水平打分
- 河里的水哪里去了——兼谈气候变暖与西方文明
- 用DIB位图显示图像
- linux的vim编辑器,强大的Vim 编辑器
- laravel-echo-server 不接收失败_6所高校公布报名不合格名单!这些问题最容易出错...
- php生成excel完整实例代码,PHP输出Excel实例代码
- C语言rf,C89:关键字 - osc_fdjrfnux的个人空间 - OSCHINA - 中文开源技术交流社区
- pandas不显示index_Pandas中文官档 ~ 基础用法1
- php 调用高拍仪,html页面通过ActiveX控件调用摄像头实现拍照上传demo代码下载