如何通过Remoting实现双向通信

初探Remoting双向通信(三) 三、利用事件实现服务器向客户端通信     按照之前的思路,这次利用Marshal得到的对象,去触发事件,而事件的订阅端为客户端。为了说明问题,我重新命名了一些函数和事件名,代码如下: 远程对象: using System; using System.Collections.Generic; using System.Linq; using System.Text; names 阅读详情

 转自:http://www.cnblogs.com/artech/archive/2007/03/01/660595.html

 

Remoting是NET平台下比较成熟高效的分布式技术,我们习惯采用传统的远程调用的方式使用Remoting。在客户端所在的Application Domain,我们通过Proxy(Transparent Proxy)远程地跨Application Domain调用一个方法。当来自Client端的调用请求通过Proxy到达Server端所在的Application Domain后,Remoting Infrastructure在Server 端激活(Activate)相应的远程对象(一个继承子System.MarshalByRefObject类对象)——这里仅仅以服务端激活对象(Server Activated Object——SAO),然后再Server端执行相应的操作后把Result传递给Proxy,并最终到达Client。这是一种典型的Request/Response的调用方式。

我之所以一直比较推崇在.NET平台下使用Remoting而非XML Web Service是因为我觉得.NET Remoting是一种比较成熟的分布式技术。它自身提供了XML Web Service很多不具备的特性,其中对双向通信的支持就是一个很好的体现。

相对于典型的Request/Response的消息交换模式(Message Exchange Pattern——MEP),双向通信实质上是采用的Duplex的MEP。也就是说,Server端在执行操作的时候,可以回调(Callback)Client端的操作(这个操作时再Client端的Application Domain中执行的)。

现在我们来看如何一步一步实现在Remoting环境下的双向通信。在下面的Sample中,我们的逻辑是:调用一个数学计算的远程调用,除了传递相应的操作数之外,我们还传递一个对象,这个对象可以在Server端中回调 (Callback) 把运算结果在Client端显示出来。可以通过下面的URL下载源代码:http://www.cnblogs.com/files/artech/Artech.DuplexRemoting.zip
步骤一、构建整个Solution的整体构架

  • Artech.DuplexRemoting.Contract:Class Library Project,定义远程对象(Remote Object)和Callback对象的Contract(Interface)。实际上,站在Server端的角度上看,Callback的操作是在Client端的Application Domain中执行的,所以从本质上讲, Callback对象是Server端的远程对象。之所以定义这样一个Contract Project,其目的主要有以下两点:

如果没有把远程对象的Interface,对已某一个需要调用这个远程对象的Client来说,它必须引用远程对象本身。从安全的角度考虑,Server向Client过多暴露了操作的实现逻辑。如果我们把远程操作的Contract提取出来,Client只要引用这个Interface就可以了。

一般来说,远程对象的Contract相对时静态的(static),而业务逻辑的实现则是经常 变化的。因为Client只需要了解的是远程对象的Contract,所在无论Server端对远程对象的实现作了多大的变动,对不回对Client产生任何影响。

  • Artech.DuplexRemoting.Remoting:Class Library Project,定义远程对象本身。由于远程对象必须实现上边定义的Contract。所以需要引用Artech.DuplexRemoting.Contract。
  • Artech.DuplexRemoting.Hosting:Console Application Project,以Self-Host的方式Host Remoting。引用Artech.DuplexRemoting.Remoting。
  • Artech.DuplexRemoting.Client:Console Application Project,引用Artech.DuplexRemoting.Contract。

步骤二、定义Contract

IDuplexCalculator

   1: public interface IDuplexCalculator
   2: {
   3:     void Add(double x, double y, ICalculatorCallback callback);
   4: }

ICalculatorCallback

   1: public interface ICalculatorCallback
   2: {
   3:       void ShowResult(double x, double y, double result);
   4: }

步骤三、定义远程对象类型

DuplexCalculatorRemoting

   1: public class DuplexCalculatorRemoting : MarshalByRefObject, IDuplexCalculator
   2: {
   3:     public void Add(double x, double y, ICalculatorCallback callback)
   4:     {
   5:         Console.WriteLine("Invoke the method Add({0},{1}).", x, y);
   6:         double result = x + y;
   7:         callback.ShowResult(x, y, result);
   8:     }
   9: }

步骤四、Host远程对象

App.config

   1: <configuration>
   2:     <system.runtime.remoting>
   3:         <application name="Calculator">
   4:             <service>            
   5:                 <wellknown mode="SingleCall"
   6:                            type="Artech.DuplexRemoting.Remoting.DuplexCalculatorRemoting,Artech.DuplexRemoting.Remoting"
   7:                            objectUri="DuplexCalculator.soap" />
   8:             </service>
   9:  
  10:             <channels>
  11:                 <channel ref="http" port="8080">
  12:                     <serverProviders>
  13:                         <provider ref="wsdl" />
  14:                         <formatter ref="binary" typeFilterLevel="Full" />
  15:                     </serverProviders>
  16:                     <clientProviders>
  17:                         <formatter ref="binary" />
  18:                     </clientProviders>
  19:                 </channel>
  20:             </channels>
  21:         </application>
  22:     </system.runtime.remoting>
  23: </configuration>

Program.cs

   1: class Program
   2: {
   3:     static void Main(string[] args)
   4:     {
   5:         System.Runtime.Remoting.RemotingConfiguration.Configure("Artech.DuplexRemoting.Hosting.exe.config",false);
   6:         Console.WriteLine("Calculator service has begun to listen ");
   7:         Console.Read();
   8:     }
   9: }

这里需要特别注意的有以下两点:

  • 在定义Channel是需要指定一个双向Channel(Bi-Directional Channel)。系统给我们定义一一系列的System-Defined Channel用于调用远程对象。其中有一些只能提供单向的通信——比如只支持Client到Server的通信,而另一些可以提供双向的通信——比如TCP Channel 和Http Channel.
  • 在ServerProvider Section,我们必须设置typeFilterLevel为Full。出于安全的考量,Remoting提供了两个反序列化级别(Level)——Low & Full。Low是默认的,如果把typeFilterLevel设为Low,Remoting之会反序列化Remoting基本功能相关的对象。而设为Full则意味着Remoting会反序列化所有类型。如果你想知道那些类型是在Low Level下被限制,请参考 http://msdn2.microsoft.com/en-us/library/5dxse167.aspx。

之所以要把typeFilterLevel为Full,是因为我们的远程调用里包含一Callback对象,它实际上是一个继承System.MarshalByRefObject类对象(这个的对象将在Artech.DuplexRemoting.Client中定义)。而这个对象是不会再Low Level下被自动反序列化。

   1: <channels>
   2:   <channel ref="http" port="8080">
   3:     <serverProviders>
   4:       <provider ref="wsdl" />
   5:       <formatter ref="binary" typeFilterLevel="Full" />
   6:     </serverProviders>
   7:     <clientProviders>
   8:       <formatter ref="binary" />
   9:     </clientProviders>
  10:   </channel>
  11: </channels>

   1: public interface IDuplexCalculator
   2: {
   3:      void Add(double x, double y, ICalculatorCallback callback);
   4: }

步骤五、定义Callback对象类型和调用远程对象

CalculatorCallbackHandler

   1: public class CalculatorCallbackHandler : MarshalByRefObject, ICalculatorCallback
   2: {
   3:     public void ShowResult(double x, double y, double result)
   4:     {
   5:         Console.WriteLine("x + y = {2} where x = {0} and y = {1}", x, y, result);
   6:     }
   7: }

App.config

   1: <configuration>
   2: <system.runtime.remoting>
   3:     <application>
   4:         <channels>
   5:             <channel ref="http" port="0">
   6:                 <clientProviders>
   7:                     <formatter ref="binary" />
   8:                 </clientProviders>
   9:                 <serverProviders>
  10:                     <formatter ref="binary" typeFilterLevel="Full" />
  11:                 </serverProviders>
  12:             </channel>
  13:         </channels>        
  14:     </application>
  15: </system.runtime.remoting>
  16: </configuration>

Program.cs

   1: class Program
   2: {
   3:     static void Main(string[] args)
   4:     {
   5:         System.Runtime.Remoting.RemotingConfiguration.Configure("Artech.DuplexRemoting.Client.exe.config", false);
   6:  
   7:         InvocateDuplexCalculator("http://localhost:8080/Calculator/DuplexCalculator.soap");
   8:     }
   9:  
  10:     static void InvocateDuplexCalculator(string remoteAddress)
  11:     {
  12:         IDuplexCalculator proxy = (IDuplexCalculator)Activator.GetObject(typeof(IDuplexCalculator), remoteAddress);
  13:         proxy.Add(1, 2, new CalculatorCallbackHandler());
  14:         Console.Read();
  15:     }
  16: }

这里有两点需特别注意的:

  • 由于Server端时跨Application Domain远程地调用运行Client Application Domain中的Callback对象(Callback的执行实际是在Client而不在Server),所以Callback对象应该是一个MarshalByRefObject对象;
  • 上面我们以经提及,对于Server端了来说Callback对象实际上是一个远程对象(在Callback过程中Client端转变成Server端,而Server端转变成Client端)。Server端需要注册一些Channel用于Client访问寄宿在Server端的远程对象,同理,Server需要Callback一个寄宿在Client端Application Domain中的Callback对象,Client端需要注册相应的Channel;
  • 和Server端一样,我们必须设置typeFilterLevel为Full。 

到现在为止我们已经完成了所有的Program,我们来运行一下,在客户端你将得到如下的输出:

   1: x + y = 3 where x = 1 and y = 2

步骤六、将远程对象Host到IIS中

我们知道,Remoting有两种Host方式Self Host和IIS Host,上面我们把Remoting Host到一个Console Application中; 现在我们把试着把它Host到IIS中。实际上我们要做的工作很简单。

  • 在IIS Manager中添加一个虚拟目录对应Artech.DuplexRemoting.Remoting文件夹, 假设此虚拟目录的Alias为Artech.DuplexRemoting
  • 在Artech.DuplexRemoting.Remoting根目录下中(也就是在http://localhost/Artech.DuplexRemoting根目录下)添加一个Web.config,并添加类似于Artech.DuplexRemoting.Hosting/App.Config中 的Remoting Configuration。
   1: <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
   2:   <system.runtime.remoting>
   3:     <application>
   4:       <service>
   5:         <wellknown mode="SingleCall"
   6:                    type="Artech.DuplexRemoting.Remoting.DuplexCalculatorRemoting,Artech.DuplexRemoting.Remoting"
   7:                    objectUri="DuplexCalculator.soap" />
   8:       </service>
   9:       <channels>
  10:         <channel ref="http">
  11:           <serverProviders>
  12:             <provider ref="wsdl" />
  13:             <formatter ref="binary" typeFilterLevel="Full" />
  14:           </serverProviders>
  15:           <clientProviders>
  16:             <formatter ref="binary" />
  17:           </clientProviders>
  18:         </channel>
  19:       </channels>
  20:     </application>
  21:   </system.runtime.remoting>
  22: </configuration>

这样我们可以不需要Hosting,就可以运行Client了。

我所理解的.NET Remoting:
我所理解的Remoting(1):Marshaling & Activation - Part I
我所理解的Remoting(1):Marshaling & Activation - Part II
我所理解的Remoting(2):远程对象生命周期的管理—Part I
我所理解的Remoting(2):远程对象的生命周期管理-Part II
我所理解的Remoting(3):创建CAO Service Factory使接口和实现相互分离

 
Remoting双向通信探究与实现 在现代软件开发中,远程调用是一项重要的技术,它允许不同的计算机或进程之间进行通信和交互。客户端可以调用服务器上的对象的方法,并获取返回结果,而服务器也可以向客户端发送消息或调用客户端上的对象的方法。客户端可以调用服务器上的对象的方法,并获取返回结果,而服务器也可以向客户端发送消息或调用客户端上的对象的方法。在客户端,我们需要连接到服务器,并获取服务器上的远程对象的引用,然后使用该引用调用服务器上的方法。在客户端,我们需要连接到服务器,并获取服务器上的远程对象的引用,然后使用该引用调用服务器上的方法。 阅读详情

相关推荐

实现TCP/IP协议下Socket的客户端与服务端双向通信

网络通信是现代互联网应用的核心,而在众多通信协议中,TCP/IP协议无疑是最为基础和重要的一种。本章我们将深入探讨Socket的基本工作原理,并概述TCP/IP协议的基础知识,为后续章节中服务端和客户端的实现打下坚实的理论基础。非阻塞IO模型(Non-blocking IO)提供了一种不同于传统阻塞IO的机制,它允许应用程序在等待IO操作完成时继续执行其他任务,从而避免了线程阻塞和上下文切换的开销。这种模型特别适用于高并发场景,如Web服务器或实时通信系统。strace。

weixin_42560991的博客 937

基于TCP的多线程双向通信

简单实现一下TCP的双向通信。

qq_48066057的博客 2091

remoting双向通信

remoting 双向通信 服务端可以向客户端广播发送消息,多个客户端可以收到,客户端也可以向服务端发送消息

[原创].NET Remoting: 如何通过Remoting实现双向通信(Bidirectional Communication)

Remoting是NET平台下比较成熟高效的分布式技术,我们习惯采用传统的远程调用的方式使用Remoting。在客户端所在的Application Domain,我们通过Proxy(Transparent Proxy)远程地跨Application Domain调用一个方法。当来自Client端的调用请求通过Proxy到达Server端所在的Application Domain后,R

artech的专栏 4817

Net Remoting实现简单的服务端客户端双向通信

Net Remoting实现简单的服务端客户端双向通信

Remoting双向通信V2.0.rar

RemotingV1.0.rar RemotingV1.0.rar

C# 实现Remoting双向通信

本篇文章主要介绍了C#实现Remoting双向通信,.Net Remoting 是由客户端通过Remoting,访问通道以获得服务端对象,再通过代理解析为客户端对象来实现通信的 闲来无事想玩玩双向通信,实现类似QQ的互发消息的功能。于是乎开始学习.Net Remoting. .Net Remoting 是由客户端通过Remoting,访问通道以获得服务端对象,再通过代理解析为客户端对象...

weixin_30438813的博客 275

Remoting TCP双向通信

采用TCP方式实现Remoting双向通信。 服务器向所有客户端进行广播消息。 客户端可断开重连。 服务器自动记录客户端IP和端口号进行连接。

.NET Remoting: 如何通过Remoting实现双向通信(Bidirectional)

Remoting是NET平台下比较成熟高效的分布式技术,我们习惯采用传统的远程调用的方式使用Remoting。在客户端所在的Application Domain,我们通过Proxy(Transparent Proxy)远程地跨Application Domain调用一个方法。当来自Client端的调用请求通过Proxy到达Server端所在的Application Domain后,Remoting...

weixin_30782293的博客 127

Remoting双向通信V4.0.rar

Remoting双向通信V4.0.rar

信息奥赛课课通(C++)p154-1近似排序

试题描述 读入一对正整数,将这两个数之间(包括这两个数本身)的所有数按下述特别规则排序后输出,该特别规则是按两数倒过来的值进行比较决定其大小,如30倒过来为3,29倒过来为92,则29大于30. 输入要求 1行,包含两个用空格隔开的自然数,这两个自然数给出了待排序数的范围,其中1≤第一个数≤第二个数≤999999999,两个数之差不超过100. 输出要求 输出排序后的数据,每行输出...

mengdicfm的博客 7283

在Unity中使用.Net Remoting实现双向通信

前言: 之前公司接到项目的需求是使用一台电脑远程控制另外一台电脑,点击操作端电脑的Button,使显示端显示指定的画面.这个需求本质上两台电脑之间的相互通信,第一个想到的方案就是开发两个app,一个是服务器,一个是客户端,使用Tcp进行通信.本人没有使用这个方案的原因有以下两个: 1.项目需求只是远程控制,本人使用互联网进行连接有一种杀鸡用牛刀的感觉. 2.本人是个前端程序员,该项目开发周期...

weixin_39106746的博客 1434

别再为淘宝滑块发愁了!一个Python脚本自动获取x5sec cookie的保姆级教程

本文提供了一套完整的Python自动化解决方案,帮助开发者轻松应对淘宝滑块验证码问题。通过模拟浏览器行为、精准识别滑块缺口位置和生成拟人化移动轨迹,脚本能够自动获取关键的x5sec cookie,显著提升爬虫效率。教程涵盖环境配置、验证机制分析、代码实现及反检测策略,是解决淘宝滑块验证的实用指南。

weixin_30300225的博客 574

delphi prism 如何通过.net Remoting实现双向通信

Remoting是NET平台下比较成熟高效的分布式技术,我们习惯采用传统的远程调用的方式使用Remoting。在客户端所在的Application Domain,我们通过Proxy(Transparent Proxy)远程地跨Application Domain调用一个方法。当来自Client端的调用请求通过Proxy到达Server端所在的Application Domain后,Remoting

驴子的专栏 1167

UG/NX二次开发实战:用Python脚本批量更新100个零件参数,解放你的双手

本文详细介绍了如何利用NXOpen Python API进行UG/NX二次开发,实现批量更新100个零件参数的自动化流程。通过环境配置、框架设计、核心代码实现及性能优化,帮助工程师高效完成参数化设计任务,显著提升工作效率。

weixin_28694169的博客 276

银河麒麟(ky10)x86与arm双架构下编译zlmediakit的实战指南

本文提供了在银河麒麟(ky10)操作系统上,针对x86与arm双架构编译部署流媒体服务器zlmediakit的完整实战指南。文章详细阐述了从环境准备、依赖安装、代码获取到编译构建与测试的全过程,重点解析了两种CPU架构下的关键差异与注意事项,帮助开发者高效完成国产化平台上的流媒体服务搭建。

weixin_29306875的博客 100

测试Remoting服务端和客户端的双向通信

最近有个项目,大致需求是,服务端发送消息通知客户端上传指定的数据,然后处理后一部分显示在服务端界面上。也是在网上胡乱搜索一片,看到一篇Remoting广播事件的博客+Remoting觉得这么还可以做。 大致原理是:通过服务端广播事件,客户端通过调用远程类将数据以参数的方式传给服务端,然后激活服务端界面层的事件就达到双向了。都是靠远程类里的2个事件,一个给服务端,一个给客户端,分别交叉执行。这就相...

weixin_33845881的博客 226

OpenWRT使用4G/5G无线网卡模块上网

将4G/5G开发板插入设备,终端输入lsusb或lspci,看设备是否识别到4G/5G模块。

1万+
上一篇: 值参数、引用参数、输出参数、数据参数
下一篇: QQ在线客服代码 飘浮在右侧的QQ客服js特效演示
hongyanjava
博客等级 码龄17年 12粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值