示例#1
0
        /// <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);
        }
示例#3
0
        /// <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) { }
                }
            }
        }