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(); } }
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 { } } } }
// 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); }
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); } } }
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); }
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); } }