コード例 #1
0
        public FuncStreamHandler(string protocol, StreamHandlerFunc handle = null, AsyncStreamHandlerFunc asyncHandle = null)
        {
            _handle      = handle;
            _asyncHandle = asyncHandle;

            Protocol = protocol;
        }
コード例 #2
0
 public ProliferateServer(RequestHandler requestHandler,
                          int maxConcurrentConnections, string pipeNamePrefix, TaskScheduler handlerTaskScheduler = null)
 {
     _messageHandler           = requestHandler.StreamHandlerFunc;
     _maxConcurrentConnections = maxConcurrentConnections;
     _pipeNamePrefix           = pipeNamePrefix;
     _handlerTaskScheduler     = handlerTaskScheduler ?? TaskScheduler.Default;
 }
コード例 #3
0
        public static RequestHandler FromAction(Action <PipeReadWrapper, PipeWriteWrapper> handler)
        {
            StreamHandlerFunc taskReturningWrapper = (incomingRequestStream, outgoingResponseStream) =>
            {
                handler(incomingRequestStream, outgoingResponseStream);
                return(Task.FromResult(false)); //The value false isn't used for anything, just need a task.
            };

            return(new RequestHandler(taskReturningWrapper));
        }
コード例 #4
0
        public static RequestHandler FromTaskReturning(ReaderWriterHandlerFunc handler)
        {
            StreamHandlerFunc adapter = (incomingRequestStream, outgoingResponseStream) =>
            {
                var reader = new System.IO.StreamReader(incomingRequestStream);
                using (var writer = new System.IO.StreamWriter(outgoingResponseStream))
                {
                    return(handler(reader, writer));
                }
            };

            return(new RequestHandler(adapter));
        }
コード例 #5
0
        public static RequestHandler FromAction(Action <System.IO.StreamReader, System.IO.StreamWriter> handler)
        {
            StreamHandlerFunc taskReturningWrapper = (incomingRequestStream, outgoingResponseStream) =>
            {
                var reader = new System.IO.StreamReader(incomingRequestStream);
                using (var writer = new System.IO.StreamWriter(outgoingResponseStream))
                {
                    handler(reader, writer);
                }
                return(Task.FromResult(false)); //The value false isn't used for anything, just need a task.
            };

            return(new RequestHandler(taskReturningWrapper));
        }
コード例 #6
0
        public static RequestHandler FromAction <Trequest, Tresponse>(Func <Trequest, Tresponse> handler)
        {
            StreamHandlerFunc taskReturningWrapper = (incomingRequestStream, outgoingResponseStream) =>
            {
                var requestObj = (Trequest)_binaryFormatter.Deserialize(incomingRequestStream);
                //Need to call CheckRemainingByteChunkSize to trigger a read from the stream to make sure
                //we've read everything from the pipe. Otherwise we'll get a hang.
                incomingRequestStream.CheckRemainingByteChunkSize();
                incomingRequestStream.Close();
                var responseObj = (Tresponse)handler(requestObj);
                _binaryFormatter.Serialize(outgoingResponseStream, responseObj);
                return(Task.FromResult(false)); //The value false isn't used for anything, just need a task.
            };

            return(new RequestHandler(taskReturningWrapper));
        }
コード例 #7
0
        public static RequestHandler FromTaskReturning <Trequest, Tresponse>(
            Func <Trequest, Task <Tresponse> > handler)
        {
            StreamHandlerFunc adapter = async(incomingRequestStream, outgoingResponseStream) =>
            {
                var requestObj = (Trequest)_binaryFormatter.Deserialize(incomingRequestStream);
                //Need to call CheckRemainingByteChunkSize to trigger a read from the stream to make sure
                //we've read everything from the pipe. Otherwise we'll get a hang.
                incomingRequestStream.CheckRemainingByteChunkSize();
                incomingRequestStream.Close();
                var responseObj = await handler(requestObj);

                _binaryFormatter.Serialize(outgoingResponseStream, responseObj);
            };

            return(new RequestHandler(adapter));
        }
コード例 #8
0
 private static async Task <ConnectionHandlerResult> ConnectionHandler(TaskCompletionSource <bool> tcs,
                                                                       StreamHandlerFunc messageHandler, int maxConcurrentConnections, string pipeNamePrefix)
 {
     using (var incomingRequestPipe = new NamedPipeServerStream(
                pipeNamePrefix + "ParentToChild", PipeDirection.InOut, maxConcurrentConnections))
     {
         incomingRequestPipe.WaitForConnection();
         tcs.SetResult(true); //Use the TaskCompletionSource to signal back that the pipe received a connection.
         var readWrapper = new PipeReadWrapper(incomingRequestPipe);
         if (readWrapper.CheckRemainingByteChunkSize() == Constants.ShutdownId)
         {
             return(ConnectionHandlerResult.Shutdown);
         }
         using (var writeWrapper = new PipeWriteWrapper(incomingRequestPipe))
         {
             await messageHandler(readWrapper, writeWrapper);
         }
     }
     return(ConnectionHandlerResult.Normal);
 }
コード例 #9
0
        private static async Task ProduceConnectionHandlers(
            CancellationToken cancellationToken,
            int maxConcurrentConnections,
            string pipeNamePrefix,
            StreamHandlerFunc messageHandler,
            TaskScheduler handlerTaskScheduler)
        {
            //Make the connectionLostInterval slightly longer than the interval the server uses for sending pings.
            const int connectionLostInterval   = Constants.PingIntervalMilliseconds + 100;
            var       establishConnectionTasks = new List <Task>();
            var       handleRequestTasks       = new List <Task <ConnectionHandlerResult> >();
            Task      pingHandlerTask          = null;
            var       receivedPing             = true;
            var       delayTask = Task.Delay(connectionLostInterval);

            while (!cancellationToken.IsCancellationRequested)
            {
                //When there are no remaining establishConnectionTasks it means there are no free handlers waiting for
                //a connection from the parent process, so start a new handler unless we've reached
                //the maximum number of concurrent connections.
                while (establishConnectionTasks.Count == 0 && handleRequestTasks.Count < maxConcurrentConnections)
                {
                    var tcs = new TaskCompletionSource <bool>();
                    //This is the same as calling Task.Run except that we're specifying the TaskScheduler.
                    var handleRequestTask = Task.Factory.StartNew(
                        () => ConnectionHandler(tcs, messageHandler, maxConcurrentConnections, pipeNamePrefix),
                        CancellationToken.None,
                        TaskCreationOptions.DenyChildAttach,
                        handlerTaskScheduler
                        ).Unwrap();
                    handleRequestTasks.Add(handleRequestTask);
                    establishConnectionTasks.Add(tcs.Task);
                }
                var allTasks = establishConnectionTasks.Concat(handleRequestTasks).ToList();
                if (pingHandlerTask == null)
                {
                    pingHandlerTask = Task.Run(() => PingConnectionHandler(pipeNamePrefix));
                }
                allTasks.Add(pingHandlerTask);
                if (!allTasks.Contains(delayTask))
                {
                    allTasks.Add(delayTask);
                }
                var finishedTask = await Task.WhenAny(allTasks);

                if (finishedTask == delayTask)
                {
                    if (!receivedPing)
                    {
                        break;
                    }
                    allTasks.Remove(delayTask);
                    receivedPing = false;
                    delayTask    = Task.Delay(connectionLostInterval);
                }
                else if (RemoveFromListIfPresent(establishConnectionTasks, finishedTask))
                {
                }
                else if (finishedTask == pingHandlerTask)
                {
                    receivedPing    = true;
                    pingHandlerTask = null;
                }
                else if (finishedTask is Task <ConnectionHandlerResult> )
                {
                    var handlerTask = finishedTask as Task <ConnectionHandlerResult>;
                    if (handlerTask.Result == ConnectionHandlerResult.Shutdown)
                    {
                        break;
                    }
                    handleRequestTasks.Remove(handlerTask);
                }
                else
                {
                    throw new Exception("Unknown task.");
                }
            }
        }
コード例 #10
0
 public static RequestHandler FromTaskReturning(StreamHandlerFunc handler)
 {
     return(new RequestHandler(handler));
 }
コード例 #11
0
 internal RequestHandler(StreamHandlerFunc streamHandler)
 {
     this.StreamHandlerFunc = streamHandler;
 }
コード例 #12
0
        public MultistreamMuxer AddHandler(string protocol, StreamHandlerFunc handle = null, AsyncStreamHandlerFunc asyncHandle = null)
        {
            RemoveHandler(protocol);

            return(AddHandler(new FuncStreamHandler(protocol, handle, asyncHandle)));
        }