一、远程对象

①RemoteHello.csproj 类库项目,程序集名称 RemoteHello ,默认命名空间 Wrox.ProCSharp.Remoting;

②派生自System.MarsshalByRefObject  ;

③根据不同的代理方式,需要有不同的构造函数(注意客户端的代码会有注释);

④Hello.cs源文件中的代码如下;

  1. namespace Wrox.ProCSharp.Remoting
  2. {
  3. public class Hello:MarshalByRefObject
  4. {
  5. public Hello()
  6. {
  7. Console.WriteLine("创建Hello");
  8. }
  9. public Hello(string name)
  10. {
  11. Console.WriteLine($"创建 {name}");
  12. }
  13. public string Greeting(string name)
  14. {
  15. Console.WriteLine($"Hello {name}!!!!");
  16. return $"Hello {name}!!!!";
  17. }
  18. }
  19. }

二、服务端

  ①tcp、http和ipc三种不同的通讯协议服务端的实现;

  ②每种通讯协议都支持激活知名对象和激活客户端激活的对象的服务创建方式;

  ③每种的通讯协议包含的两种对象创建方式同客户端的代理创建方式都是一 一 对应的,例如:服务端使用的是tcp的服务端激活方式,客户端也必须是tcp的服务端激活方式代理创建方式;

  ④下方代码位于服务控制台项目HelloServer中的Program.cs源文件中;

  ⑤注意服务项目需要依赖远程对象库;

  1. using System;
  2. using System.Runtime.Remoting;
  3. using System.Runtime.Remoting.Channels;
  4. using System.Runtime.Remoting.Channels.Http;
  5. using System.Runtime.Remoting.Channels.Ipc;
  6. using System.Runtime.Remoting.Channels.Tcp;
  7. using Wrox.ProCSharp.Remoting;
  8.  
  9. namespace HelloServer
  10. {
  11. class Program
  12. {
  13. static void Main(string[] args)
  14. {
  15. {// tcp
  16. {// 服务端激活(激活知名对象)
  17. //var tcpChannel = new TcpServerChannel(8085);
  18. //ChannelServices.RegisterChannel(tcpChannel, false);
  19. //RemotingConfiguration.RegisterWellKnownServiceType(typeof(Hello), "Hi", WellKnownObjectMode.SingleCall);
  20. }
  21.  
  22. {// 激活客户端激活的对象
  23. //var tcpChannel = new TcpServerChannel(8085);
  24. //ChannelServices.RegisterChannel(tcpChannel, false);
  25. //RemotingConfiguration.ApplicationName = "Hi";
  26. //RemotingConfiguration.RegisterActivatedServiceType(typeof(Hello));
  27. }
  28.  
  29. }
  30.  
  31. {// http
  32. {// 服务端激活(激活知名对象)
  33. //var httpChannel = new HttpServerChannel(8086);
  34. //ChannelServices.RegisterChannel(httpChannel, false);
  35. //RemotingConfiguration.RegisterWellKnownServiceType(typeof(Hello), "Hi", WellKnownObjectMode.SingleCall);
  36. }
  37.  
  38. {// 激活客户端激活的对象
  39. //var httpChannel = new HttpServerChannel(8086);
  40. //ChannelServices.RegisterChannel(httpChannel, false);
  41. //RemotingConfiguration.ApplicationName = "Hi";
  42. //RemotingConfiguration.RegisterActivatedServiceType(typeof(Hello));
  43. }
  44.  
  45. }
  46. {// ipc 只能用于客户端和服务端在同一操作系统上
  47. {// 服务端激活(激活知名对象)
  48. //var ipcChannel = new IpcServerChannel("myIpcPort");
  49. //ChannelServices.RegisterChannel(ipcChannel, false);
  50. //RemotingConfiguration.RegisterWellKnownServiceType(typeof(Hello), "Hi", WellKnownObjectMode.SingleCall);
  51. }
  52.  
  53. {// 激活客户端激活的对象
  54. var ipcChannel = new IpcServerChannel("myIpcPort");
  55. ChannelServices.RegisterChannel(ipcChannel, false);
  56. RemotingConfiguration.ApplicationName = "Hi";
  57. RemotingConfiguration.RegisterActivatedServiceType(typeof(Hello));
  58. }
  59.  
  60. }
  61.  
  62. Console.WriteLine("Press Enter to exit!");
  63. Console.ReadLine();
  64. }
  65. }
  66. }

三、客户端

  ①tcp、http和ipc三种不同的通讯协议客户端的实现;

  ②每种通讯协议都支持激活知名对象(服务端激活)和激活客户端激活的对象的客户端代理创建方式;

  ③每种的通讯协议包含的两种对象创建方式同客户端的代理创建方式都是一 一 对应的,例如:服务端使用的是tcp的服务端激活方式,客户端也必须是tcp的服务端激活方式代理创建方式;

  ④下方代码位于服务控制台项目HelloClient中的Program.cs源文件中;

  ⑤注意服务项目需要依赖远程对象库;

  ⑥请注意阅读代码的注释,对规则和特性有关键描述;

  ⑦每种通讯协议的客户端激活代码都实现了三种远程代理创建方式,中间空了一行间隔开,请一定注意;

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.Sockets;
  5. using System.Runtime.InteropServices;
  6. using System.Runtime.Remoting;
  7. using System.Runtime.Remoting.Activation;
  8. using System.Runtime.Remoting.Channels;
  9. using System.Runtime.Remoting.Channels.Http;
  10. using System.Runtime.Remoting.Channels.Ipc;
  11. using System.Runtime.Remoting.Channels.Tcp;
  12. using System.Runtime.Remoting.Lifetime;
  13. using System.Text;
  14. using Wrox.ProCSharp.Remoting;
  15.  
  16. namespace ConsoleApp3
  17. {
  18. class Program
  19. {
  20. static void Main(string[] args)
  21. {
  22. try
  23. {
  24. #region tcp
  25. {// tcp
  26. { // 服务端激活 对象调用后消失
  27. // 只能默认构造函数
  28. //TcpClientChannel tcpClient = new TcpClientChannel();
  29. //ChannelServices.RegisterChannel(tcpClient, false);
  30. //Hello obj = (Hello)Activator.GetObject(typeof(Hello), @"tcp://10.0.6.207:8085/Hi");
  31. //if (obj == null)
  32. //{
  33. // Console.WriteLine("获取远程代理失败!");
  34. // return;
  35. //}
  36.  
  37. //Console.WriteLine(obj.Greeting("tcp1"));
  38. }
  39. { // 客户端激活 对象持久
  40. //TcpClientChannel tcpClient = new TcpClientChannel();
  41. //ChannelServices.RegisterChannel(tcpClient, false);
  42. //object[] attrs = { new UrlAttribute(@"tcp://10.0.6.207:8085/Hi") };
  43. ////程序集 + 类型 + url属性 默认构造方法
  44. //ObjectHandle handle = Activator.CreateInstance("RemoteHello", "Wrox.ProCSharp.Remoting.Hello", attrs);
  45. //if (handle == null)
  46. //{
  47. // Console.WriteLine("获取远程代理失败!");
  48. // return;
  49. //}
  50. //Hello obj = handle.Unwrap() as Hello;
  51. //Console.WriteLine(obj.Greeting("tcp1"));
  52.  
  53. //TcpClientChannel tcpClient = new TcpClientChannel();
  54. //ChannelServices.RegisterChannel(tcpClient, false);
  55. //object[] attrs = { new UrlAttribute(@"tcp://10.0.6.207:8085/Hi") };
  56. //// 类型 + 参数 + url属性 参数位null,默认构造函数
  57. //Hello obj = (Hello)Activator.CreateInstance(typeof(Hello),new object[] {"周静a" }, attrs);
  58. //if (obj == null)
  59. //{
  60. // Console.WriteLine("获取远程代理失败!");
  61. // return;
  62. //}
  63. //Console.WriteLine(obj.Greeting("tcp2"));
  64.  
  65. //TcpClientChannel tcpClient = new TcpClientChannel();
  66. //ChannelServices.RegisterChannel(tcpClient, false);
  67. //// 注册
  68. //RemotingConfiguration.RegisterActivatedClientType(typeof(Hello), "tcp://10.0.6.207:8085/Hi");
  69. //// 创建
  70. //Hello obj = new Hello("周静");
  71. //if (obj == null)
  72. //{
  73. // Console.WriteLine("注册远程代理对象失败!");
  74. // return;
  75. //}
  76. //Console.WriteLine(obj.Greeting("tcp3"));
  77. }
  78. }
  79. #endregion
  80. #region http
  81. {// http
  82. { // 服务端激活 对象调用后消失
  83. // 只能默认构造函数
  84. //HttpClientChannel httpClient = new HttpClientChannel();
  85. //ChannelServices.RegisterChannel(httpClient, false);
  86. //Hello obj = (Hello)Activator.GetObject(typeof(Hello), @"http://10.0.6.207:8086/Hi");
  87. //if (obj == null)
  88. //{
  89. // Console.WriteLine("获取远程代理失败!");
  90. // return;
  91. //}
  92.  
  93. //Console.WriteLine(obj.Greeting("http1"));
  94. }
  95. { // 客户端激活 对象持久
  96. //HttpClientChannel httpClient = new HttpClientChannel();
  97. //ChannelServices.RegisterChannel(httpClient, false);
  98. //object[] attrs = { new UrlAttribute(@"http://10.0.6.207:8086/Hi") };
  99. ////程序集 + 类型 + url属性 默认构造方法
  100. //ObjectHandle handle = Activator.CreateInstance("RemoteHello", "Wrox.ProCSharp.Remoting.Hello", attrs);
  101. //if (handle == null)
  102. //{
  103. // Console.WriteLine("获取远程代理失败!");
  104. // return;
  105. //}
  106. //Hello obj = handle.Unwrap() as Hello;
  107. //Console.WriteLine(obj.Greeting("http1"));
  108.  
  109. //HttpClientChannel httpClient = new HttpClientChannel();
  110. //ChannelServices.RegisterChannel(httpClient, false);
  111. //object[] attrs = { new UrlAttribute(@"http://10.0.6.207:8086/Hi") };
  112. //// 类型 + 参数 + url属性 参数位null,默认构造函数
  113. //Hello obj = (Hello)Activator.CreateInstance(typeof(Hello), new object[] { "周静a" }, attrs);
  114. //if (obj == null)
  115. //{
  116. // Console.WriteLine("获取远程代理失败!");
  117. // return;
  118. //}
  119. //Console.WriteLine(obj.Greeting("http2"));
  120.  
  121. //HttpClientChannel httpClient = new HttpClientChannel();
  122. //ChannelServices.RegisterChannel(httpClient, false);
  123. //// 注册
  124. //RemotingConfiguration.RegisterActivatedClientType(typeof(Hello), "http://10.0.6.207:8086/Hi");
  125. //// 创建
  126. //Hello obj = new Hello("周静");
  127. //if (obj == null)
  128. //{
  129. // Console.WriteLine("注册远程代理对象失败!");
  130. // return;
  131. //}
  132. //Console.WriteLine(obj.Greeting("tcp3"));
  133. }
  134. }
  135. #endregion
  136.  
  137. #region ipc
  138. {// ipc 服务端和客户端只能在同一操作系统中,不持支跨域
  139. { // 服务端激活 对象调用后消失
  140. // 只能默认构造函数
  141. //IpcClientChannel ipcClient = new IpcClientChannel();
  142. //ChannelServices.RegisterChannel(ipcClient, false);
  143. //Hello obj = (Hello)Activator.GetObject(typeof(Hello), @"ipc://myIpcPort/Hi");
  144. //if (obj == null)
  145. //{
  146. // Console.WriteLine("获取远程代理失败!");
  147. // return;
  148. //}
  149.  
  150. //Console.WriteLine(obj.Greeting("ipc1"));
  151. }
  152. { // 客户端激活 对象持久
  153. //IpcClientChannel ipcClient = new IpcClientChannel();
  154. //ChannelServices.RegisterChannel(ipcClient, false);
  155. //object[] attrs = { new UrlAttribute(@"ipc://myIpcPort/Hi") };
  156. ////程序集 + 类型 + url属性 默认构造方法
  157. //ObjectHandle handle = Activator.CreateInstance("RemoteHello", "Wrox.ProCSharp.Remoting.Hello", attrs);
  158. //if (handle == null)
  159. //{
  160. // Console.WriteLine("获取远程代理失败!");
  161. // return;
  162. //}
  163. //Hello obj = handle.Unwrap() as Hello;
  164. //Console.WriteLine(obj.Greeting("ipc1"));
  165.  
  166. //IpcClientChannel ipcClient = new IpcClientChannel();
  167. //ChannelServices.RegisterChannel(ipcClient, false);
  168. //object[] attrs = { new UrlAttribute(@"ipc://myIpcPort/Hi") };
  169. //// 类型 + 参数 + url属性 参数位null,默认构造函数
  170. //Hello obj = (Hello)Activator.CreateInstance(typeof(Hello), new object[] { "周静a" }, attrs);
  171. //if (obj == null)
  172. //{
  173. // Console.WriteLine("获取远程代理失败!");
  174. // return;
  175. //}
  176. //Console.WriteLine(obj.Greeting("ipc2"));
  177.  
  178. //IpcClientChannel ipcClient = new IpcClientChannel();
  179. //ChannelServices.RegisterChannel(ipcClient, false);
  180. //// 注册
  181. //RemotingConfiguration.RegisterActivatedClientType(typeof(Hello), "ipc://myIpcPort/Hi");
  182. //// 创建
  183. //Hello obj = new Hello("周静");
  184. //if (obj == null)
  185. //{
  186. // Console.WriteLine("注册远程代理对象失败!");
  187. // return;
  188. //}
  189. //Console.WriteLine(obj.Greeting("ipc3"));
  190. }
  191. }
  192. #endregion
  193.  
  194. }
  195. catch (Exception ex)
  196. {
  197.  
  198. Console.WriteLine(ex.Message);
  199. }
  200. Console.WriteLine("Press AnyKey to Exit");
  201. Console.ReadKey();
  202.  
  203. }
  204. }
  205. }

四、其他注意事项

  ① 本次实现只是remoting的简单实现,对初学者学习应该能很省很多事,其他AOP等方面的深度应用请阅读相关书籍,C#高级编程系列的书籍;

  ② 工程项目是在win10 64操作系统上vs2019中实现验证的,如有错误和疑问,欢迎留言,谢谢!

  1. 服务端激活

.net remoting(一)的更多相关文章

  1. spring remoting源码分析--Hessian分析

    1. Caucho 1.1 概况 spring-remoting代码的情况如下: 本节近分析caucho模块. 1.2 分类 其中以hession为例,Hessian远程服务调用过程: Hessian ...

  2. Visual Studio 2013 Ultimate因为CodeLens功能导致Microsoft.Alm.Shared.Remoting.RemoteContainer.dll高CPU占用率的折中解决方案

    1.为什么Microsoft.Alm.Shared.Remoting.RemoteContainer.dll的CPU占用率以及内存使用率会那么高? 在Visual Studio 2013 Ultima ...

  3. VS2015 出现 .NETSystem.Runtime.Remoting.RemotingException: TCP 错误

    错误内容: 界面显示内容为: .NET�������������System.Runtime.Remoting.RemotingException: TCP 淇¢亾鍗忚鍐茬獊: 搴斾负鎶ュご銆� 鍦 ...

  4. .Net中Remoting通信机制简单实例

    .Net中Remoting通信机制 前言: 本程序例子实现一个简单的Remoting通信案例 本程序采用语言:c# 编译工具:vs2013工程文件 编译环境:.net 4.0 程序模块: Test测试 ...

  5. .Net中Remoting通信机制

    Remoting通信机制 Remoting介绍 主要元素 通道类型 激活方式 对象定义 Remoting介绍 什么是Remoting,简而言之,我们可以将其看作是一种分布式处理方式. 从微软的产品角度 ...

  6. .NET Remoting 应用实例

    前言 项目中运用到.NET Remoting ,前段时间也看了下.NET Remoting的相关资料,感觉自己应该动手写个实例来梳理下对.NET Remoting认识和理解,不足的地方请大家指正. 简 ...

  7. Holographic Remoting

    看到微软官方的 Holographic Remoting Player https://developer.microsoft.com/en-us/windows/holographic/hologr ...

  8. IIS部署Remoting总结

    1.在IIS里新建一个网站,命名为test,路径指向 e:\test: 2.在 e:\test下创建目录bin: 3.把Remoting远程对象的Project设置为类库,编译为DLL文件,然后复制到 ...

  9. .NET Remoting 体系结构 之 在 ASP.NET 中驻留远程服务器

    迄今为止,所有服务器示例都是运行在自驻留(self-hosted)的.NET 服务器上.自驻留的服务器必 须手动启动..NET Remoting 服务器也可以在许多其他的应用程序类型中启动.在 Win ...

  10. Remoting and web services using Spring[摘自官网]

    spring document url: http://docs.spring.io/spring/docs/ Using Hessian First we’ll have to create a n ...

随机推荐

  1. 微信小程序-swiper(轮播图)抖动问题

    ps:问题 组件swiper(轮播图)真机上不自动滚动 一直卡在那里抖动 以前遇到这个问题,官方一直没有正面回复.就搁置了,不过有大半年没写小程序了也没去关注,今天就去看了下官方文档,发觉更新了点好东 ...

  2. c语言中的malloc函数

    少壮不努力,大一的时候c语言学得不扎实,最近学数据结构的时候看到c语言中malloc函数都不知道了,这里记录一下,避免以后再忘. malloc的全称是memory allocation,中文叫动态内存 ...

  3. R语言:日薪和应发工资

    生产部门普通员工为日薪,有时要知道日薪和应发工资的转换关系.做表一为日薪取整数,白天工资+晚上工资=应发工资,延长工作时间取时薪的1.5倍,应发工资保留到十位.做表二为应发工资取十的倍数,推算相应日薪 ...

  4. 设计模式之GOF23状态模式

    状态模式state 场景:当具有许多状态并且需要频繁改变时,用这种模式 -电梯的运行:维修,正常,自动关门,自动开门,向上运行,向下运行,消防状态 -红绿灯:红灯,黄灯,绿灯 -企业或政府系统:公文的 ...

  5. USACO 3.1 Contact

    http://www.nocow.cn/index.php/Translate:USACO/contact 题目大意:给一个只含0和1的序列,统计每个子序列的重复次数,并按次数递减来输出 考虑子序列时 ...

  6. IOS App打包发布完整流程

    注册成为开发者 登录苹果开发者中心,点击Accounts,在这里需要你填写你的Appple ID进行登录,如果没有,点击这里申请一个,填写信息就成,这里就不再赘述.申请完成之后,使用申请的AppID进 ...

  7. 安装Kibana出现的问题

    安装Kibana出现的问题 前言 该问题的出现是在安装配置完成之后,也就是说下载好了kibana的相关包,在启动过程中出现的错误,该错误是在centos6的机器上引发的,是因为系统中的GLIBC_2. ...

  8. LeetCode链表专题

    链表 套路总结 1.多个指针 移动 2.虚假链表头:凡是有可能删除头节点的都创建一个虚拟头节点,代码可以少一些判断(需要用到首部前一个元素的时候就加虚拟头指针) 3.快慢指针 如leetcode160 ...

  9. VS2019 使用

    下载 官网下载:链接 安装 1.点击下载程序,会显示这个界面 2.点击“继续”,等待安装程序安装完成 4.安装程序下载安装验证完毕,将会提示进入这个界面 5.为了方便起见,这里仅展示安装C++功能,在 ...

  10. SonarQube搭建手记

    前提 这篇文章记录的是SonarQube服务搭建的详细过程,应用于云迁移后的PipleLine的代码扫描环节. 笔者有软件版本升级强迫症,一般喜欢使用软件的最新版本,编写此文的时候(2020-05-1 ...