简体   繁体   English

通过套接字动态调用方法

[英]Dynamically invoke a method over a socket

I have 2 pc's with some software, now I need one pc to execute a method on another pc, now I've searched high and low but could not find anything on how to do this. 我有两台装有某些软件的电脑,现在我需要一台电脑才能在另一台电脑上执行一种方法,现在我搜索过高和过低,但找不到有关如何执行此操作的任何信息。 I could do this with writing my own little interface that serializes the arguments, method name and return objects and sending this over a socket then deserialize this execute the method using reflection, and return an result object over the socket. 我可以编写自己的小接口来序列化参数,方法名和返回对象,然后通过套接字发送,然后使用反射反序列化执行该方法,然后通过套接字返回结果对象。 But I would like someone else's opinion before I start writing something that is much easier another way. 但是在我开始写另一种更容易的东西之前,我希望别人的意见。

  • Send multiple arguments (they will all be received and send as an object) 发送多个参数(它们都将被接收并作为对象发送)
  • Return an object 返回一个对象
  • serialize back an exception object if any has occurred 如果发生任何异常,则序列化回一个异常对象

I have not done anything in serializing objects and sending them over a socket, but are all standard objects serializable? 在序列化对象和通过套接字发送它们方面,我没有做任何事情,但是所有标准对象都可以序列化吗? Like a List<> array[] float dateTime ? 就像List<> array[] float dateTime吗?

I hope to have explained this ok, if not I'm sorry and ask what is not clear. 我希望可以对此进行解释,如果没有,对不起,请问不清楚的地方。

Create service WCF and config WCF to work over TCP. 创建服务WCF并配置WCF以在TCP上工作。

This will give you most things 'out of the box' (serialize /deserialize, open/close socket ) 这将为您“开箱即用”提供大多数功能(序列化/反序列化,打开/关闭套接字)

There are good examples here , here and good reading here 有很好的例子在这里这里和良好的阅读这里

I have searched the internet for examples and pasted together some code, i'm posting it here if somone needs it too. 我在互联网上搜索了示例,并粘贴了一些代码,如果有人也需要它,我会在此处发布它。 This is a dirty code but it works, the InvokeMethod is on the client side, and the startIBC is what needs to be started on each server: 这是一个肮脏的代码,但是它可以工作,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.");

        }

What you are describing sounds like remote procedure calling (RPC). 您所描述的听起来像是远程过程调用(RPC)。 RPC allows you to create a single object on a server which clients can interact with as if it were a local object (so completely avoid the need to deal with sockets). RPC允许您在服务器上创建单个对象,客户端可以像本地对象一样与之进行交互(因此完全避免了处理套接字的需要)。 Alternatively each client can also create its own unique server object to interact with. 或者,每个客户端也可以创建自己的唯一服务器对象以进行交互。

A full implementation of RPC can be found in the network library networkcomms.net . 可以在网络库networkcomms.net中找到RPC的完整实现。 The following code snippet is taken from the available RPC example and uses an object of type MathClass that can perform simple maths calculations. 以下代码段摘自可用的RPC示例,并使用了MathClass类型的对象,该对象可以执行简单的数学计算。

The object exists server side: 该对象存在于服务器端:

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

On the client side: 在客户端:

//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));

Disclaimer: I have to add that I am a developer for this library. 免责声明:我必须补充一点,我是该库的开发人员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM