//public static TInterface CreateHandler<TInterface, THandler>(this IResolver resolver) where TInterface : class where THandler : IInterfaceHandler //{ // var typeInfo = CreateTypeInfo(typeof(TInterface), typeof(THandler)); // var obj = (TInterface)Resolver.CreateInstance(resolver, typeInfo); // return obj; //} public static TInterface CreateHandler <TInterface, THandler>(this IResolverSession session) where TInterface : class where THandler : IInterfaceHandler { var typeInfo = CreateTypeInfo(typeof(TInterface), typeof(THandler), session.Resolve <IMethodContextInfoProvider>()); var obj = (TInterface)session.CreateInstance(typeInfo); return(obj); }
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 })); }
public static bool TryCreateInstance(this IResolverSession session, ConstructorInfo constructorInfo, out object obj) { if (session == null) { throw new ArgumentNullException(nameof(session)); } if (constructorInfo == null) { throw new ArgumentNullException(nameof(constructorInfo)); } obj = null; var parameters = constructorInfo.GetParameters(); object[] arguments = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { if (!session.TryResolve(parameters[i].ParameterType, out var value)) { return(false); } arguments[i] = value; } obj = constructorInfo.Invoke(arguments); return(true); }
public static object CreateInstance(this IResolverSession session, TypeInfo typeInfo) { if (TryCreateInstance(session, typeInfo, out var obj)) { return(obj); } throw new KeyNotFoundException($"Constructor for type $'{typeInfo.Name}' not found"); }
protected async void ClientListenAsync(TcpClient client, IResolverSession session, bool isClient, CancellationToken cancellationToken) { try { if (client.Client.RemoteEndPoint is IPEndPoint ep) { var epInfo = new EndpointInfo() { Address = ep.Address.ToString(), Port = ep.Port, }; session.Resolver.Register(epInfo); } var packetStream = new PacketStream(client.GetStream()); var protocol = new SocketProtocolHandler(session, packetStream, Serializer, HandlerProvider); session.Resolver.Register(protocol); if (!isClient) { ClientConnected(this, session); } else { Connected(this, session); } await protocol.ListenAsync(cancellationToken); } catch (Exception e) { if (!session.TryDispose(out var ex)) { TryOnException(ex); } TryOnException(e); try { if (!isClient) { ClientDisconnected(this, session, e); } else { Disconnected(this, session, e); } } catch (Exception de) { TryOnException(de); } } }
private void TryDispose() { try { session?.Dispose(); session = null; } catch { // do nothing } }
public SocketProtocolHandler(IResolverSession session, IPacketStream packetStream, IProtocolConverter protocolConverter, IProtocolHandler protocolHandler) { this.ResolverSession = session; this.packetStream = packetStream ?? throw new ArgumentNullException(nameof(packetStream)); this.protocolHandler = protocolHandler ?? throw new ArgumentNullException(nameof(protocolHandler)); this.protocolConverter = protocolConverter ?? throw new ArgumentNullException(nameof(protocolConverter)); this.ConverterHeader = new ConverterHeader() { VersionMajor = 1 }; }
public void Dispose() { slim.Wait(); try { session?.Dispose(); session = null; } finally { slim.Release(); } }
public override async Task <object> HandleAsync(IResolverSession session, object[] requests, CancellationToken cancellationToken) { await slim.WaitAsync(); try { return(await base.HandleAsync(session, requests, cancellationToken)); } finally { slim.Release(); } }
public MethodProtocolHandler(IHandlerProvider handlerProvider, IResolverSession resolverSession) { if (handlerProvider == null) { throw new ArgumentNullException(nameof(handlerProvider)); } if (resolverSession == null) { throw new ArgumentNullException(nameof(resolverSession)); } this.handlerProvider = handlerProvider; //this.resolverSession = resolverSession; }
public static bool TryCreateInstance(this IResolverSession session, TypeInfo typeInfo, out object obj) { var constructors = typeInfo.GetConstructors().OrderByDescending(c => c.GetParameters().Length).ToArray(); foreach (var constructorInfo in constructors) { if (TryCreateInstance(session, constructorInfo, out obj)) { return(true); } } obj = null; return(false); }
// 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); }
public static object CreateInstance(this IResolverSession session, ConstructorInfo constructorInfo) { if (session == null) { throw new ArgumentNullException(nameof(session)); } if (constructorInfo == null) { throw new ArgumentNullException(nameof(constructorInfo)); } var parameters = constructorInfo.GetParameters(); var arguments = parameters.Select(p => session.Resolve(p.ParameterType)).ToArray(); return(constructorInfo.Invoke(arguments)); }
public ProtocolInterfaceHandler(IProtocolHandler protocolHandler, ITypeContextProvider contextProvider, IResolverSession resolverSession) { if (protocolHandler == null) { throw new ArgumentNullException(nameof(protocolHandler)); } if (resolverSession == null) { throw new ArgumentNullException(nameof(resolverSession)); } this.protocolHandler = protocolHandler; this.resolverSession = resolverSession; context = contextProvider.GetTypeContext(typeof(TActAs)); }
public void SendSecurity(IResolverSession session, SecurityInjectContext securityInjectContext) { sendSecurity?.Invoke(session, securityInjectContext); }
private async Task ConnectAsync() { TryDispose(); session = await Host.StartClientAsync(hostOrIp, port, CancellationToken.None); }
public async Task HostAndCreateChannel() { // Create host var host = new ProtocolHost(); // Load controllers from reference. host.LoadFromReference <ProtocolHostTests>(); // Register object to dependency injection. Just an example. This test doesn't require this. host.Resolver.Register(new CalculatorParameter() { First = 10 }); // Start server. Should be skiped on client side. var serverTask = host.StartServerAsync("127.0.0.1", 90, CancellationToken.None); IResolverSession clientSession = null; // Handle client connections. host.ClientConnected += (h, s) => { // Session of client connected to server. clientSession = s; }; // Can be used in Program.Main to run server. Task ends when server socket stops listening. // await serverTask; // Connect client. Should be skiped on server side. var session = await host.StartClientAsync("127.0.0.1", 90); // Create channel of IAddMethod interface on client side and call method from client to server. var serverSideCalculator = session.CreateChannel <IAddMethod>(); // Create Stopwatch for performance measure. var watch = Stopwatch.StartNew(); var tasks = new List <Task <CalculatorResult> >(); // Run asynchronous 10k requests. for (int i = 0; i < 10000; i++) { // From client call method on server side. var task = serverSideCalculator.AddAsync(10, 9); tasks.Add(task); } // Wait when all 10k requests ends. var serverResults = await Task.WhenAll(tasks); // Stop Stopwatch. watch.Stop(); // Check result. foreach (var serverResult in serverResults) { Assert.AreEqual(19, serverResult.Result); } // Check if elapsed time is less than one second. Assert.IsTrue(watch.ElapsedMilliseconds < 1000, $"Elapsed time is more than one second. Elapsed time in milliseconds: {watch.ElapsedMilliseconds}"); // Since we created both server and client from same ProtocolHost, they have same controllers that we can call. // Create channel of IAddMethod interface on server side and call method from server to client. var clientSideCalculator = clientSession.CreateChannel <IAddMethod>(); var clientResult = await clientSideCalculator.AddAsync(10, 10); Assert.AreEqual(20, clientResult.Result); // Close client connection. session.Dispose(); }
public SocketProtocolHandler(IResolverSession session, Stream stream, IProtocolConverter protocolConverter, IHandlerProvider handlerProvider) : this(session, new PacketStream(stream), protocolConverter, handlerProvider) { }
public static async Task <T> HandleAsync <T>(this IHandlerProvider handlerProvider, IResolverSession session, string scopeId, string actionId, params object[] requests) { //var actionBytes = Encoding.UTF8.GetBytes(actionId); return(await HandleAsync <T>(handlerProvider, session, scopeId, actionId, requests, CancellationToken.None)); }
public static bool TryCreateInstance(this IResolverSession session, Type type, out object obj) { return(TryCreateInstance(session, type.GetTypeInfo(), out obj)); }
public static object CreateInstance(this IResolverSession session, Type type) { return(CreateInstance(session, type.GetTypeInfo())); }
public static T CreateInstance <T>(this IResolverSession session) { return((T)CreateInstance(session, typeof(T))); }
public SocketProtocolHandler(IResolverSession session, IPacketStream packetStream, ISerializer serializer, IHandlerProvider handlerProvider) : this(session, packetStream, new ProtocolConverter(serializer), handlerProvider) { }
public IEnumerable <DataContext> SendData(IResolverSession session, DataInjectContext dataInjectContext) { return(sendData?.Invoke(session, dataInjectContext)); }
public void ReceiveData(IResolverSession session, DataInjectContext dataInjectContext) { receiveData?.Invoke(session, dataInjectContext); }
//public static async Task<T> HandleAsync<T>(this IHandlerProvider handlerProvider, IResolverSession session, // string scopeId, string actionId, object[] requests, CancellationToken cancellationToken) //{ // var actionBytes = new byte[4]; // actionBytes.AddBytes<int>(actionId, 4, 0); // return await HandleAsync<T>(handlerProvider, session, scopeId, actionBytes, requests, cancellationToken); //} public static async Task <T> HandleAsync <T>(this IHandlerProvider handlerProvider, IResolverSession session, string scopeId, string actionId, object[] requests, CancellationToken cancellationToken) { var parameterTypes = requests.Where(r => !(r is CancellationToken)).Select(r => r.GetType()).ToArray(); var returnType = typeof(T); var parameterHash = TypeHasher.GetMethodBytes(parameterTypes, returnType, t => t.Name); //var scopeBytes = Encoding.UTF8.GetBytes(scopeId); var actionHash = TypeHasher.CreateMD5Hash(Encoding.UTF8.GetBytes($"scope-{scopeId}:action-{actionId}"), parameterHash); var handler = handlerProvider.GetHandler(actionHash.ToByteArray()); return((T)await handler.HandleAsync(session, requests, cancellationToken)); }
public static async Task <T> HandleAsync <T>(this IHandlerProvider handlerProvider, IResolverSession session, string scopeId, int actionId, params object[] requests) { return(await HandleAsync <T>(handlerProvider, session, scopeId, actionId.ToString(), requests, CancellationToken.None)); }
public SocketProtocolHandler(IResolverSession session, Stream stream, ISerializer serializer, IHandlerProvider handlerProvider) : this(session, new PacketStream(stream), serializer, handlerProvider) { }
//public virtual async Task<object> HandleAsync(object[] requests, CancellationToken cancellationToken) //{ // return await HandleAsync(new Resolver(), requests, cancellationToken); //} public virtual async Task <object> HandleAsync(IResolverSession session, object[] requests, CancellationToken cancellationToken) { if (requests == null) { throw new ArgumentNullException(nameof(requests)); } if (classRoles.Length > 0 || methodRoles.Length > 0) { if (!session.TryResolve <IRole>(out var role)) { throw new UnauthorizedException(UnauthorizedReason.NoRoleProvider); } if (classRoles.Length > 0 && !classRoles.All(ar => ar.AnyOfRoles.Any(r => role.Contains(r)))) { throw new UnauthorizedException(UnauthorizedReason.ClassAccess); } if (methodRoles.Length > 0 && !methodRoles.All(ar => ar.AnyOfRoles.Any(r => role.Contains(r)))) { throw new UnauthorizedException(UnauthorizedReason.MethodAccess); } } var instance = session.Resolve(handlerType); var parameters = method.GetParameters(); var arguments = new object[parameters.Length]; var argumentIndex = 0; for (int i = 0; i < arguments.Length; i++) { if (session.TryResolve(parameters[i].ParameterType, out var arg)) { arguments[i] = arg; } else { if (parameters[i].ParameterType.GetTypeInfo().IsAssignableFrom(typeof(CancellationToken))) { arguments[i] = cancellationToken; } else if (parameters[i].ParameterType.GetTypeInfo().IsAssignableFrom(typeof(IResolverSession))) { arguments[i] = session; } else { if (requests.Length > argumentIndex) { var req = requests[argumentIndex]; var typeInfo = parameters[i].ParameterType.GetTypeInfo(); if (!typeInfo.IsClass || typeInfo.IsAssignableFrom(req.GetType())) { arguments[i] = req; argumentIndex++; continue; } } arguments[i] = null; } } } var result = method.Invoke(instance, arguments); if (result == null) { return(null); } if (result is Task) { var task = (Task)result; await task; if (resultProperty != null) { return(resultProperty.GetValue(result)); } return(null); } return(result); }
public SocketProtocolHandler(IResolverSession session, IPacketStream packetStream, IProtocolConverter protocolConverter, IHandlerProvider handlerProvider) : this(session, packetStream, protocolConverter, new MethodProtocolHandler(handlerProvider, session)) { }