public FuncStreamHandler(string protocol, StreamHandlerFunc handle = null, AsyncStreamHandlerFunc asyncHandle = null) { _handle = handle; _asyncHandle = asyncHandle; Protocol = protocol; }
public ProliferateServer(RequestHandler requestHandler, int maxConcurrentConnections, string pipeNamePrefix, TaskScheduler handlerTaskScheduler = null) { _messageHandler = requestHandler.StreamHandlerFunc; _maxConcurrentConnections = maxConcurrentConnections; _pipeNamePrefix = pipeNamePrefix; _handlerTaskScheduler = handlerTaskScheduler ?? TaskScheduler.Default; }
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)); }
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)); }
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)); }
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)); }
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)); }
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); }
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."); } } }
public static RequestHandler FromTaskReturning(StreamHandlerFunc handler) { return(new RequestHandler(handler)); }
internal RequestHandler(StreamHandlerFunc streamHandler) { this.StreamHandlerFunc = streamHandler; }
public MultistreamMuxer AddHandler(string protocol, StreamHandlerFunc handle = null, AsyncStreamHandlerFunc asyncHandle = null) { RemoveHandler(protocol); return(AddHandler(new FuncStreamHandler(protocol, handle, asyncHandle))); }