示例#1
0
        /// <summary>
        /// Sends asynchronous request to the server.
        /// </summary>
        /// <param name="requestId">Request ID.</param>
        /// <param name="callParameters">Call parameters.</param>
        /// <returns>
        /// Returns <c>null</c> on success or result containing error status
        /// on failure.
        /// </returns>
        private IRpcResult SendAsyncRequest(uint requestId, RpcCallParameters callParameters)
        {
            if (!callParameters.IsAsync)
            {
                throw new InvalidOperationException("Call is not asychronous.");
            }

            IRpcResult result = null;

            try
            {
                var stream = this.GetChannelStream();
                var call   = this.ProtocolObjectFactory.BuildCall(callParameters);
                this.ProtocolObjectFactory.WriteMessage(stream, requestId, call, null);
                this.log.TraceFormat("Asynchronous message sent {0}.", requestId);
            }
            catch (IOException ex)
            {
                this.log.DebugFormat("Exception while sending a message {0}. Disconnected?", ex, requestId);
                this.CloseChannel();
                result        = this.ProtocolObjectFactory.CreateRpcResult();
                result.Status = RpcStatus.ChannelFailure;
            }

            return(result);
        }
示例#2
0
        public void WriteMessage(Stream stream, uint requestId, IRpcCall call, IRpcResult result)
        {
            // TODO: It may be more efficient to write complete request to a memory buffer first
            // and then write into the stream to avoid blocking other threads while
            // data actually being serialized.
            using (var writer = new BinaryWriter(stream, Encoding.UTF8, true))
            {
                lock (this.writeLock)
                {
                    writer.Write(requestId);

                    byte contentFlags = 0;
                    contentFlags |= call != null ? ProtocolObjectFactory.HasCallFlag : (byte)0;
                    contentFlags |= result != null ? ProtocolObjectFactory.HasResultFlag : (byte)0;
                    writer.Write(contentFlags);

                    if (call != null)
                    {
                        ((RpcCall)call).Serialize(writer);
                    }

                    if (result != null)
                    {
                        ((RpcResult)result).Serialize(writer);
                    }
                }
            }
        }
示例#3
0
        private void ExecuteRequest(ServerContext context, IRpcCall call, IRpcResult result)
        {
            IRpcServiceStub service;

            // Check whether the called method is for service or transient object.
            // The service are identified by name and the lifetime is controlled by the
            // server side.
            // The transient objects are registered as result of a method call and
            // identified by object ID. The lifetime of transient object is
            // controlled by the client.
            if (call.ObjectId != 0)
            {
                // Try to find object that corresponds to the marshalled interface.
                service = context.ObjectManager.GetInstance(call.ObjectId);
                if (service == null)
                {
                    result.Status = RpcStatus.UnknownInterface;
                    this.log.ErrorFormat(
                        "Cannot find object '{0}' with '{1}.{2}' interface",
                        call.ObjectId,
                        call.ServiceName,
                        call.MethodName);
                }
            }
            else
            {
                // Try to find service in global scope and then within connection context.
                service = this.objectManager.GetService(call.ServiceName);
                if (service == null)
                {
                    service = context.ObjectManager.GetService(call.ServiceName);
                    if (service == null)
                    {
                        this.log.ErrorFormat(
                            "Cannot find service with interface '{0}.{1}'",
                            call.ServiceName,
                            call.MethodName);
                        result.Status = RpcStatus.UnknownInterface;
                    }
                }
            }

            if (service != null)
            {
                this.log.TraceFormat("Calling method '{0}.{1}'.", call.ServiceName, call.MethodName);
                service.CallMethod(context, call, result);
            }
            else
            {
                Debug.Assert(result.Status != RpcStatus.Succeeded, "Result cannot be a success");
            }
        }
示例#4
0
        /// <summary>
        /// Sends specified request to the server.
        /// </summary>
        /// <param name="requestId">Request ID.</param>
        /// <param name="callParameters">Call parameters.</param>
        /// <returns>
        /// Returns <c>null</c> on success or result containing error status
        /// on failure.
        /// </returns>
        private IRpcResult SendSyncRequest(uint requestId, RpcCallParameters callParameters)
        {
            if (callParameters.IsAsync)
            {
                throw new InvalidOperationException("Call must be synchronous.");
            }

            lock (this.pendingCallsLock)
            {
                this.pendingCalls.Add(requestId, new PendingCall());
                this.log.TraceFormat("Registered request {0} to wait for reply.", requestId);
            }

            IRpcResult result = null;

            try
            {
                var stream = this.GetChannelStream();
                var call   = this.ProtocolObjectFactory.BuildCall(callParameters);
                this.ProtocolObjectFactory.WriteMessage(stream, requestId, call, null);
                this.log.TraceFormat("Message sent {0}.", requestId);
            }
            catch (IOException ex)
            {
                this.log.Debug("Exception while sending a message. Disconnected?", ex);
                this.CloseChannel();
                lock (this.pendingCallsLock)
                {
                    if (!this.pendingCalls.ContainsKey(requestId))
                    {
                        // This should really never happen, unless there is a logic error.
                        result        = this.ProtocolObjectFactory.CreateRpcResult();
                        result.Status = RpcStatus.InternalError;
                        this.log.ErrorFormat("Failed to find pending call {0}.", requestId);
                        Debug.Fail("Failed to find pending call.");
                    }
                    else
                    {
                        this.pendingCalls.Remove(requestId);
                    }
                }

                result        = this.ProtocolObjectFactory.CreateRpcResult();
                result.Status = RpcStatus.ChannelFailure;
            }

            return(result);
        }
示例#5
0
        public void CallMethod(IServerContext context, IRpcCall rpcCall, IRpcResult result)
        {
            if (rpcCall.MethodName == "Ping")
            {
                if (rpcCall.CallData == null || rpcCall.CallData.Length != 4)
                {
                    result.Status = RpcStatus.InvalidCallParameter;
                    return;
                }

                var counter = BitConverter.ToInt32(rpcCall.CallData, 0);
                ++counter;
                result.ResultData = BitConverter.GetBytes(counter);
            }
            else
            {
                result.Status = RpcStatus.UnknownMethod;
            }
        }
示例#6
0
        public void CallMethod(IServerContext context, IRpcCall rpcCall, IRpcResult rpcResult)
        {
            rpcResult.Status = RpcStatus.Succeeded;

            if (rpcCall.MethodName == "Method_V_V")
            {
                this.Impl.Method_V_V(context);
            }
            else if (rpcCall.MethodName == "Method_V_M")
            {
                var input = new StructType();
                input.MergeFrom(new CodedInputStream(rpcCall.CallData));
                this.Impl.Method_V_M(context, input);
                rpcResult.ResultData = new Empty().ToByteArray();
            }
            else if (rpcCall.MethodName == "Method_M_V")
            {
                var result = this.Impl.Method_M_V(context);
                rpcResult.ResultData = result.ToByteArray();
            }
            else if (rpcCall.MethodName == "Method_M_M")
            {
                var input = new StructType();
                input.MergeFrom(new CodedInputStream(rpcCall.CallData));
                var result = this.Impl.Method_M_M(context, input);
                rpcResult.ResultData = result.ToByteArray();
            }
            else if (rpcCall.MethodName == "AsyncMethod_V_V")
            {
                this.Impl.AsyncMethod_V_V(context);
            }
            else if (rpcCall.MethodName == "AsyncMethod_V_M")
            {
                var input = new StructType();
                input.MergeFrom(new CodedInputStream(rpcCall.CallData));
                this.Impl.AsyncMethod_V_M(context, input);
            }
            else
            {
                rpcResult.Status = RpcStatus.UnknownMethod;
            }
        }
示例#7
0
 public void CallMethod(IServerContext context, IRpcCall rpcCall, IRpcResult rpcResult)
 {
 }