一、远程对象

①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. IDEA的窗口布局设置

    修改idea的窗口布局 idea默认的窗口模式是如: 可以通过File->Appearance->Window Options->勾选 Widescreen tool window ...

  2. 谈谈Spring bean的生命周期(一)

    简介 本片文章主要讲Spring IOC容器中 bean 的生命周期 Spring bean 生命周期 Spring 中bean的声明周期 可以分为如下4个阶段: 实例化阶段--Instantiati ...

  3. Python爬虫丨大众点评数据爬虫教程(2)

    大众点评数据爬虫获取教程 --- [SVG映射版本] 前言: 大众点评是一款非常受大众喜爱的一个第三方的美食相关的点评网站.从网站内可以推荐吃喝玩乐优惠信息,提供美食餐厅.酒店旅游.电影票.家居装修. ...

  4. R语言:计算现金工资的币数

    新入职的员工,有的没有相应银行卡,需要计算现金工资的币数.实发工资,一般取整数. 简化计算,纸币面值只有100.10.1.4278除以100等于42余78,78除以10等于7余8,8除以1等于8. 复 ...

  5. [hdu4498]离散化,simpson求积分

    题意:,求这个函数在[0,100]上的图像的长度. 思路:采用离散化的思想,求出所有交点 ,把交点排序,把[0,100]分成若干个小区间,这样原函数在每个小区间上的图像属于某一个二次函数或者是一条直线 ...

  6. iOS中的事件响应链、单例模式、工厂模式、观察者模式

    学习内容 欢迎关注我的iOS学习总结--每天学一点iOS:https://github.com/practiceqian/one-day-one-iOS-summary iOS中事件传递和相应机制 i ...

  7. 快速了解pandas

    pandas主要就下面两方面:(只要稍微了解下面两点,那你就会用了) 1.两种数据结构(Series和DataFrame) 2.对这两种数据进行处理(主要是对DataFrame处理) -------- ...

  8. 关于jquery 项目中文件上传还有图片上传功能的尴尬???

    做项目需要兼容IE8,所以找了好久,都没找到合适的希望有大神能够解惑!!! 要求是兼容IE8,在选完图片直接自动上传,有进度展示,并有成功的标记,下面的选择文件也是一个input file 选择完自动 ...

  9. ql的python学习之路-day15

    前言:本节主要讲解的是文件路径 在实际的软件开发中会设计一个项目的文件目录,按照执行包bin.配置包config.核心包core等来设计,在执行包里面要运行核心包里的主程序mian,由于不在同一级的目 ...

  10. Redis 消息中间件 ServiceStack.Redis 轻量级

    问题: 公司开了个新项目,算上我一共3个人.车间里机台通过流水线连通联动的玩意.一个管理控制系统连接各个机台和硬件.专机类型就有5种,个数差不多20个左右. 软件规划的时候采用总分的结构,管理控制系统 ...