示例#1
0
        private static MessageProxy CreateRequestProxy(MessageAssembler operation)
        {
            Type requestType;

            int[] requestTypeInput;
            if (operation.OperationType == MethodType.Unary || operation.OperationType == MethodType.ServerStreaming)
            {
                requestType      = operation.RequestType;
                requestTypeInput = operation.RequestTypeInput;
            }
            else
            {
                requestType      = operation.HeaderRequestType ?? typeof(Message);
                requestTypeInput = operation.HeaderRequestTypeInput;
            }

            if (requestTypeInput.Length == 0)
            {
                return(new MessageProxy(Array.Empty <string>(), requestType));
            }

            var requestNames = new string[requestTypeInput.Length];

            for (var i = 0; i < requestNames.Length; i++)
            {
                var index = requestTypeInput[i];
                requestNames[i] = operation.Parameters[index].Name;
            }

            return(new MessageProxy(requestNames, requestType));
        }
示例#2
0
        private void BuildWriteServerStreamingResult(ILGenerator body, MessageAssembler message)
        {
            if (message.HeaderResponseType == null && !message.IsAsync)
            {
                // return ServerChannelAdapter.ServerStreaming(service.Simple());
                var channelAdapter = typeof(ServerChannelAdapter)
                                     .StaticMethod(nameof(ServerChannelAdapter.ServerStreaming))
                                     .MakeGenericMethod(message.ResponseType.GenericTypeArguments[0]);
                body.Emit(OpCodes.Call, channelAdapter);
            }
            else if (message.HeaderResponseType == null && message.IsAsync)
            {
                // return ServerChannelAdapter.ServerStreamingTask(service.SimpleTask());
                var channelAdapter = typeof(ServerChannelAdapter)
                                     .StaticMethod(message.Operation.ReturnType.IsValueTask() ? nameof(ServerChannelAdapter.ServerStreamingValueTask) : nameof(ServerChannelAdapter.ServerStreamingTask))
                                     .MakeGenericMethod(message.ResponseType.GenericTypeArguments[0]);
                body.Emit(OpCodes.Call, channelAdapter);
            }
            else
            {
                // return ServerChannelAdapter.ServerStreamingHeaderTask(service.HeaderTask(), AdaptHeaderTask);
                var adapterField = BuildServerStreamingResultAdapter(message);
                body.Emit(OpCodes.Ldarg_0);
                body.Emit(OpCodes.Ldfld, adapterField);

                var channelAdapter = typeof(ServerChannelAdapter)
                                     .StaticMethod(message.Operation.ReturnType.IsValueTask() ? nameof(ServerChannelAdapter.ServerStreamingHeaderValueTask) : nameof(ServerChannelAdapter.ServerStreamingHeaderTask))
                                     .MakeGenericMethod(message.Operation.ReturnType.GetGenericArguments()[0], message.HeaderResponseType, message.ResponseType.GenericTypeArguments[0]);
                body.Emit(OpCodes.Call, channelAdapter);
            }
        }
示例#3
0
        private FieldBuilder BuildServerStreamingResultAdapter(MessageAssembler message)
        {
            // private static (Message<string, int>, IAsyncEnumerable<int>) AdaptHeaderTask((string, IAsyncEnumerable<int>, int) result)
            var parameterType = message.Operation.ReturnType.GetGenericArguments()[0];
            var returnType    = typeof(ValueTuple <,>).MakeGenericType(
                message.HeaderResponseType,
                typeof(IAsyncEnumerable <>).MakeGenericType(message.ResponseType.GenericTypeArguments[0]));

            var method = _typeBuilder
                         .DefineMethod(
                GetUniqueMemberName("__Adapt" + message.Operation.Name + "Response"),
                MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static,
                returnType,
                new[] { parameterType });

            var body = method.GetILGenerator();

            // return (new Message<string, int>(result.Item1, result.Item3), result.Item2);
            var headerPropertiesCount = message.HeaderResponseTypeInput.Length;

            for (var i = 0; i < headerPropertiesCount; i++)
            {
                body.Emit(OpCodes.Ldarg_0);

                var index     = message.HeaderResponseTypeInput[i] + 1;
                var fieldName = "Item" + index.ToString(CultureInfo.InvariantCulture);

                body.Emit(OpCodes.Ldfld, parameterType.InstanceFiled(fieldName));
            }

            // new Message<string, int>()
            body.Emit(OpCodes.Newobj, message.HeaderResponseType !.Constructor(headerPropertiesCount));

            // push stream
            var streamFieldName = "Item" + (message.ResponseTypeIndex + 1).ToString(CultureInfo.InvariantCulture);

            body.Emit(OpCodes.Ldarg_0);
            body.Emit(OpCodes.Ldfld, parameterType.InstanceFiled(streamFieldName));

            body.Emit(OpCodes.Newobj, returnType !.Constructor(2));
            body.Emit(OpCodes.Ret);

            var delegateType = typeof(Func <,>).MakeGenericType(parameterType, returnType);

            // private readonly Func<(string, IAsyncEnumerable<int>, int), (Message<string, int>, IAsyncEnumerable<int>)> _adaptHeaderTask = AdaptHeaderTask;
            var field = _typeBuilder
                        .DefineField(
                GetUniqueMemberName("__" + message.Operation.Name + "ResponseAdapter"),
                delegateType,
                FieldAttributes.Private | FieldAttributes.InitOnly);

            // _adaptHeaderTask = AdaptHeaderTask
            _ctor.Emit(OpCodes.Ldarg_0);
            _ctor.Emit(OpCodes.Ldnull);
            _ctor.Emit(OpCodes.Ldftn, method);
            _ctor.Emit(OpCodes.Newobj, delegateType.Constructor(typeof(object), typeof(IntPtr)));
            _ctor.Emit(OpCodes.Stfld, field);

            return(field);
        }
示例#4
0
 public void TestMultipleMessages()
 {
     byte[] data = SerializeAll("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten");
     IList<Chunk> chunks = Chop(data, 100);
     MessageAssembler assembler = new MessageAssembler(Formatter);
     IList<object> result = new List<object>();
     foreach(Chunk chunk in chunks)
     {
         IList<object> messages = assembler.Assemble(chunk.Bytes, chunk.Size);
         foreach (object message in messages)
         {
             result.Add(message);
         }
     }
     Assert.NotNull(result);
     Assert.AreEqual(10, result.Count);
     Assert.AreEqual("one", result[0]);
     Assert.AreEqual("two", result[1]);
     Assert.AreEqual("three", result[2]);
     Assert.AreEqual("four", result[3]);
     Assert.AreEqual("five", result[4]);
     Assert.AreEqual("six", result[5]);
     Assert.AreEqual("seven", result[6]);
     Assert.AreEqual("eight", result[7]);
     Assert.AreEqual("nine", result[8]);
     Assert.AreEqual("ten", result[9]);
 }
示例#5
0
        private void BuildUnary(ILGenerator body, MessageAssembler decorator, OperationDescription operation)
        {
            // optionsBuilder
            InitializeCallOptionsBuilder(body, decorator);

            // var call = new UnaryCall<TRequest, TResponse>(method, CallInvoker, optionsBuilder)
            var callType = typeof(UnaryCall <,>)
                           .MakeGenericType(decorator.RequestType, decorator.ResponseType);

            InitializeCall(body, operation, callType);

            // call.Invoke(message)
            body.Emit(OpCodes.Ldloca_S, 1);                                       // call
            PushMessage(body, decorator.RequestType, decorator.RequestTypeInput); // message

            var invokeMethod = callType.InstanceGenericMethod(
                decorator.IsAsync ? "InvokeAsync" : "Invoke",
                decorator.ResponseType.IsGenericType ? 1 : 0);

            if (decorator.ResponseType.IsGenericType)
            {
                invokeMethod = invokeMethod.MakeGenericMethod(decorator.ResponseType.GenericTypeArguments);
            }

            body.Emit(OpCodes.Call, invokeMethod);

            // Task => new ValueTask
            if (decorator.Operation.ReturnType.IsValueTask())
            {
                body.Emit(OpCodes.Newobj, decorator.Operation.ReturnType.Constructor(invokeMethod.ReturnType));
            }

            body.Emit(OpCodes.Ret);
        }
示例#6
0
        private void BuildServerStreaming(ILGenerator body, MessageAssembler message, Type serviceType)
        {
            // service
            body.Emit(OpCodes.Ldarg_1);

            for (var i = 0; i < message.Parameters.Length; i++)
            {
                var parameter = message.Parameters[i];
                if (message.ContextInput.Contains(i))
                {
                    PushContext(body, 3, parameter.ParameterType);
                }
                else
                {
                    var propertyName = "Value" + (Array.IndexOf(message.RequestTypeInput, i) + 1);

                    // request.Value1
                    body.Emit(OpCodes.Ldarg_2);
                    body.Emit(OpCodes.Callvirt, message.RequestType.InstanceProperty(propertyName).GetMethod);
                }
            }

            // service.Method
            CallContractMethod(body, message, serviceType);

            BuildWriteServerStreamingResult(body, message);

            body.Emit(OpCodes.Ret);
        }
示例#7
0
        private void InitializeCallOptionsBuilder(ILGenerator body, MessageAssembler operation)
        {
            // var optionsBuilder = new CallOptionsBuilder(DefaultOptions)
            body.DeclareLocal(typeof(CallOptionsBuilder));
            body.Emit(OpCodes.Ldarg_0);                         // this
            body.Emit(OpCodes.Ldfld, _callOptionsFactoryField); // DefaultOptions
            body.Emit(OpCodes.Newobj, typeof(CallOptionsBuilder).Constructor(typeof(Func <CallOptions>)));
            body.Emit(OpCodes.Stloc_0);

            // optionsBuilder = optionsBuilder.With()
            foreach (var i in operation.ContextInput)
            {
                body.Emit(OpCodes.Ldloca_S, 0); // optionsBuilder
                body.EmitLdarg(i + 1);          // parameter

                var parameterType = operation.Parameters[i].ParameterType;

                Type?nullable = null;
                if (parameterType.IsValueType)
                {
                    nullable = Nullable.GetUnderlyingType(parameterType);
                    if (nullable == null)
                    {
                        // CancellationToken => CancellationToken?
                        body.Emit(OpCodes.Newobj, typeof(Nullable <>).MakeGenericType(parameterType).Constructor(parameterType));
                    }
                }

                var withMethodName = "With" + (nullable?.Name ?? parameterType.Name);
                body.Emit(OpCodes.Call, typeof(CallOptionsBuilder).InstanceMethod(withMethodName)); // .With
                body.Emit(OpCodes.Stloc_0);
            }
        }
示例#8
0
        private void PushHeaderProperty(ILGenerator body, MessageAssembler message, int parameterIndex)
        {
            var propertyName = "Value" + (Array.IndexOf(message.HeaderRequestTypeInput, parameterIndex) + 1);

            body.Emit(OpCodes.Ldarg_2);                                                                        // requestHeader
            body.Emit(OpCodes.Callvirt, message.HeaderRequestType !.InstanceProperty(propertyName).GetMethod); // requestHeader
        }
示例#9
0
        private void ImplementMethod(MessageAssembler decorator, OperationDescription operation)
        {
            var body = CreateMethodWithSignature(decorator.Operation);

            switch (decorator.OperationType)
            {
            case MethodType.Unary:
                BuildUnary(body, decorator, operation);
                break;

            case MethodType.ClientStreaming:
                BuildClientStreaming(body, operation);
                break;

            case MethodType.ServerStreaming:
                BuildServerStreaming(body, operation);
                break;

            case MethodType.DuplexStreaming:
                BuildDuplexStreaming(body, operation);
                break;

            default:
                throw new NotImplementedException("{0} operation is not implemented.".FormatWith(decorator.OperationType));
            }
        }
        private void BuildDuplexStreaming(ILGenerator body, MessageAssembler message, Type serviceType, FieldBuilder?inputHeadersMarshallerFiled, FieldBuilder?outputHeadersMarshaller)
        {
            DeclareHeaderValues(body, message, inputHeadersMarshallerFiled, 4);

            body.Emit(OpCodes.Ldarg_1); // service

            for (var i = 0; i < message.Parameters.Length; i++)
            {
                var parameter = message.Parameters[i];
                if (message.ContextInput.Contains(i))
                {
                    PushContext(body, 4, parameter.ParameterType);
                }
                else if (message.HeaderRequestTypeInput.Contains(i))
                {
                    PushHeaderProperty(body, message, i);
                }
                else
                {
                    // ReadClientStream()
                    body.Emit(OpCodes.Ldarg_2); // input
                    body.EmitLdarg(4);          // context
                    body.Emit(OpCodes.Call, typeof(ServerChannelAdapter).StaticMethod(nameof(ServerChannelAdapter.ReadClientStream)).MakeGenericMethod(message.RequestType.GenericTypeArguments));
                }
            }

            // service.Method
            CallContractMethod(body, message, serviceType);

            BuildWriteServerStreamingResult(body, message, outputHeadersMarshaller);

            body.Emit(OpCodes.Ret);
        }
示例#11
0
 internal static IEnumerable <ParameterInfo> GetRequestParameters(MessageAssembler message)
 {
     for (var i = 0; i < message.RequestTypeInput.Length; i++)
     {
         yield return(message.Parameters[message.RequestTypeInput[i]]);
     }
 }
示例#12
0
        private void BuildDuplexStreaming(ILGenerator body, MessageAssembler message, Type serviceType)
        {
            body.Emit(OpCodes.Ldarg_1); // service

            for (var i = 0; i < message.Parameters.Length; i++)
            {
                var parameter = message.Parameters[i];
                if (message.ContextInput.Contains(i))
                {
                    PushContext(body, 4, parameter.ParameterType);
                }
                else if (message.HeaderRequestTypeInput.Contains(i))
                {
                    PushHeaderProperty(body, message, i);
                }
                else
                {
                    body.Emit(OpCodes.Ldarg_3); // request
                }
            }

            // service.Method
            CallContractMethod(body, message, serviceType);

            BuildWriteServerStreamingResult(body, message);

            body.Emit(OpCodes.Ret);
        }
示例#13
0
        public void GetMessageTestOK()
        {
            //parameters
            List <List <string> > allMessagesOk  = new List <List <string> >();
            List <List <string> > allMessagesBad = new List <List <string> >();

            allMessagesOk.Add(new List <string>(new string[] { "este", "", "", "mensaje", "" }));
            allMessagesOk.Add(new List <string>(new string[] { "", "es", "", "", "secreto" }));
            allMessagesOk.Add(new List <string>(new string[] { "este", "", "un", "", "" }));
            allMessagesBad.Add(new List <string>(new string[] { "este", "", "", "mensaje", "" }));
            allMessagesBad.Add(new List <string>(new string[] { "", "es", "", "", "secreto" }));
            allMessagesBad.Add(new List <string>(new string[] { "este", "", "un", "" }));
            string           messageExpected  = "este es un mensaje secreto";
            MessageAssembler messageAssembler = new MessageAssembler();

            // Act
            string messageOk = messageAssembler.GetMessage(allMessagesOk);

            // Assert
            Assert.AreEqual(messageExpected, messageOk);
            Assert.Pass();

            // Act
            string messageBad = messageAssembler.GetMessage(allMessagesBad);

            // Assert
            Assert.AreEqual(messageExpected, messageOk);
            Assert.Pass();
        }
示例#14
0
        private static StreamProxy?CreateResponseStreamProxy(MessageAssembler operation)
        {
            if (operation.OperationType != MethodType.ServerStreaming && operation.OperationType != MethodType.DuplexStreaming)
            {
                return(null);
            }

            return(new StreamProxy(operation.ResponseType.GenericTypeArguments[0]));
        }
示例#15
0
        public ProxyFactory(MethodInfo contractMethodDefinition)
        {
            var operation = new MessageAssembler(contractMethodDefinition);

            RequestProxy        = CreateRequestProxy(operation);
            ResponseProxy       = CreateResponseProxy(operation);
            RequestStreamProxy  = CreateRequestStreamProxy(operation);
            ResponseStreamProxy = CreateResponseStreamProxy(operation);
        }
示例#16
0
        public static bool renameFile(string sourceFilePath, string destFilePath, string lastWriteTime)
        {
            connectServer();
            byte[] message = MessageAssembler.renameFile(sourceFilePath, destFilePath, lastWriteTime);
            VerifyHandler.postMessage(clientSocket, message);

            if (!VerifyHandler.verify(clientSocket))
            {
                return(false);
            }
            return(true);
        }
        private ILGenerator CreateMethodWithSignature(MessageAssembler message, Type serviceType, string methodName)
        {
            switch (message.OperationType)
            {
            case MethodType.Unary:
                // Task<TResponse> Invoke(TService service, TRequest request, ServerCallContext context)
                return(_typeBuilder
                       .DefineMethod(
                           methodName,
                           MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
                           typeof(Task <>).MakeGenericType(message.ResponseType),
                           new[] { serviceType, message.RequestType, typeof(ServerCallContext) })
                       .GetILGenerator());

            case MethodType.ClientStreaming:
                // Task<TResponse> Invoke(TService service, IAsyncStreamReader<TRequest> request, ServerCallContext context)
                return(_typeBuilder
                       .DefineMethod(
                           methodName,
                           MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
                           typeof(Task <>).MakeGenericType(message.ResponseType),
                           new[] { serviceType, typeof(IAsyncStreamReader <>).MakeGenericType(message.RequestType), typeof(ServerCallContext) })
                       .GetILGenerator());

            case MethodType.ServerStreaming:
                // Task Invoke(TService service, TRequest request, IServerStreamWriter<TResponse> stream, ServerCallContext context)
                return(_typeBuilder
                       .DefineMethod(
                           methodName,
                           MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
                           typeof(Task),
                           new[] { serviceType, message.RequestType, typeof(IServerStreamWriter <>).MakeGenericType(message.ResponseType), typeof(ServerCallContext) })
                       .GetILGenerator());

            case MethodType.DuplexStreaming:
                // Task Invoke(TService service, IAsyncStreamReader<TRequest> request, IServerStreamWriter<TResponse> response, ServerCallContext context)
                return(_typeBuilder
                       .DefineMethod(
                           methodName,
                           MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
                           typeof(Task),
                           new[]
                {
                    serviceType,
                    typeof(IAsyncStreamReader <>).MakeGenericType(message.RequestType),
                    typeof(IServerStreamWriter <>).MakeGenericType(message.ResponseType),
                    typeof(ServerCallContext)
                })
                       .GetILGenerator());
            }

            throw new NotImplementedException("{0} operation is not implemented.".FormatWith(message.OperationType));
        }
示例#18
0
        public static bool createFile(string path, string lastWriteTime)
        {
            connectServer();
            byte[] message = MessageAssembler.createFile(path, lastWriteTime);
            VerifyHandler.postMessage(clientSocket, message);

            if (!VerifyHandler.verify(clientSocket))
            {
                return(false);
            }
            return(true);
        }
示例#19
0
        public static bool regist(string account, string password)
        {
            connectServer();
            byte[] message = MessageAssembler.registMsgAssemble(account, password);
            VerifyHandler.postMessage(clientSocket, message);

            if (!VerifyHandler.verify(clientSocket))
            {
                return(false);
            }
            return(true);
        }
示例#20
0
        public static bool delete(string path)
        {
            connectServer();
            byte[] message = MessageAssembler.delete(path);
            VerifyHandler.postMessage(clientSocket, message);

            if (!VerifyHandler.verify(clientSocket))
            {
                return(false);
            }
            return(true);
        }
        public async Task <IAuthenticationResult> Login(string apiKey, IUserCredentials userCredentials)
        {
            var request  = MessageAssembler.ToMessage <IUserCredentials, UserCredentials>(userCredentials);
            var response = await WithAnonymousClient()
                           .ForApplication(apiKey)
                           .OnVersion(2)
                           .Post(request)
                           .To("session")
                           .ForHttpResponseMessageReader();

            return(await BuildAuthenticationResult(response));
        }
示例#22
0
        private static bool IsSupportedContextInput(MessageAssembler message)
        {
            for (var i = 0; i < message.ContextInput.Length; i++)
            {
                var input = message.ContextInput[i];
                if (!ServerChannelAdapter.TryGetServiceContextOptionMethod(message.Parameters[input].ParameterType))
                {
                    return(false);
                }
            }

            return(true);
        }
示例#23
0
        internal static (Type?Type, ParameterInfo Parameter) GetResponseType(MessageAssembler message)
        {
            // do not return typeof(void) => Swashbuckle schema generation error
            var arguments    = message.ResponseType.GetGenericArguments();
            var responseType = arguments.Length == 0 ? null : arguments[0];

            if (message.OperationType == MethodType.ServerStreaming || message.OperationType == MethodType.DuplexStreaming)
            {
                responseType = typeof(IAsyncEnumerable <>).MakeGenericType(responseType !);
            }

            return(responseType, message.Operation.ReturnParameter);
        }
示例#24
0
        private void CallContractMethod(ILGenerator body, MessageAssembler message, Type serviceType)
        {
            var parameters = new Type[message.Parameters.Length];

            for (var i = 0; i < parameters.Length; i++)
            {
                parameters[i] = message.Parameters[i].ParameterType;
            }

            var method = serviceType.InstanceMethod(message.Operation.Name, parameters);

            body.Emit(OpCodes.Callvirt, method);
        }
        private void DeclareHeaderValues(ILGenerator body, MessageAssembler message, FieldBuilder?headersMarshallerFiled, int contextParameterIndex)
        {
            if (headersMarshallerFiled != null)
            {
                body.DeclareLocal(message.HeaderRequestType !); // var headers

                body.Emit(OpCodes.Ldarg_0);
                body.Emit(OpCodes.Ldfld, headersMarshallerFiled); // static Marshaller<>
                body.EmitLdarg(contextParameterIndex);            // context
                body.Emit(OpCodes.Call, typeof(ServerChannelAdapter).StaticMethod(nameof(ServerChannelAdapter.GetMethodInputHeader)).MakeGenericMethod(message.HeaderRequestType));
                body.Emit(OpCodes.Stloc_0);
            }
        }
示例#26
0
        public static void syncNow()
        {
            connectServer();
            string paraHome = CommonStaticVariables.homePath.Substring(0, CommonStaticVariables.homePath.Length - 1);

            byte[] message = MessageAssembler.syncNow();

            VerifyHandler.postMessage(clientSocket, message);
            VerifyHandler.verify(clientSocket);

            findFileAndSync(paraHome, paraHome);
            // flag = 2 表示已同步完成
            VerifyHandler.postMessage(clientSocket, MessageAssembler.assembleDone());
        }
示例#27
0
        public static bool modifyFile(string sourceFilePath, string fullPath, string lastWriteTime)
        {
            connectServer();
            byte[] message = MessageAssembler.modifyFile(sourceFilePath, lastWriteTime);
            VerifyHandler.postMessage(clientSocket, message);

            VerifyHandler.verify(clientSocket);
            FileTransferHandler.postFile(clientSocket, fullPath);

            if (!VerifyHandler.verify(clientSocket))
            {
                return(false);
            }
            return(true);
        }
示例#28
0
        private void BuildUnary(ILGenerator body, MessageAssembler message, Type serviceType)
        {
            // service
            body.Emit(OpCodes.Ldarg_1);

            for (var i = 0; i < message.Parameters.Length; i++)
            {
                var parameter = message.Parameters[i];
                if (message.ContextInput.Contains(i))
                {
                    PushContext(body, 3, parameter.ParameterType);
                }
                else
                {
                    var propertyName = "Value" + (Array.IndexOf(message.RequestTypeInput, i) + 1);

                    // request.Value1
                    body.Emit(OpCodes.Ldarg_2);
                    body.Emit(OpCodes.Callvirt, message.RequestType.InstanceProperty(propertyName).GetMethod);
                }
            }

            // service.Method
            CallContractMethod(body, message, serviceType);

            if (message.IsAsync)
            {
                AdaptSyncUnaryCallResult(body, message);
            }
            else
            {
                if (message.ResponseType.IsGenericType)
                {
                    // new Message<T>
                    body.Emit(OpCodes.Newobj, message.ResponseType.Constructor(message.ResponseType.GenericTypeArguments));
                }
                else
                {
                    // new Message
                    body.Emit(OpCodes.Newobj, message.ResponseType.Constructor());
                }

                // Task.FromResult
                body.Emit(OpCodes.Call, typeof(Task).StaticMethod(nameof(Task.FromResult)).MakeGenericMethod(message.ResponseType));
            }

            body.Emit(OpCodes.Ret);
        }
示例#29
0
        public void GetResponseType(MethodInfo method)
        {
            var expected = method.GetCustomAttribute <ResponseMetadataAttribute>();
            var message  = new MessageAssembler(method);

            var responseType    = ApiDescriptionGenerator.GetResponseType(message);
            var responseHeaders = ApiDescriptionGenerator.GetResponseHeaderParameters(message);

            responseType.Type.ShouldBe(expected !.Type);
            responseType.Parameter.ShouldBe(method.ReturnParameter);

            responseHeaders.Length.ShouldBe(expected.HeaderTypes.Length);
            for (var i = 0; i < expected.HeaderTypes.Length; i++)
            {
                responseHeaders[i].Type.ShouldBe(expected.HeaderTypes[i]);
                responseHeaders[i].Name.ShouldBe(expected.HeaderNames[i]);
            }
        }
示例#30
0
        private static MessageProxy CreateResponseProxy(MessageAssembler operation)
        {
            Type responseType;

            string[] names;
            if (operation.OperationType == MethodType.Unary || operation.OperationType == MethodType.ClientStreaming)
            {
                responseType = operation.ResponseType;
                names        = operation.ResponseType == typeof(Message) ? Array.Empty <string>() : MessageProxy.UnaryResultNames;
            }
            else
            {
                responseType = operation.HeaderResponseType ?? typeof(Message);
                names        = operation.GetResponseHeaderNames();
            }

            return(new MessageProxy(names, responseType));
        }
示例#31
0
        public static bool logout(string account, string password)
        {
            if (!clientSocket.Connected)
            {
                return(true);
            }

            byte[] message = MessageAssembler.logoutMsgAssemble(account, password);
            VerifyHandler.postMessage(clientSocket, message);

            if (!VerifyHandler.verify(clientSocket))
            {
                return(false);
            }
            clientSocket.Shutdown(SocketShutdown.Both);
            clientSocket.Close();
            return(true);
        }
        /// <summary>
        /// Attempts to assemble the chunk into a completed message.
        /// If this is the last chunk of a message, the completed message
        /// is returned, and any unsatisfied dependencies that are now
        /// satisfied by the completed message are recursively assembled.
        /// All such assembled message are also returned via the enumeration.
        /// </summary>
        /// <remarks>
        /// This method is called by <see cref="Add"/> and <see cref="FlushWaitingChunks"/>,
        /// after all chunk dependencies are satisfied.
        /// </remarks>
        /// <param name="chunk">The chunk to assemble.</param>
        /// <returns>
        /// The enumeration of decoded messages.
        /// The enumeration may be empty or may
        /// have arbitrarily many members if dependencies were
        /// (recursively) satisfied by this chunk.
        /// </returns>
        protected IEnumerable<object> Assemble(Chunk chunk)
        {
            // Process single-chunk messages immediately.
            if (chunk.NumberOfChunksInMessage <= 1) {
                // Don't create a MessageAssembler for singleton chunks.
                // Instead, just return the message immediately.
                using (MemoryStream ms = new MemoryStream(chunk.Data)) {
                    yield return this.m_Formatter.Deserialize(ms);

                    // The message has been completed, so flush any chunks which were waiting for it.
                    foreach (object dependent in this.FlushWaitingChunks(chunk.MessageSequence))
                        yield return dependent;
                    yield break;
                }
            }

            // For multi-chunk messages, we first attempt to find an existing MessageAssembler
            // instance for the message to which the chunk belongs (based on the range of chunk
            // sequence numbers the message spans).
            MessageAssembler assembler = this.NewestMessageAssember, previous = null;
            object message;
            for (; ; ) {
                bool done, remove, complete;

                // If there does not exist any assembler for which IsInRange(chunk) returned true,
                // create one to hold the chunk.
                if (assembler == null) {
                    Debug.WriteLine(string.Format("Creating a new MessageAssembler to manage multipart message (message #{0}, chunks #{1}-{2})",
                        chunk.MessageSequence,
                        chunk.ChunkSequenceInMessage + 1,
                        chunk.NumberOfChunksInMessage),
                        this.GetType().ToString());

                    assembler = new MessageAssembler(chunk.MessageSequence,
                        chunk.NumberOfChunksInMessage, this.m_Formatter);

                    // Insert the assembler as the first entry in our linked list,
                    // since it is most likely to be used by subsequent chunks.
                    assembler.NextOldestAssembler = this.NewestMessageAssember;
                    this.NewestMessageAssember = assembler;
                }

                // See if the chunk belongs to the current assembler.
                if (assembler.MessageSequence == chunk.MessageSequence) {
                    // If so, add the chunk to it, and we can stop searching.
                    assembler.Add(chunk);
                    done = true;

                    // If the message has been fully assembled, process it
                    // and remove the no-longer-needed assembler.
                    complete = assembler.IsComplete;
                    if (complete) {
                        message = assembler.DeserializeMessage();
                        remove = true;
                    } else {
                        message = null;
                        remove = false;
                    }
                }

                else if (assembler.MessageSequence < chunk.OldestRecoverableMessage) {
                    // For each message assembler that is waiting for more chunks (and to which the current
                    // chunk does not belong), make sure it will be possible to complete the message in
                    // the future.  If the sender reports that its OldestRecoverableFrame is greater than
                    // the sequence number of any frame yet needed to complete the message, then no
                    // NACK we send can ever satisfy our needs, so we discard the message completely
                    // (removing the assembler from the linked list).
                    Debug.WriteLine(string.Format("### Giving up on message #{0} (chunks #{0}-{1}): the oldest available chunk is {2}!",
                        chunk.MessageSequence,
                        chunk.ChunkSequenceInMessage + 1,
                        chunk.NumberOfChunksInMessage,
                        chunk.OldestRecoverableMessage), this.GetType().ToString());
                    remove = true;
                    message = null;
                    done = false;
                    complete = false;
                }
                else {
                    remove = false;
                    message = null;
                    done = false;
                    complete = false;
                }

                // If the assembler is no longer useful, remove it from the linked list.
                // (There are a couple of conditions, above, under which this might happen.)
                if (remove) {
                    if (previous == null) {
                        this.NewestMessageAssember = assembler.NextOldestAssembler;
                    } else {
                        previous.NextOldestAssembler = assembler.NextOldestAssembler;
                    }
                }

                // If an assembler was found which accepted the chunk, we're done.
                // (There are a couple of conditions, above, under which this might happen.)
                if (done) {
                    if (complete) {
                        yield return message;

                        // The message has been completed, so flush any chunks which were waiting for it.
                        foreach (object dependent in this.FlushWaitingChunks(chunk.MessageSequence))
                            yield return dependent;
                    }
                    yield break;
                } else {
                    // Get the next assembler.  Do not break from the loop if there
                    // is no "next" assembler, since one will be created.
                    previous = assembler;
                    assembler = assembler.NextOldestAssembler;
                }
            }
        }