private static void RunRPCFunctionHandler <T, I>(PacketHeader header, Connection connection, RemoteCallWrapper wrapper) where T : I { I instance = default(I); MethodInfo funcRef = typeof(I).GetMethod(wrapper.name); try { lock (locker) { instance = (I)(RPCObjectsById[wrapper.instanceId].RPCObject); } } catch (Exception) { wrapper.result = null; wrapper.Exception = "SERVER SIDE EXCEPTION\n\n" + "Invalid instanceID" + "\n\nEND SERVER SIDE EXCEPTION\n\n"; connection.SendObject(header.PacketType, wrapper); return; } object[] args = null; if (wrapper.args == null) { args = new object[0]; } else { args = (from arg in wrapper.args select arg.UntypedValue).ToArray(); } try { wrapper.result = RPCArgumentBase.CreateDynamic(funcRef.Invoke(instance, args)); wrapper.args = (from arg in args select RPCArgumentBase.CreateDynamic(arg)).ToList(); } catch (Exception e) { wrapper.result = null; if (e.InnerException != null) { e = e.InnerException; } wrapper.Exception = "SERVER SIDE EXCEPTION\n\n" + e.ToString() + "\n\nEND SERVER SIDE EXCEPTION\n\n"; } string returnPacketType = header.GetOption(PacketHeaderStringItems.RequestedReturnPacketType); connection.SendObject(returnPacketType, wrapper); }
/// <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"); } }
private static EventHandler <A> GenerateEvent <A>(Connection clientConnection, string instanceId, Type interfaceType, string eventName) where A : EventArgs { return(new EventHandler <A>((sender, args) => { var packetType = interfaceType.Name + "-RPC-LISTENER-" + instanceId; RemoteCallWrapper callWrapper = new RemoteCallWrapper(); callWrapper.name = eventName; callWrapper.instanceId = instanceId; callWrapper.args = new List <RPCArgumentBase>() { RPCArgumentBase.CreateDynamic(sender), RPCArgumentBase.CreateDynamic(args) }; clientConnection.SendObject(packetType, callWrapper); })); }