Exemple #1
0
        public void CheckReferenceResults()
        {
            //DJBHash32
            uint r1 = DJBHash32.ComputeHash(_testData);

            Assert.Equal(BitConverter.ToUInt32(_testResults[typeof(DJBHash32)], 0), r1);

            //Farmhash32
            uint r2 = FarmHash32.ComputeHash(_testData);

            Assert.Equal(BitConverter.ToUInt32(_testResults[typeof(FarmHash32)], 0), r2);

            //Farmhash64
            ulong r3 = FarmHash64.ComputeHash(_testData);

            Assert.Equal(BitConverter.ToUInt64(_testResults[typeof(FarmHash64)], 0), r3);

            //FNV1A32
            uint r4 = FNV1A32.ComputeHash(_testData);

            Assert.Equal(BitConverter.ToUInt32(_testResults[typeof(FNV1A32)], 0), r4);

            //MurmurHash32
            uint r5 = MurmurHash32.ComputeHash(_testData);

            Assert.Equal(BitConverter.ToUInt32(_testResults[typeof(MurmurHash32)], 0), r5);

            //MurmurHash128
            byte[] r6 = MurmurHash128.ComputeHash(_testData);
            Assert.True(_testResults[typeof(MurmurHash128)].SequenceEqual(r6));

            //SipHash64
            ulong r7 = SipHash64.ComputeHash(_testData);

            Assert.Equal(BitConverter.ToUInt64(_testResults[typeof(SipHash64)], 0), r7);

            //SuperFastHash32
            uint r8 = SuperFastHash32.ComputeHash(_testData);

            Assert.Equal(BitConverter.ToUInt32(_testResults[typeof(SuperFastHash32)], 0), r8);

            //xxHash32
            uint r9 = xxHash32.ComputeHash(_testData);

            Assert.Equal(BitConverter.ToUInt32(_testResults[typeof(xxHash32)], 0), r9);

            //xxHash64
            ulong r10 = xxHash64.ComputeHash(_testData);

            Assert.Equal(BitConverter.ToUInt64(_testResults[typeof(xxHash64)], 0), r10);
        }
        public StreamingHubHandler(Type classType, MethodInfo methodInfo, StreamingHubHandlerOptions handlerOptions, IServiceProvider serviceProvider)
        {
            var hubInterface    = classType.GetInterfaces().First(x => x.GetTypeInfo().IsGenericType&& x.GetGenericTypeDefinition() == typeof(IStreamingHub <,>)).GetGenericArguments()[0];
            var interfaceMethod = GetInterfaceMethod(classType, hubInterface, methodInfo.Name);

            this.serviceProvider = serviceProvider;

            this.HubType    = classType;
            this.HubName    = hubInterface.Name;
            this.MethodInfo = methodInfo;
            // Validation for Id
            if (methodInfo.GetCustomAttribute <MethodIdAttribute>() != null)
            {
                throw new InvalidOperationException($"Hub Implementation can not add [MethodId], you should add hub `interface`. {classType.Name}/{methodInfo.Name}");
            }
            this.MethodId = interfaceMethod.GetCustomAttribute <MethodIdAttribute>()?.MethodId ?? FNV1A32.GetHashCode(interfaceMethod.Name);

            this.UnwrappedResponseType = UnwrapResponseType(methodInfo);

            var resolver   = handlerOptions.SerializerOptions.Resolver;
            var parameters = methodInfo.GetParameters();

            this.RequestType = MagicOnionMarshallers.CreateRequestTypeAndSetResolver(classType.Name + "/" + methodInfo.Name, parameters, ref resolver);

            this.serializerOptions = handlerOptions.SerializerOptions.WithResolver(resolver);

            this.AttributeLookup = classType.GetCustomAttributes(true)
                                   .Concat(methodInfo.GetCustomAttributes(true))
                                   .Cast <Attribute>()
                                   .ToLookup(x => x.GetType());

            this.filters = handlerOptions.GlobalStreamingHubFilters
                           .OfType <IMagicOnionFilterFactory <StreamingHubFilterAttribute> >()
                           .Concat(classType.GetCustomAttributes <StreamingHubFilterAttribute>(true).Select(x => new StreamingHubFilterDescriptor(x, x.Order)))
                           .Concat(classType.GetCustomAttributes(true).OfType <IMagicOnionFilterFactory <StreamingHubFilterAttribute> >())
                           .Concat(methodInfo.GetCustomAttributes <StreamingHubFilterAttribute>(true).Select(x => new StreamingHubFilterDescriptor(x, x.Order)))
                           .Concat(methodInfo.GetCustomAttributes(true).OfType <IMagicOnionFilterFactory <StreamingHubFilterAttribute> >())
                           .OrderBy(x => x.Order)
                           .ToArray();

            // validation filter
            if (methodInfo.GetCustomAttribute <MagicOnionFilterAttribute>(true) != null)
            {
                throw new InvalidOperationException($"StreamingHub method can not add [MagicOnionFilter], you should add [StreamingHubFilter]. {classType.Name}/{methodInfo.Name}");
            }

            this.toStringCache    = HubName + "/" + MethodInfo.Name;
            this.getHashCodeCache = HubName.GetHashCode() ^ MethodInfo.Name.GetHashCode() << 2;

            // ValueTask (StreamingHubContext context) =>
            // {
            //    T request = LZ4MessagePackSerializer.Deserialize<T>(context.Request, context.FormatterResolver);
            //    Task<T> result = ((HubType)context.HubInstance).Foo(request);
            //    return WriteInAsyncLockInTaskWithMessageId(result) || return new ValueTask(result)
            // }
            try
            {
                var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

                var contextArg           = Expression.Parameter(typeof(StreamingHubContext), "context");
                var requestArg           = Expression.Parameter(RequestType, "request");
                var getSerializerOptions = Expression.Property(contextArg, typeof(StreamingHubContext).GetProperty("SerializerOptions", flags) !);
                var contextRequest       = Expression.Property(contextArg, typeof(StreamingHubContext).GetProperty("Request", flags) !);
                var noneCancellation     = Expression.Default(typeof(CancellationToken));
                var getInstanceCast      = Expression.Convert(Expression.Property(contextArg, typeof(StreamingHubContext).GetProperty("HubInstance", flags) !), HubType);

                var callDeserialize = Expression.Call(messagePackDeserialize.MakeGenericMethod(RequestType), contextRequest, getSerializerOptions, noneCancellation);
                var assignRequest   = Expression.Assign(requestArg, callDeserialize);

                Expression[] arguments = new Expression[parameters.Length];
                if (parameters.Length == 1)
                {
                    arguments[0] = requestArg;
                }
                else
                {
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        arguments[i] = Expression.Field(requestArg, "Item" + (i + 1));
                    }
                }

                var callBody = Expression.Call(getInstanceCast, methodInfo, arguments);

                var finalMethod = (methodInfo.ReturnType.IsGenericType)
                    ? typeof(StreamingHubContext).GetMethod(nameof(StreamingHubContext.WriteResponseMessage), flags) !.MakeGenericMethod(UnwrappedResponseType !)
                    : typeof(StreamingHubContext).GetMethod(nameof(StreamingHubContext.WriteResponseMessageNil), flags) !;
                callBody = Expression.Call(contextArg, finalMethod, callBody);

                var body         = Expression.Block(new[] { requestArg }, assignRequest, callBody);
                var compiledBody = Expression.Lambda(body, contextArg).Compile();

                this.MethodBody = BuildMethodBodyWithFilter((Func <StreamingHubContext, ValueTask>)compiledBody);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"Can't create handler. Path:{ToString()}", ex);
            }
        }
        internal static void VerifyMethodDefinitions(MethodDefinition[] definitions)
        {
            // define and set.
            var map = new Dictionary <int, MethodDefinition>(definitions.Length);

            foreach (var item in definitions)
            {
                var methodId = item.MethodInfo.GetCustomAttribute <MethodIdAttribute>()?.MethodId ?? FNV1A32.GetHashCode(item.MethodInfo.Name);
                if (map.ContainsKey(methodId))
                {
                    throw new Exception($"TReceiver does not allows duplicate methodId(hash code). Please change name or use MethodIdAttribute. {map[methodId].MethodInfo.Name} and {item.MethodInfo.Name}");
                }
                map.Add(methodId, item);

                if (!(item.MethodInfo.ReturnType == typeof(void)))
                {
                    throw new Exception($"Invalid definition, TReceiver's return type must only be `void`. {item.MethodInfo.Name}.");
                }

                item.MethodId = methodId;
            }
        }
Exemple #4
0
        static void VerifyMethodDefinitions(MethodDefinition[] definitions)
        {
            var map = new Dictionary <int, MethodDefinition>(definitions.Length);

            foreach (var item in definitions)
            {
                var methodId = item.MethodInfo.GetCustomAttribute <MethodIdAttribute>()?.MethodId ?? FNV1A32.GetHashCode(item.MethodInfo.Name);
                if (map.ContainsKey(methodId))
                {
                    throw new Exception($"TStreamingHub does not allows duplicate methodId(hash code). Please change name or use MethodIdAttribute. {map[methodId].MethodInfo.Name} and {item.MethodInfo.Name}");
                }
                map.Add(methodId, item);

                if (!(item.MethodInfo.ReturnType.IsGenericType && item.MethodInfo.ReturnType.GetGenericTypeDefinition() == typeof(Task <>)) &&
                    item.MethodInfo.ReturnType != typeof(Task))
                {
                    throw new Exception($"Invalid definition, TStreamingHub's return type must only be `Task` or `Task<T>`. {item.MethodInfo.Name}.");
                }

                item.MethodId = methodId;
                if (item.RequestType == null)
                {
                    item.RequestType = MagicOnionMarshallers.CreateRequestType(item.MethodInfo.GetParameters());
                }
            }
        }
 public uint FNV1A32Test()
 {
     return(FNV1A32.ComputeHash(_testData));
 }