Exemplo n.º 1
0
            public static InternalPacket ProtoDeserialize(byte[] data, int pos, int size)
            {
                InternalPacket ret         = new InternalPacket();
                PacketProto    protoPacket = new PacketProto();

                MemoryStream ms = new MemoryStream(data, pos, size);

                protoPacket.MergeFrom(ms);

                ret.MsgId          = protoPacket.MsgId;
                ret.FullMethodName = protoPacket.FullMethodName;
                ret.Options        = protoPacket.Options;

                if (protoPacket.DataTypeCase == PacketProto.DataTypeOneofCase.Payload)
                {
                    ret.Payload = protoPacket.Payload.Data.ToByteArray();
                    int payloadSize = protoPacket.Payload.Size;

                    if (payloadSize < 0 || payloadSize > ms.Length || ret.Payload.Length != payloadSize)
                    {
                        throw new InvalidDataException("Pacote inválido: tamanho de payload inválido");
                    }
                }

                if (protoPacket.DataTypeCase == PacketProto.DataTypeOneofCase.Exception)
                {
                    ret.Exception = RpcExceptionFactory.CreateFrom(protoPacket.Exception);
                }

                return(ret);
            }
Exemplo n.º 2
0
        /// <summary>
        /// Encerra o RPC conforme o resultado da finalização da task de entrada.
        /// Caso a task tenha sido encerrada com sucesso, o RPC é desconectado com o envio do
        /// valor de retorno da task, encerrando as chamadas remotas com sucesso usando o valor
        /// de retorno em questão.
        /// Caso a task tenha sido encerrada com erro, um erro RpcException é enviado
        /// para o ponto remoto, encerrando as chamadas remotas com erro.
        /// Em qualquer caso, as chamadas locais são canceladas/encerradas por desconexão.
        /// </summary>
        /// <param name="taskSend">Task de processamento do retorno do RPC</param>
        public void Close(Task <TSend> taskSend)
        {
            if (m_State != StreamState.Open)
            {
                return;
            }
            m_State = StreamState.Closed;

            InternalPacket packet;

            if (taskSend.IsFaulted || taskSend.IsCanceled)
            {
                var rpcException = RpcExceptionFactory.CreateFrom(taskSend.Exception);
                packet = PacketFactory.NewPacket(m_MsgId, P_OPTIONS_RPC_ERROR, rpcException);
            }
            else
            {
                var data = taskSend.Result;
                packet = PacketFactory.NewPacket(m_MsgId, P_OPTIONS_RPC_RETURN, m_Method.RequestMarshaller, data);
            }

            m_Session.TrySend(packet);
            m_ReturnValueTcs.TrySetCanceled();
            Finish();
        }
Exemplo n.º 3
0
        /// <summary>
        /// Cancela o RPC atual.
        /// As chamadas locais pendentes são canceladas/encerradas por desconexão.
        /// As chamadas remotas pendentes são canceladas caso ainda conectado.
        /// </summary>
        public void Cancel()
        {
            if (m_State == StreamState.Open)
            {
                m_State = StreamState.Canceled;
                var rpcException = RpcExceptionFactory.Create(StatusCode.Cancelled, "A operação foi cancelada.");
                var packet       = PacketFactory.NewPacket(m_MsgId, P_OPTIONS_RPC_ERROR, rpcException);
                m_Session.Send(packet);
                m_ReturnValueTcs.TrySetCanceled();

                Finish();
            }
        }
Exemplo n.º 4
0
        // ---------------------------------
        // ----- PAYLOAD IS TASKRESULT -----
        // ---------------------------------

        public static Task <InternalPacket> NewPacket <TSend>(int msgId, Marshaller <TSend> marshaller, Task <TSend> taskResult)
        {
            GrpcPreconditions.CheckNotNull(marshaller, nameof(marshaller));
            GrpcPreconditions.CheckNotNull(taskResult, nameof(taskResult));

            return(taskResult.ContinueWith((tResult) =>
            {
                if (taskResult.IsFaulted)
                {
                    var rpcException = RpcExceptionFactory.CreateFrom(taskResult.Exception);
                    return NewInternalPacket(msgId, P_DEFAULT_OPTIONS, null, rpcException);
                }

                if (taskResult.IsCanceled)
                {
                    return null;
                }

                return NewInternalPacket(msgId, P_DEFAULT_OPTIONS, null, marshaller, taskResult.Result);
            }));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Encerra o RPC conforme o resultado da finalização da task de entrada.
        /// Caso a task tenha sido encerrada com sucesso, o RPC é desconectado sem o envio de
        /// um valor de retorno, encerrando as chamadas remotas por desconexão (close).
        /// Caso a task tenha sido encerrada com erro, um erro RpcException é enviado
        /// para o ponto remoto, encerrando as chamadas remotas com erro.
        /// Em qualquer caso, as chamadas locais são canceladas/encerradas por desconexão.
        /// </summary>
        /// <param name="taskSend">Task de processamento do retorno do RPC</param>
        public void Close(Task taskSend)
        {
            if (m_State != StreamState.Open)
            {
                return;
            }
            m_State = StreamState.Closed;

            InternalPacket packet;

            Exception ex = null;

            if (taskSend.IsFaulted)
            {
                ex = taskSend.Exception;
            }
            else if (taskSend.IsCanceled)
            {
                ex = new OperationCanceledException();
            }

            if (taskSend.IsFaulted || taskSend.IsCanceled)
            {
                // Failed return
                var rpcException = RpcExceptionFactory.CreateFrom(ex);
                packet = PacketFactory.NewPacket(m_MsgId, P_OPTIONS_RPC_ERROR, rpcException);
            }
            else
            {
                // Normal return
                packet = PacketFactory.NewPacket(m_MsgId, P_OPTIONS_RPC_CLOSE);
            }

            m_Session.TrySend(packet);
            m_ReturnValueTcs.TrySetCanceled();
            Finish();
        }