【转载】.NET Remoting学习笔记(二)激活方式

【转载】.NET Remoting学习笔记(二)激活方式

目录
  • .NET Remoting学习笔记(一)概念
  • .NET Remoting学习笔记(二)激活方式
  • .NET Remoting学习笔记(三)信道

参考:百度百科 ♂风车车.Net

激活方式概念

在访问远程类型的一个对象实例之前,必须通过一个名为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.运行服务端后,开启两个客户端程序,查看结果如下:

<span>【转载】.NET Remoting学习笔记(二)激活方式</span>

代码示意中,当TestMessageMarshal有新实例时,其构造函数会创建不同的标识(GUID),服务端接收到客户端的数据请求,并将标识编号输出到界面,从界面中可以看出,多个客户端请求的通道,服务端都是用一个通道(一个实例)来进行处理的。

SingleCall模式

SingleCall是一种无状态模式。一旦设置为SingleCall模式,则当客户端调用远程对象的方法时, Remoting会为每一个客户端建立一个远程对象实例,至于对象实例的销毁则是由GC自动管理的。同上一个例子而言,则访问远程对象的两个客户获得的都是1。我们仍然可以借鉴Asp .Net的状态管理,认为它是一种Session状态。

我们修改服务端代码如下,客户端不需要修改:

/*服务端注册,使用SingleCall激活*/
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(MessageMarshal.TestMessageMarshal), "TestMessageMarshal", WellKnownObjectMode.SingleCall);

开启服务端,然后开启一个客户端,如下
<span>【转载】.NET Remoting学习笔记(二)激活方式</span>

从输出结果中可以看出,每次服务端都会为每一个客户端请求建立一个远程对象实例。

客户端激活

与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.测试,开启服务端和两个客户端
<span>【转载】.NET Remoting学习笔记(二)激活方式</span>

可以看出每个服务端为每个客户端都会创建一个实例对象。

其测试目录结构如下,不然客户端远程对象和服务端会不对应。会报“找不到请求的服务”的异常

 

<span>【转载】.NET Remoting学习笔记(二)激活方式</span> 

注意:服务端对象和客户端对象激活方式的区别:

服务端激活时,服务通过RegisterWellKnownServiceType方法的objectUri来标识

客户端激活时,服务通过RemotingConfiguration.ApplicationName属性来标识

客户端调用服务时,用务地址需指定正确

 

这就是 Remoting 的三种 激活方式,如有问题欢迎指正。

作者:释迦苦僧 出处:http://www.cnblogs.com/woxpp/p/3995366.html 

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119394.html原文链接:https://javaforall.net

(0)
上一篇 2021年11月18日 下午7:00
下一篇 2021年11月18日 下午7:00


相关推荐

  • let暂时性死区理解「建议收藏」

    let暂时性死区理解「建议收藏」Let中提到的暂时性死区到底是什么,它的产生原因是? ES6规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”,也就是说使用let声明的变量都是先声明再使用,不存在变量提升问题。letmyname=’sxx’;{console.log(myname);l…

    2022年6月24日
    29
  • Android应用程序开发以及背后的设计思想深度剖析(1)

    Android应用程序开发以及背后的设计思想深度剖析(1)本文内容 主题是透过应用程序来分析 Android 系统的设计原理与构架 我们先会简单介绍一下 Android 里的应用程序编程 然后以这些应用程序在运行环境上的需求来分析出 为什么我们的 Android 系统需要今天这样的设计方案 这样的设计会有怎样的意义 Android 究竟是基于怎样的考虑才变成今天的这个样子 所以本文更多的分析 Android 应用程序设计背后的思想 品味良好架构设计的魅力 分五次连载完成

    2026年3月18日
    4
  • 【n8n教程笔记——工作流Workflow】n8n部署 Windows n8n安装n8n Docker-compose n8n tunnel n8n PostgreSQL n8n时区设置

    【n8n教程笔记——工作流Workflow】n8n部署 Windows n8n安装n8n Docker-compose n8n tunnel n8n PostgreSQL n8n时区设置

    2026年3月15日
    4
  • awk 用法示例大全[通俗易懂]

    awk 用法示例大全[通俗易懂]文章目录#删除temp文件的重复行awk’!($0inarray){array[$0];print}’temp#查看最长使用的10个unix命令awk'{print$1}’~/.bash_history|sort|uniq-c|sort-rn|head-n10#查看机器的ip列表ifconfig-a|awk’/Bcast/{print$2}’|cut-c5-19#查看机器的每个远程链接机器的连接数netstat-ant

    2022年7月11日
    24
  • memcached 与redis 的区别?

    memcached 与redis 的区别?1 Redis 不仅仅支持简单的 k v 类型的数据 同时还提供 list set zset hash 等数据结构的存储 而 memcache 只支持简单数据类型 需要客户端自己处理复杂对象 2 Redis 支持数据的持久化 可以将内存中的数据保持在磁盘中 重启的时候可以再次加载进行使用 PS 持久化在 rdb aof 3 由于 Memcache 没有持久化机制 因此宕机所有缓存数据失效 Redis 配置为持久化 宕机重启后 将自动加载宕机时刻的数据到缓存系统中 具有更好的灾备机制 4 Memcache 可以

    2026年3月19日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号