【问题标题】:Dynamically invoke a method over a socket通过套接字动态调用方法
【发布时间】:2013-06-05 09:59:53
【问题描述】:

我有两台电脑和一些软件,现在我需要一台电脑在另一台电脑上执行一个方法,现在我搜索了高低,但找不到任何关于如何执行此操作的信息。我可以通过编写自己的小接口来实现这一点,该接口序列化参数、方法名称和返回对象,并通过套接字发送,然后反序列化,使用反射执行方法,并通过套接字返回结果对象。但在我开始以另一种方式编写更容易的东西之前,我想听听其他人的意见。

  • 发送多个参数(它们都将作为对象接收和发送)
  • 返回一个对象
  • 如果发生异常对象,则序列化回一个异常对象

我在序列化对象并通过套接字发送它们方面没有做任何事情,但是所有标准对象都是可序列化的吗?喜欢List<> array[] float dateTime

我希望已经解释清楚了,如果没有我很抱歉并问什么不清楚。

【问题讨论】:

    标签: c# sockets reflection methods invoke


    【解决方案1】:

    创建服务 WCF 并配置 WCF 以通过 TCP 工作。

    这将为您提供“开箱即用”的大多数东西(序列化/反序列化,打开/关闭套接字)

    有很好的例子herehere和很好的阅读here

    【讨论】:

    • 我已经搜索了这个例子,但我找不到任何我完全理解的东西,我需要的是网络上有多个通勤者可以在其他通勤者上执行方法,但我没有在网络上找到了任何易于阅读的示例。
    【解决方案2】:

    我已经在互联网上搜索示例并将一些代码粘贴在一起,如果有人也需要它,我将其发布在这里。这是一个肮脏的代码,但它可以工作,InvokeMethod 在客户端,而 startIBC 是需要在每个服务器上启动的:

    [ServiceContract]
        public interface IBlissRequest
        {
            [OperationContract]
            object SystemRequest(string InstanceName, string MethodName, params object[] Parameters);
        }
    
        public class BlissRequest : IBlissRequest
        {
            public object SystemRequest(string InstanceName, string MethodName, params object[] Parameters)
            {
                return System21.BlissProcessingUnit.BPU.RequestFromIBC(InstanceName, MethodName, Parameters);
            }
        }
    
    public static object InvokeMethod(string targetIpAddress, string InstanceName, string MethodName, params object[] Parameters)
            {
                try
                {
                    var ep = "net.tcp://" + targetIpAddress + ":9985/IBC";
    
                    NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
    
                    ChannelFactory<IBlissRequest> pipeFactory = new ChannelFactory<IBlissRequest>(binding, new EndpointAddress(ep));
    
                    IBlissRequest pipeProxy = pipeFactory.CreateChannel();
    
                    return pipeProxy.SystemRequest(InstanceName, MethodName, Parameters);
                }
                catch 
                {
                    BPUConsole.WriteLine(BPUConsole.WriteSource.IBC, "Unable to execute method: '" + MethodName +"' on Instance: '"+InstanceName+"' becouse IBC is unable to connect to: "+ targetIpAddress);
                    throw new Exception("Unable to connect to: " + targetIpAddress);
                }
            }
    
            public static void StartIBC()
            {
                var uri = "net.tcp://" + BlissProcessingUnit.BPUInformation.LocalIpAddresses[0] + ":9985";
                Console.WriteLine("Opening connection on: " + uri);
    
                ServiceHost host = new ServiceHost(typeof(BlissRequest), new Uri[] { new Uri(uri) });
    
                NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
    
                host.AddServiceEndpoint(typeof(IBlissRequest), binding, "IBC");
    
                host.Open();
    
                Console.WriteLine("Service is available. " + "Press <ENTER> to exit.");
    
            }
    

    【讨论】:

      【解决方案3】:

      您所描述的内容听起来像是远程过程调用 (RPC)。 RPC 允许您在服务器上创建单个对象,客户端可以与该对象进行交互,就好像它是本地对象一样(因此完全避免了处理套接字的需要)。或者,每个客户端也可以创建自己的唯一服务器对象来与之交互。

      可以在网络库networkcomms.net 中找到完整的 RPC 实现。以下代码 sn-p 取自可用的 RPC 示例,并使用类型为 MathClass 的对象,该对象可以执行简单的数学计算。

      对象存在服务器端:

      //Register a single object server side called "Calculator"
      RemoteProcedureCalls.Server.RegisterInstanceForPublicRemoteCall<MathClass, IMath>(new MathClass(), "Calculator");
      

      在客户端:

      //Get a reference to the remote object named "Calculator"
      IMath calc = RemoteProcedureCalls.Client.CreateProxyToPublicNamedInstance<IMath>(connection, "Calculator", out instanceId);
      //We can now use the calculator object as if it were local
      //The following WriteLine outputs '12' where the calculation was performed on the server
      Console.WriteLine(calc.Multiply(4, 3));
      

      免责声明:我必须补充一点,我是这个库的开发人员。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-29
        • 2018-06-25
        • 2014-02-20
        • 2012-07-07
        • 1970-01-01
        • 2017-06-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多