【转载】.NET Remoting学习笔记(二)激活方式
目录
- .NET Remoting学习笔记(一)概念
- .NET Remoting学习笔记(二)激活方式
- .NET Remoting学习笔记(三)信道
激活方式概念
在访问远程类型的一个对象实例之前,必须通过一个名为Activation的进程创建它并进行初始化。这种客户端通过通道来创建远程对象,称为对象的激活。
激活分为两大类:服务器端激活 客户端激活
服务器端激活
又称WellKnow(知名对象)
服务器应用程序在激活对象实例之前会在一个众所周知的统一资源标识符(URI)上来发布这个类型。然后该服务器进程会为此类型配置一个WellKnown对象,并根据指定的端口或地址来发布对象。
服务器端激活分为:SingleTon模式 SingleCall模式
SingleTon模式
设置为SingleTon激活方式,则Remoting将为所有客户端建立同一个对象实例。当对象处于活动状态时, SingleTon实例会处理所有后来的客户端访问请求,而不管它们是同一个客户端,还是其他客户端。SingleTon实例将在方法调用中一直维持其状态。举例来说,如果一个远程对象有一个累加方法(i=0;++i),被多个客户端(例如两个)调用。如果设置为SingleTon方式,则第一个客户获得值为1,第二个客户获得值为2,因为他们获得的对象实例是相同的。如果熟悉Asp .Net的状态管理,我们可以认为它是一种Application状态。
下面贴代码:
1.创建远程调用处理的类
using System;
using System.Runtime.Remoting.Metadata; namespace MessageMarshal
{
/*创建发送消息委托*/
public delegate void SendMessageHandler(string messge); [Serializable]
public class TestMessageMarshal : MarshalByRefObject
{
private Guid ID { get; set; } /*新建对象实例时重新创建标识编号*/
public TestMessageMarshal()
{
ID = Guid.NewGuid();
} /*创建发送消息事件*/
public static event SendMessageHandler SendMessageEvent; /*发送消息*/
[SoapMethod(XmlNamespace = "MessageMarshal", SoapAction = "MessageMarshal#SendMessage")]
public void SendMessage(string messge)
{
if (SendMessageEvent != null)
SendMessageEvent(ID.ToString() + "\t" + messge);
}
}
}
2.创建服务端代码
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http; namespace TestRemotingServer
{
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("创建HTTP通道"); /*创建HTTP通道*/
HttpChannel channel = new HttpChannel(816); /*注册通道服务端*/
ChannelServices.RegisterChannel(channel, false); /*服务端注册,使用Singletong激活*/
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MessageMarshal.TestMessageMarshal), "TestMessageMarshal", WellKnownObjectMode.Singleton); Console.WriteLine("started ..."); /*接收客户端事件*/
MessageMarshal.TestMessageMarshal.SendMessageEvent += new MessageMarshal.SendMessageHandler(TestMessageMarshal_SendMessageEvent); Console.Read();
} static void TestMessageMarshal_SendMessageEvent(string messge)
{
Console.WriteLine(messge);
}
}
}
3.创建客户端代码
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Threading; namespace TestRemotingClient
{
class Program
{
static void Main(string[] args)
{
/*创建通道*/
HttpChannel channel = new HttpChannel(); /*注册通道*/
ChannelServices.RegisterChannel(channel, false); /*注册通道 的 远程处理类型*/
RemotingConfiguration.RegisterWellKnownClientType(typeof(MessageMarshal.TestMessageMarshal), "http://localhost:816/TestMessageMarshal"); /*创建消息实体*/
MessageMarshal.TestMessageMarshal TestMessage = new MessageMarshal.TestMessageMarshal(); while (true)
{
TestMessage.SendMessage("DateTime.Now:" + System.DateTime.Now.ToString());
Console.WriteLine("send message...");
Thread.Sleep(2000);
}
}
}
}
4.运行服务端后,开启两个客户端程序,查看结果如下:

代码示意中,当TestMessageMarshal有新实例时,其构造函数会创建不同的标识(GUID),服务端接收到客户端的数据请求,并将标识编号输出到界面,从界面中可以看出,多个客户端请求的通道,服务端都是用一个通道(一个实例)来进行处理的。
SingleCall模式
SingleCall是一种无状态模式。一旦设置为SingleCall模式,则当客户端调用远程对象的方法时, Remoting会为每一个客户端建立一个远程对象实例,至于对象实例的销毁则是由GC自动管理的。同上一个例子而言,则访问远程对象的两个客户获得的都是1。我们仍然可以借鉴Asp .Net的状态管理,认为它是一种Session状态。
我们修改服务端代码如下,客户端不需要修改:
/*服务端注册,使用SingleCall激活*/
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MessageMarshal.TestMessageMarshal), "TestMessageMarshal", WellKnownObjectMode.SingleCall);
开启服务端,然后开启一个客户端,如下
从输出结果中可以看出,每次服务端都会为每一个客户端请求建立一个远程对象实例。
客户端激活
与WellKnown模式不同, Remoting在激活每个对象实例的时候,会给每个客户端激活的类型指派一个URI。客户端激活模式一旦获得客户端的请求,将为每一个客户端都建立一个实例引用。SingleCall模式和客户端激活模式是有区别的:首先,对象实例创建的时间不一样。客户端激活方式是客户一旦发出调用的请求,就实例化;而SingleCall则是要等到调用对象方法时再创建。其次,SingleCall模式激活的对象是无状态的,对象生命期的管理是由GC管理的,而客户端激活的对象则有状态,其生命周期可自定义。其三,两种激活模式在服务器端和客户端实现的方法不一样。尤其是在客户端,SingleCall模式是由 GetObject()来激活,它调用对象默认的构造函数。而客户端激活模式,则通过CreateInstance()来激活,它可以传递参数,所以可以调用自定义的构造函数来创建实例。
1.修改服务端代码
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http; namespace TestRemotingServer
{
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("创建HTTP通道"); /*创建HTTP通道*/
HttpChannel channel = new HttpChannel(816); /*注册通道服务端*/
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.ApplicationName = "test"; /*服务端注册,使用SingleCall激活*/
RemotingConfiguration.RegisterActivatedServiceType(typeof(MessageMarshal.TestMessageMarshal)); Console.WriteLine("started ..."); /*接收客户端事件*/
MessageMarshal.TestMessageMarshal.SendMessageEvent += new MessageMarshal.SendMessageHandler(TestMessageMarshal_SendMessageEvent); Console.Read();
} static void TestMessageMarshal_SendMessageEvent(string messge)
{
Console.WriteLine(messge);
}
}
}
2.修改客户端代码
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Threading; namespace TestRemotingClient
{
class Program
{
static void Main(string[] args)
{
/*创建通道*/
HttpChannel channel = new HttpChannel(); /*注册通道*/
ChannelServices.RegisterChannel(channel, false); /*注册通道 的 远程处理类型*/
RemotingConfiguration.RegisterActivatedClientType(typeof(MessageMarshal.TestMessageMarshal), "http://localhost:816/test"); /*创建消息实体*/
MessageMarshal.TestMessageMarshal TestMessage = new MessageMarshal.TestMessageMarshal(); while (true)
{
TestMessage.SendMessage("DateTime.Now:" + System.DateTime.Now.ToString());
Console.WriteLine("send message...");
Thread.Sleep(2000);
}
}
}
}
3.测试,开启服务端和两个客户端
可以看出每个服务端为每个客户端都会创建一个实例对象。
其测试目录结构如下,不然客户端远程对象和服务端会不对应。会报“找不到请求的服务”的异常
注意:服务端对象和客户端对象激活方式的区别:
服务端激活时,服务通过RegisterWellKnownServiceType方法的objectUri来标识
客户端激活时,服务通过RemotingConfiguration.ApplicationName属性来标识
客户端调用服务时,用务地址需指定正确
这就是 Remoting 的三种 激活方式,如有问题欢迎指正。
作者:释迦苦僧 出处:http://www.cnblogs.com/woxpp/p/3995366.html
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
【转载】.NET Remoting学习笔记(二)激活方式的更多相关文章
- .NET Remoting学习笔记(二)激活方式
目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 参考:百度百科 ♂风车车.Net 激活方式概念 在 ...
- 【转载】.NET Remoting学习笔记(三)信道
目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 参考:♂风车车.Net .NET Framework ...
- 【转载】.NET Remoting学习笔记(一)概念
目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 背景 自接触编程以来,一直听过这个名词Remotin ...
- .NET Remoting学习笔记(三)信道
目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 参考:♂风车车.Net .NET Framework ...
- .NET Remoting学习笔记(一)概念
目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 背景 自接触编程以来,一直听过这个名词Remotin ...
- AJax 学习笔记二(onreadystatechange的作用)
AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...
- java之jvm学习笔记二(类装载器的体系结构)
java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...
- NumPy学习笔记 二
NumPy学习笔记 二 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...
- muduo学习笔记(二)Reactor关键结构
目录 muduo学习笔记(二)Reactor关键结构 Reactor简述 什么是Reactor Reactor模型的优缺点 poll简述 poll使用样例 muduo Reactor关键结构 Chan ...
随机推荐
- mongodb权限机制以及扩展
mongodb权限机制 启动权限机制之前要先在MONGODB中添加管理员账号: 1. 创建账号 重装安装一个mongodb,安装时添加一个 --auth参数: 先把安装好的从服务中删除掉(删除之后数据 ...
- [Kubernetes]深入解析Pod
Pod是Kubernetes项目的原子调度单位 为什么需要Pod? 容器是未来云计算系统中的进程,容器镜像就是这个系统里的".exe"安装包,那Kubernetes就是操作系统. ...
- LINQ学习笔记 Join 与 Group join
LINQ中的Join对应T-SQL中的内连接,并无左连接的方法,当然也没有右连接. 要达成Left join必须依靠GroupJoin来完成. GroupJoin顾名思义就是先集团在做加入,加入的不同 ...
- shell的for循环
与其他编程语言类似,Shell支持for循环. for循环一般格式为: for 变量 in 列表 do command1 command2 ... commandN done 列表是一组值(数字.字符 ...
- 【bzoj4826】[Hnoi2017]影魔 单调栈+可持久化线段树
题目描述 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵魂,都有着自己 ...
- Java 线程池的原理与实现学习(一)
线程池:多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中 ...
- poj1717 Dominoes (背包)
A domino is a flat, thumbsized tile, the face of which is divided into two squares, each left blank ...
- Min(BZOJ 1441)
题目描述 给出n个数(A1...An)现求一组整数序列(X1...Xn)使得S=A1*X1+...An*Xn>0,且S的值最小 输入 第一行给出数字N,代表有N个数 下面一行给出N个数 输出 S ...
- MongoDB_副本集集群模式
主从模式: 在10.3.13.213 主节点, 10.3.2.33 从节点.mongodb 安装路径均为:/usr/local/server/mongodb 参考文章:http://www.lance ...
- ajax 提交数组,mybatis 数组接受
function jinxingzhong() { // 配送单编号:psd2017090103 var divHtml = ""; $.ajax({ type: "PO ...