/// <summary> /// Private method for simplifying the remote procedure call. I don't want to write this in IL!! /// </summary> /// <param name="clientObject"></param> /// <param name="functionToCall"></param> /// <param name="args"></param> /// <returns></returns> public static object RemoteCallClient(IRPCProxy clientObject, string functionToCall, object[] args) { if (!clientObject.IsDisposed) { var connection = clientObject.ServerConnection; RemoteCallWrapper wrapper = new RemoteCallWrapper(); wrapper.args = (from arg in args select RPCArgumentBase.CreateDynamic(arg)).ToList(); wrapper.name = functionToCall; wrapper.instanceId = clientObject.ServerInstanceID; var guid = ShortGuid.NewGuid(); string packetTypeRequest = clientObject.ImplementedInterface.Name + "-RPC-CALL-" + wrapper.instanceId; string packetTypeResponse = packetTypeRequest + "-" + guid; SendReceiveOptions options = clientObject.SendReceiveOptions; clientObject.RPCTimeout = 500000; if (options != null) { wrapper = connection.SendReceiveObject <RemoteCallWrapper, RemoteCallWrapper>(packetTypeRequest, packetTypeResponse, clientObject.RPCTimeout, wrapper, options, options); } else { wrapper = connection.SendReceiveObject <RemoteCallWrapper, RemoteCallWrapper>(packetTypeRequest, packetTypeResponse, clientObject.RPCTimeout, wrapper); } if (wrapper.Exception != null) { throw new RPCException(wrapper.Exception); } for (int i = 0; i < args.Length; i++) { args[i] = wrapper.args[i].UntypedValue; } if (wrapper.result != null) { return(wrapper.result.UntypedValue); } else { return(null); } } else { throw new ObjectDisposedException("clientObject", "RPC object has already been disposed of and cannot be reused"); } }
public string RPCDemo() { //获取RPCInvoke IRPCInvoke invoke = Core.Resolve <IRPCInvoke>("RPC"); invoke.Register <Param, string>("ADD", Add); //获取RPCProxy IRPCProxy proxy = Core.Resolve <IRPCProxy>("RPC"); //输入错误的函数名称会报错 string result = proxy.DoFunc <Param, string>("Add", new Param("Demo:", "Test1")); IRPCProxy proxy2 = Core.Resolve <IRPCProxy>("RPC"); result += "\n"; result += proxy2.DoFunc <Param, string>("ADD", new Param("Demo:", "Test2")); return(result); }
/// <summary> /// Causes the provided <see cref="IRPCProxy"/> instance to be disposed /// </summary> /// <param name="clientObject">The <see cref="IRPCProxy"/> to dispose</param> public static void DestroyRPCClient(IRPCProxy clientObject) { if (!clientObject.IsDisposed) { clientObject.GetType().GetField("isDisposed", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(clientObject, true); var connection = clientObject.ServerConnection; if (connection.ConnectionInfo.ConnectionState != ConnectionState.Shutdown) { string packetTypeRequest = clientObject.ImplementedInterface.Name + "-REMOVE-REFERENCE-" + clientObject.ServerInstanceID; RemoteCallWrapper wrapper = new RemoteCallWrapper(); wrapper.args = new List <RPCArgumentBase>(); wrapper.name = null; wrapper.instanceId = clientObject.ServerInstanceID; //Tell the server that we are no longer listenning try { connection.SendObject <RemoteCallWrapper>(packetTypeRequest, wrapper); } catch (Exception) { } //Next remove the event packet handler try { connection.RemoveIncomingPacketHandler(clientObject.ImplementedInterface.Name + "-RPC-LISTENER-" + clientObject.ServerInstanceID); } catch (Exception) { } //Next remove the server side dispose handler try { connection.RemoveIncomingPacketHandler(clientObject.ImplementedInterface.Name + "-RPC-DISPOSE-" + clientObject.ServerInstanceID); } catch (Exception) { } } //Finally remove the object from the cache. This guarentees that if we try to get the instance again at some time in the future //we won't end up with a disposed RPC object lock (cacheLocker) { var cacheKey = new CachedRPCKey(clientObject.ServerInstanceID, clientObject.ServerConnection, clientObject.ImplementedInterface); try { cachedInstances.Remove(cacheKey); } catch (Exception) { } } } }