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系统 分布式应用模式设计与实现相关推荐

  1. 解析大型.NET ERP系统:十三种界面设计模式

    成熟的ERP系统的界面应该都是从模板中拷贝出来的,各类功能的界面有规律可遵循.软件界面设计模式化或是艺术性的创作,我认可前者,模式化的界面客户容易举一反三,降低学习门槛.除了一些小部分的功能界面设计特 ...

  2. 解析大型.NET ERP系统架构设计 Framework+ Application 设计模式

    我对大型系统的理解,从数量上面来讲,源代码超过百万行以上,系统有超过300个以上的功能,从质量上来讲系统应该具备良好的可扩展性和可维护性,系统中的功能紧密关联.除去业务上的复杂性,如何设计这样的一个协 ...

  3. 解析大型.NET ERP系统 设计异常处理模块

    异常处理模块是大型系统必备的一个组件,精心设计的异常处理模块可提高系统的健壮性.下面从我理解的角度,谈谈异常处理的方方面面.我的设计仅仅限定于Windows Forms,供参考. 1 定义异常类型 . ...

  4. 解析大型.NET ERP系统 高质量.NET代码设计模式

    1 缓存 Cache 系统中大量的用到缓存设计模式,对系统登入之后不变的数据进行缓存,不从数据库中直接读取.耗费一些内存,相比从SQL Server中再次读取数据要划算得多.缓存的基本设计模式参考下面 ...

  5. 解析大型.NET ERP系统 20条数据库设计规范

    数据库设计规范是个技术含量相对低的话题,只需要对标准和规范的坚持即可做到.当系统越来越庞大,严格控制数据库的设计人员,并且有一份规范书供执行参考.在程序框架中,也有一份强制性的约定,当不遵守规范时报错 ...

  6. 解析大型.NET ERP系统 设计通用Microsoft Excel导入功能

    做企业管理软件很难避免与Microsoft Excel打交道,常常是软件做好了,客户要求说再做一个Excel导入功能.导入Excel数据的功能的难度不大,从Excel列数据栏位的取值,验证值,再导入到 ...

  7. 解析大型.NET ERP系统 多国语言实现

    实现多国语言有许多种实现方案,无外乎是一种字符串替换技术,将界面控件的文本标签替换成相应语言的文字..NET Windows Forms实现多国语言的方法有以下几种: 1 .NET的方案,使用资源文件 ...

  8. 单出口双防火墙双核心冗余_大型自动化物流系统之冗余设计

    文|红云红河烟草(集团)有限责任公司 徐跃明.王磊 昆明昆船物流信息产业有限公司 姚正亚.王响雷 昆明船舶设备集团有限公司 曾学 冗余设计是提升自动化物流系统可靠性.可用性的主要方法之一,本文通过对大 ...

  9. 新零售分销系统开发模式设计

    新零售分销系统开发,新零售分销系统开发模式,新零售分销系统开发设计. 1.新零售系统解决开店时间较短,周期慢,十多分钟就可以开一家店,极力推荐,扫二维码这种方法.简单,方便快捷,便捷. 2.新零售系统 ...

  10. 基于Jeecgboot前后端分离的ERP系统开发数据库设计(二)

    -- ---------------------------- -- Table structure for erp_goods -- ---------------------------- DRO ...

最新文章

  1. python实现glove,gensim.word2vec模型训练实例
  2. linux oracle io 查看,Linux上Oracle是否使用异步io的诊断
  3. python的用途-python“ with”语句的用途是什么?
  4. 您对无法重新创建的表进行了更改或者启用了“阻止保存要求重新创建表的更改”选项...
  5. 全栈溯源、mAPM、金融性能、Oracle VS. MySQL:看APM技术专场有哪些干货
  6. 跟我学习dubbo-ZooKeeper注册中心安装(2)
  7. LeetCode-11-Container With Most Water
  8. 计算机学科 集体备课记录,信息技术学科组集体备课活动记录.pdf
  9. java题库管理考试管理源码,基于jsp的题库管理系统-JavaEE实现题库管理系统 - java项目源码...
  10. 入门级蛋白质结构查看PyMol的使用——PyMol常用命令
  11. 红帽子linux管理
  12. 5月25日------疯狂猜成语-----四周第七次站立会议 参会人员:杨霏,袁雪,胡潇丹,郭林林,尹亚男,赵静娜...
  13. 游戏的现实规则和非现实规则
  14. 世纪互联加入云计算专委会 推动应用进程
  15. C++实现复数矩阵求逆 matlab inv
  16. 深大校园网掉线/Drcom掉线/使校园网保持在线V2.0+Linux端Drcom登录方法(宿舍区教学区)
  17. 爬虫利器BeautifulSoup之CSS选择器的基本使用
  18. linux下route路由设置命令详解
  19. 基于深度学习的人工林地面激光扫描点云立木特征参数提取方法
  20. 用手机怎么查看网页的源代码0

热门文章

  1. VS编译NPAPI:jref类型出错
  2. 管理感悟:给自己编程水平打分
  3. 河里的水哪里去了——兼谈气候变暖与西方文明
  4. 用DIB位图显示图像
  5. linux的vim编辑器,强大的Vim 编辑器
  6. laravel-echo-server 不接收失败_6所高校公布报名不合格名单!这些问题最容易出错...
  7. php生成excel完整实例代码,PHP输出Excel实例代码
  8. C语言rf,C89:关键字 - osc_fdjrfnux的个人空间 - OSCHINA - 中文开源技术交流社区
  9. pandas不显示index_Pandas中文官档 ~ 基础用法1
  10. php 调用高拍仪,html页面通过ActiveX控件调用摄像头实现拍照上传demo代码下载