• C# Remoting例子


     4-23 https://www.cnblogs.com/zhengyun_ustc/archive/2006/06/09/remoting_InvalidCredentialException.html

     今天看了一篇C# Remoting的一个简单例子,博主简单的介绍了remoting,目前所开发的系统也用到了remoting,特意重温了下系统,发觉其实也就那么回事情,服务器端定义远程对象,配置配置文件,客户端调用远程对象,其实也没有那么高大上(可能本人还未理解其中精髓)。

      先展示代码,再说明这其中的机制(以C# Remoting的一个简单例子为基础)

    1 创建RemoteSample项目,将其编译成lib文件。

    在这个项目中创建三个接口(RemoteArrayInterface,RemoteStringInterface,RemoteCacuteInterface,这三个接口有不同的用途,分别处理字符串、数组、计算。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    namespace RemoteSample
    {
      public  interface RemoteArrayInterface
        {
          int SumArray(int[] a);
        }
    }

      

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    namespace RemoteSample
    {
      public  interface RemoteCalcuteInterface
        {
             int sum(int a, int b);
        }
    }

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    namespace RemoteSample
    {
      public  interface RemoteStringInterface
        {
         string CombineString(string str1, string str2);
        }
    }

     2,  server端

    1)创建一个远程类,继承MarshalByRefObject,实现上面的接口     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using RemoteSample;
    namespace RemoteSampleServer
    {
        public class RemoteObject : MarshalByRefObject,RemoteArrayInterface,RemoteCalcuteInterface,RemoteStringInterface
        {
            public RemoteObject()
            {
                Console.WriteLine("New Reference Added");
            }
            public int sum(int a, int b)
            {
                return a + b;
            }
            public  int SumArray(int[] array)
            {
                int sum = 0;
                for (int i = 0; i < array.Length; i++)
                {
                    sum += array[i];
                }
                return sum;
            }
          public string CombineString(string str1, string str2)
          {
              return  str1 + " is not equal " + str2;
          }
        }
    }

      

    2)server主体部分

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using RemoteSample;
    using System.Runtime.Remoting;
    using System.Runtime.Remoting.Channels;
    using System.Runtime.Remoting.Channels.Tcp;
    namespace RemoteSampleServer
    {
        class RemoteServer
        {
            static void Main(string[] args)
            {
                try
                {
                    TcpServerChannel tcpserverchannel = new TcpServerChannel(8888);
                    ChannelServices.RegisterChannel(tcpserverchannel,false);
                    RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteObject), "RemoteObject", WellKnownObjectMode.SingleCall);
                    Console.WriteLine("press any key");
                    Console.ReadKey();
                }
                catch(Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
     
            }
        }
    }

     原博客中注册信道只用了一个参数,该方法已经废弃了,这里有两个参数,如果启用安群,第二个参数设置为true,否则设置为false,如果设置为false,将不会使在tcp或Ipc信道上所做的安全设置无效。

    这里采用了服务器端激活(Wellknow),使用singlecall方式。

     3  客户端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using RemoteSample;
    namespace RemoteSampleClient
    {
        class RemoteClient
        {
            static void Main(string[] args)
            {
                RemoteCalcuteInterface calcuteRemote = (RemoteSample.RemoteCalcuteInterface)Activator.GetObject(typeof(RemoteSample.RemoteCalcuteInterface), "tcp://localhost:8888/RemoteObject");
                Console.WriteLine("a +b = {0}", calcuteRemote.sum(1, 5).ToString());
                RemoteStringInterface stringRemote = (RemoteSample.RemoteStringInterface)Activator.GetObject(typeof(RemoteSample.RemoteStringInterface), "tcp://localhost:8888/RemoteObject");
                Console.WriteLine(" {0}", stringRemote.CombineString("wei xiao bao","kang xi"));
                int[] array = new int[4] { 1, 3, 4, 5 };
                RemoteArrayInterface arrayRemote = (RemoteSample.RemoteArrayInterface)Activator.GetObject(typeof(RemoteSample.RemoteArrayInterface), "tcp://localhost:8888/RemoteObject");
                Console.WriteLine("The sum is  {0}", arrayRemote.SumArray(array));      
                Console.ReadKey();
            }
        }
    }

      原来客户端要注册信道,貌似不用注册信道,也能正常运行,不知道是啥原因。

    个人理解:服务器端可以定义多种服务,将每种类型的服务设计成为借口,定义一个远程对象实现这些服务。客户端按需使用,要哪种类型的就通过activation获取。

    这里很多信息在代码当中设置,在实际项目中,这样做肯定是不好的。目前我所接触的系统是通过配置文件设置,配置文件的好处的不需要修改代码,不需要编译。

    一些概念性的知识,可以查阅百度百科。

  • 相关阅读:
    CSU 1598 最长公共前缀 (简单KMP或者暴力)
    CSU
    HDU 1711 Number Sequence (KMP简单题)
    HDU 1142 A Walk Through the Forest(最短路+记忆化搜索)
    HDU 1116 Play on Words(欧拉回路+并查集)
    POJ 1384 Intervals (区间差分约束,根据不等式建图,然后跑spfa)
    HDU 1165 Eddy's research II(给出递归公式,然后找规律)
    使用kvm虚拟出Centos6.5系统相关步骤
    netstat命令
    Centos6.5安装和使用docker
  • 原文地址:https://www.cnblogs.com/wwwbdabc/p/10749624.html
Copyright © 2020-2023  润新知