Example #1
0
        public virtual void SendResponse(DataContent dataContent, int requestId, bool canBeCached, bool cache)
        {
            var stop = ProtocolWatch.Start("rp-send-response");

            Monitor.Enter(this);
            try
            {
                ThrowClosed();

                var requestHeader = new RequestHeader()
                {
                    RequestId    = requestId,
                    RequestType  = RequestType.Response,
                    CanBeCached  = canBeCached,
                    RezervedFlag = 0,
                };

                var index = PrepareSendData(sendBuffer, requestHeader, dataContent);

                packetStream.WritePacket(sendBuffer, (ushort)index, false);
            }
            catch (Exception e)
            {
                OnClosed(e);
                throw;
            }
            finally
            {
                Monitor.Exit(this);
                stop();
            }
        }
Example #2
0
        protected virtual async void HandleRequest(DataContent dataContent, int requestId, int index, CancellationTokenSource cancellationTokenSource)
        {
            var cache = false;

            try
            {
                var stop   = ProtocolWatch.Start("rp-handle-request");
                var result = await protocolHandler.HandleDataAsync(ResolverSession, dataContent, cancellationTokenSource.Token);

                stop();
                SendResponse(result, requestId, false, cache);
            }
            catch (Exception e)
            {
                try
                {
                    var response = CreateErrorResponse(e);
                    SendResponse(response, requestId, false, cache);
                }
                catch (Exception re)
                {
                    try
                    {
                        OnClosed(e);
                        cancellationTokenSource.Cancel();
                    }
                    catch { }
                }
            }
        }
Example #3
0
        public async Task <DataContent> HandleDataAsync(IResolverSession session, DataContent dataContent, CancellationToken cancellationToken)
        {
            var actionHashData = dataContent[DataFlag.ActionHash].First()?.Data;
            var request        = dataContent[DataFlag.Data].Select(d => d.Data).ToArray();

            if (actionHashData == null || !(actionHashData is ByteArray actionHash))
            {
                throw new ProtocolException("Parameter hash is null or not ByteArray", ErrorCode.BadRequest);
            }

            if (!handlerProvider.TryGetHandler(actionHash, out var handlerItem))
            {
                throw new ProtocolException($"Handler for action hash '{actionHash}' not found", ErrorCode.BadRequest);
            }

            object response = await handlerItem.HandleAsync(session ?? resolverSession, request, cancellationToken);

            if (response == null)
            {
                return(new DataContent());
            }

            return(new DataContent(new DataContext()
            {
                Data = response,
                DataFlag = DataFlag.Data
            }));
        }
Example #4
0
        public virtual void SendResponse(object response, int requestId, bool canBeCached, bool cache)
        {
            var dataContent = new DataContent(new DataContext()
            {
                DataFlag = DataFlag.Data,
                Data     = response,
            });

            SendResponse(dataContent, requestId, canBeCached, cache);
        }
Example #5
0
        public static T GetData <T>(this DataContent content, byte type) where T : class
        {
            var data = content[type].SingleOrDefault()?.Data;

            if (data == null)
            {
                return(null);
            }
            if (data is T t)
            {
                return(t);
            }

            throw new ArgumentException($"Data for data flag '{type}' is not of type '{typeof(T).FullName}' but '{data.GetType().FullName}'");
        }
Example #6
0
        // todo request cache

        public virtual Task <DataContent> HandleDataAsync(IResolverSession session, DataContent dataContent, CancellationToken cancellationToken)
        {
            var stop       = ProtocolWatch.Start("send-request");
            var taskSource = new TaskCompletionSource <DataContent>();

            Monitor.Enter(this);
            try
            {
                ThrowClosed();

                var requestId = lastRequestId++;

                var requestHeader = new RequestHeader()
                {
                    RequestId    = requestId,
                    CanBeCached  = false,
                    RequestType  = RequestType.Request,
                    RezervedFlag = 0
                };


                var index = PrepareSendData(sendBuffer, requestHeader, dataContent);

                responses[requestId] = taskSource;

                cancellationToken.Register(() =>
                {
                    if (responses.TryRemove(requestId, out var tcs))
                    {
                        tcs.TrySetCanceled();
                    }
                });

                packetStream.WritePacket(sendBuffer, index, false);
            }
            catch (Exception e)
            {
                OnClosed(e);
                throw;
            }
            finally
            {
                Monitor.Exit(this);
                stop();
            }

            return(taskSource.Task);
        }
Example #7
0
        protected virtual void HandleResponse(DataContent dataContent, int requestId, bool canBeCached, int index)
        {
            var stop = ProtocolWatch.Start("rp-handle-response");

            if (responses.TryRemove(requestId, out var tcs))
            {
                try
                {
                    if (tcs.Task.IsCompleted || tcs.Task.IsCanceled || tcs.Task.IsFaulted)
                    {
                        return;
                    }

                    tcs.TrySetResult(dataContent);
                    stop();
                }
                catch (Exception e)
                {
                    tcs.TrySetException(e);
                }
            }
        }
Example #8
0
        public object HandleAsync(string methodName, byte[] actionHashBytes, object[] args)
        {
            var watch = Stopwatch.StartNew();

            var stop = ProtocolWatch.Start("handle-async");

            var actionHash    = new ByteArray(actionHashBytes);
            var methodContext = context.GetMethodContext(actionHash);

            CancellationToken cancellationToken;

            if (methodContext.CancellationIndex >= 0)
            {
                cancellationToken = (CancellationToken)args[methodContext.CancellationIndex];
            }
            else
            {
                var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));
                cancellationToken = cts.Token;
            }

            stop();

            stop = ProtocolWatch.Start("handle-send-request");

            var actionHashDataContext = new DataContext()
            {
                DataFlag = DataFlag.ActionHash,
                Data     = actionHash,
            };

            var additionalCount = 1;

            var argumentContexts = new DataContext[methodContext.ArgumentIndexes.Length + additionalCount]; // { actionDataContext, dataDataContext };

            argumentContexts[0] = actionHashDataContext;

            for (int i = 0; i < methodContext.ArgumentIndexes.Length; i++)
            {
                argumentContexts[i + additionalCount] = new DataContext()
                {
                    DataFlag = DataFlag.Data,
                    Data     = args[methodContext.ArgumentIndexes[i]],
                };
            }

            var dataContent = new DataContent(argumentContexts);

            var result = protocolHandler.HandleDataAsync(resolverSession, dataContent, cancellationToken); // todo change to Add session

            stop();
            stop = ProtocolWatch.Start("handle-async");

            var tcsType = methodContext.TaskCompletionSourceType;
            var task    = WrapTask(result, tcsType, methodContext.ContextInfo.MethodInfo.ReturnType.GenericTypeArguments.Length > 0);

            stop();
            watch.Stop();
            ts += (int)watch.Elapsed.Ticks;

            return(task);
        }
Example #9
0
        protected virtual void HandlePacket(byte[] readBuffer, int length, CancellationTokenSource cancellationTokenSource)
        {
            ThrowClosed();

            var stop = ProtocolWatch.Start("rp-receive-request");

            var index = 0;

            var converterHeader = protocolConverter.Resolve <ConverterHeader>(readBuffer, ref index);
            var requestHeader   = protocolConverter.Resolve <RequestHeader>(readBuffer, ref index);

            if (converterHeader.VersionMajor != 1)
            {
                throw new ProtocolException(ErrorCode.VersionNotSupported);
            }


            if (SecurityInject != null)
            {
                var securityContext = new SecurityInjectContext()
                {
                    ConverterHeader = converterHeader,
                    RequestHeader   = requestHeader,
                    HeaderEndIndex  = index,
                    Data            = sendBuffer,
                    Length          = length
                };

                SecurityInject?.ReceiveSecurity(ResolverSession, securityContext);
                length = securityContext.Length;
            }

            var resolvedContexts = protocolConverter.Resolve(readBuffer, ref index, length);
            var resolvedContent  = new DataContent(resolvedContexts);

            if (DataInject != null)
            {
                var injectContext = new DataInjectContext()
                {
                    ConverterHeader = converterHeader,
                    RequestHeader   = requestHeader,
                    DataContent     = resolvedContent,
                };

                DataInject.ReceiveData(ResolverSession, injectContext);
            }

            stop();


            var requestId = requestHeader.RequestId;

            if (requestHeader.RequestType == RequestType.Response)
            {
                HandleResponse(resolvedContent, requestId, requestHeader.CanBeCached, index);
            }
            else if (requestHeader.RequestType == RequestType.Request)
            {
                HandleRequest(resolvedContent, requestId, index, cancellationTokenSource);
            }
            else
            {
                throw new ProtocolException(ErrorCode.BadRequest);
            }
        }
Example #10
0
        protected virtual int PrepareSendData(byte[] sendBuffer, RequestHeader requestHeader, DataContent dataContent)
        {
            var index = 4;

            var converterHeader        = this.ConverterHeader;
            var converterHeaderContext = new DataContext()
            {
                Data     = converterHeader,
                DataFlag = DataFlag.Header,
            };

            var requestHeaderContext = new DataContext()
            {
                Data     = requestHeader,
                DataFlag = DataFlag.Header
            };

            DataContext[] dataContexts = null;
            if (DataInject != null)
            {
                var injectContext = new DataInjectContext()
                {
                    ConverterHeader = ConverterHeader,
                    RequestHeader   = requestHeader,
                    DataContent     = dataContent,
                };

                dataContexts                = DataInject.SendData(ResolverSession, injectContext)?.ToArray();
                converterHeader             = injectContext.ConverterHeader;
                converterHeaderContext.Data = converterHeader;
            }

            protocolConverter.Apply(sendBuffer, ref index, converterHeaderContext, requestHeaderContext);
            var headerEndIndex = index;

            if (dataContexts != null)
            {
                protocolConverter.Apply(sendBuffer, ref index, dataContexts);
            }

            protocolConverter.Apply(sendBuffer, ref index, dataContent.DataContexts);

            if (SecurityInject != null)
            {
                var securityContext = new SecurityInjectContext()
                {
                    ConverterHeader = converterHeader,
                    RequestHeader   = requestHeader,
                    HeaderEndIndex  = headerEndIndex,
                    Data            = sendBuffer,
                    Length          = index
                };

                SecurityInject?.SendSecurity(ResolverSession, securityContext);
                index = securityContext.Length;
            }

            sendBuffer.InsertLength(index - 4);

            return(index);
        }
Example #11
0
        public static object GetData(this DataContent content, byte type)
        {
            var data = content[type].SingleOrDefault()?.Data;

            return(data);
        }