private async void StartInternal(CancellationToken cancellationToken) { byte[] buffer = new byte[256]; var commandBuilder = new StringBuilder(); var serverStream = new NamedPipeServerStream(this.PipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 0, 0); using (cancellationToken.Register(() => serverStream.Close())) { while (!cancellationToken.IsCancellationRequested) { await Task.Factory.FromAsync(serverStream.BeginWaitForConnection, serverStream.EndWaitForConnection, TaskCreationOptions.None); int read = await serverStream.ReadAsync(buffer, 0, buffer.Length); commandBuilder.Append(Encoding.ASCII.GetString(buffer, 0, read)); while (!serverStream.IsMessageComplete) { read = serverStream.Read(buffer, 0, buffer.Length); commandBuilder.Append(Encoding.ASCII.GetString(buffer, 0, read)); } var response = this.HandleReceivedCommand(commandBuilder.ToString()); var responseBytes = Encoding.ASCII.GetBytes(response); serverStream.Write(responseBytes, 0, responseBytes.Length); serverStream.WaitForPipeDrain(); serverStream.Disconnect(); commandBuilder.Clear(); } } }
public async void Process(NamedPipeServerStream pipeServerStream) { serverStream = pipeServerStream; while (serverStream.IsConnected) { var ipcMessage = new byte[1]; if (await serverStream.ReadAsync(ipcMessage, 0, 1) > 0) await ProcessPacket(ipcMessage[0], serverStream); } }
/// <summary> /// Starts the listener. /// </summary> /// <remarks> /// </remarks> private void StartListener() { if (_cancellationTokenSource.Token.IsCancellationRequested) { return; } try { if (IsRunning) { Logger.Message("Starting New Listener {0}", listenerCount++); var serverPipe = new NamedPipeServerStream(PipeName, PipeDirection.InOut, Instances, PipeTransmissionMode.Message, PipeOptions.Asynchronous, BufferSize, BufferSize, _pipeSecurity); var listenTask = Task.Factory.FromAsync(serverPipe.BeginWaitForConnection, serverPipe.EndWaitForConnection, serverPipe); listenTask.ContinueWith(t => { if (t.IsCanceled || _cancellationTokenSource.Token.IsCancellationRequested) { return; } StartListener(); // spawn next one! if (serverPipe.IsConnected) { var serverInput = new byte[BufferSize]; serverPipe.ReadAsync(serverInput, 0, serverInput.Length).AutoManage().ContinueWith(antecedent => { var rawMessage = Encoding.UTF8.GetString(serverInput, 0, antecedent.Result); if (string.IsNullOrEmpty(rawMessage)) { return; } var requestMessage = new UrlEncodedMessage(rawMessage); // first command must be "startsession" if (!requestMessage.Command.Equals("StartSession", StringComparison.CurrentCultureIgnoreCase)) { return; } // verify that user is allowed to connect. try { var hasAccess = false; serverPipe.RunAsClient(() => { hasAccess = PermissionPolicy.Connect.HasPermission; }); if (!hasAccess) { return; } } catch { return; } // check for the required parameters. // close the session if they are not here. if (string.IsNullOrEmpty(requestMessage["id"]) || string.IsNullOrEmpty(requestMessage["client"])) { return; } var isSync = requestMessage["async"].IsFalse(); if (isSync) { StartResponsePipeAndProcessMesages(requestMessage["client"], requestMessage["id"], serverPipe); } else { Session.Start(requestMessage["client"], requestMessage["id"], serverPipe, serverPipe); } }).Wait(); } }, _cancellationTokenSource.Token, TaskContinuationOptions.AttachedToParent, TaskScheduler.Current); } } catch /* (Exception e) */ { RequestStop(); } }
private async Task ConnectToBrokerWorker() { Trace.Assert(_brokerProcess == null); string rhostBrokerExe = Path.Combine(_rhostDirectory, RHostBrokerExe); if (!_services.FileSystem.FileExists(rhostBrokerExe)) { throw new RHostBrokerBinaryMissingException(); } Process process = null; try { string pipeName = Guid.NewGuid().ToString(); using (var serverUriPipe = new NamedPipeServerStream(pipeName, PipeDirection.In)) { var psi = new ProcessStartInfo { FileName = rhostBrokerExe, UseShellExecute = false, Arguments = $" --logging:logHostOutput {Log.LogVerbosity >= LogVerbosity.Normal}" + $" --logging:logPackets {Log.LogVerbosity == LogVerbosity.Traffic}" + $" --server.urls http://127.0.0.1:0" + // :0 means first available ephemeral port $" --startup:name \"{Name}\"" + $" --startup:writeServerUrlsToPipe {pipeName}" + $" --lifetime:parentProcessId {Process.GetCurrentProcess().Id}" + $" --security:secret \"{_credentials.Password}\"" + $" --R:autoDetect false" + $" --R:interpreters:{InterpreterId}:name \"{Name}\"" + $" --R:interpreters:{InterpreterId}:basePath \"{_rHome.TrimTrailingSlash()}\"" }; if (!ShowConsole) { psi.CreateNoWindow = true; } process = StartBroker(psi); process.EnableRaisingEvents = true; var cts = new CancellationTokenSource(100000); process.Exited += delegate { cts.Cancel(); _brokerProcess = null; _connectLock.EnqueueReset(); }; await serverUriPipe.WaitForConnectionAsync(cts.Token); var serverUriData = new MemoryStream(); try { // Pipes are special in that a zero-length read is not an indicator of end-of-stream. // Stream.CopyTo uses a zero-length read as indicator of end-of-stream, so it cannot // be used here. Instead, copy the data manually, using PipeStream.IsConnected to detect // when the other side has finished writing and closed the pipe. var buffer = new byte[0x1000]; do { int count = await serverUriPipe.ReadAsync(buffer, 0, buffer.Length, cts.Token); serverUriData.Write(buffer, 0, count); } while (serverUriPipe.IsConnected); } catch (OperationCanceledException) { throw new RHostDisconnectedException("Timed out while waiting for broker process to report its endpoint URI"); } string serverUriStr = Encoding.UTF8.GetString(serverUriData.ToArray()); Uri[] serverUri; try { serverUri = Json.DeserializeObject<Uri[]>(serverUriStr); } catch (JsonSerializationException ex) { throw new RHostDisconnectedException($"Invalid JSON for endpoint URIs received from broker ({ex.Message}): {serverUriStr}"); } if (serverUri?.Length != 1) { throw new RHostDisconnectedException($"Unexpected number of endpoint URIs received from broker: {serverUriStr}"); } CreateHttpClient(serverUri[0]); } if (DisposableBag.TryAdd(DisposeBrokerProcess)) { _brokerProcess = process; } } finally { if (_brokerProcess == null) { try { process?.Kill(); } catch (Exception) { } finally { process?.Dispose(); } } } }
public static async Task ClientCloneTests() { const string pipeName = "fooClientclone"; byte[] msg1 = new byte[] { 5, 7, 9, 10 }; byte[] received0 = new byte[] { }; byte[] received1 = new byte[] { 0, 0, 0, 0 }; using (NamedPipeServerStream server = new NamedPipeServerStream(pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte)) using (NamedPipeClientStream clientBase = new NamedPipeClientStream(".", pipeName, PipeDirection.Out, PipeOptions.None)) { await Task.WhenAll(server.WaitForConnectionAsync(), clientBase.ConnectAsync()); using (NamedPipeClientStream client = new NamedPipeClientStream(PipeDirection.Out, false, true, clientBase.SafePipeHandle)) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Assert.Equal(1, client.NumberOfServerInstances); } Assert.Equal(PipeTransmissionMode.Byte, client.TransmissionMode); Task clientTask = Task.Run(() => client.Write(msg1, 0, msg1.Length)); int len1 = server.Read(received1, 0, msg1.Length); await clientTask; Assert.Equal(msg1.Length, len1); Assert.Equal(msg1, received1); // test special cases of buffer lengths = 0 int len0 = server.Read(received0, 0, 0); Assert.Equal(0, len0); Assert.Equal(0, await server.ReadAsync(received0, 0, 0)); } } }
public static async Task ServerPInvokeChecks() { // calling every API related to server and client to detect any bad PInvokes using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.Out)) { Task clientTask = Task.Run(() => StartClient(PipeDirection.In)); server.WaitForConnection(); Assert.False(server.CanRead); Assert.False(server.CanSeek); Assert.False(server.CanTimeout); Assert.True(server.CanWrite); Assert.False(server.IsAsync); Assert.True(server.IsConnected); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Assert.Equal(0, server.OutBufferSize); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { Assert.True(server.OutBufferSize > 0); } else { Assert.Throws<PlatformNotSupportedException>(() => server.OutBufferSize); } Assert.Equal(PipeTransmissionMode.Byte, server.ReadMode); Assert.NotNull(server.SafePipeHandle); Assert.Equal(PipeTransmissionMode.Byte, server.TransmissionMode); server.Write(new byte[] { 123 }, 0, 1); await server.WriteAsync(new byte[] { 124 }, 0, 1); server.Flush(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { server.WaitForPipeDrain(); } else { Assert.Throws<PlatformNotSupportedException>(() => server.WaitForPipeDrain()); } await clientTask; } using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.In)) { Task clientTask = Task.Run(() => StartClient(PipeDirection.Out)); server.WaitForConnection(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Assert.Equal(0, server.InBufferSize); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { Assert.True(server.InBufferSize > 0); } else { Assert.Throws<PlatformNotSupportedException>(() => server.InBufferSize); } byte[] readData = new byte[] { 0, 1 }; Assert.Equal(1, server.Read(readData, 0, 1)); Assert.Equal(1, server.ReadAsync(readData, 1, 1).Result); Assert.Equal(123, readData[0]); Assert.Equal(124, readData[1]); } }
//public void readFromNamedPipeStream(NamedPipeServerStream stream) //{ // discardProcessedData(); // //read if there's something to read and if we have available storage // if (m_bytesInBuffer < m_maxChunkSize) // m_bytesInBuffer += stream.Read(m_buffer, m_bytesInBuffer, m_maxChunkSize - m_bytesInBuffer); //} public async Task< int> readFromNamedPipeStreamAsync(NamedPipeServerStream stream,CancellationToken cancelToken) { int numBytesRead= 0; discardProcessedData(); //read if there's something to read and if we have available storage if (m_bytesInBuffer < m_maxChunkSize) { try { numBytesRead = await stream.ReadAsync(m_buffer, m_bytesInBuffer, m_maxChunkSize - m_bytesInBuffer, cancelToken); } catch(OperationCanceledException) { logMessage("async read from pipe opeartion cancelled"); } m_bytesInBuffer += numBytesRead; } return numBytesRead; }
public static void ClientCloneTests() { const string pipeName = "fooClientclone"; byte[] msg1 = new byte[] { 5, 7, 9, 10 }; byte[] received0 = new byte[] { }; byte[] received1 = new byte[] { 0, 0, 0, 0 }; using (NamedPipeServerStream server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte)) { using (NamedPipeClientStream clientBase = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None)) { Task clientTask = Task.Run(() => { clientBase.Connect(); using (NamedPipeClientStream client = new NamedPipeClientStream(PipeDirection.InOut, false, true, clientBase.SafePipeHandle)) { client.Write(msg1, 0, msg1.Length); int serverCount = client.NumberOfServerInstances; Assert.Equal(1, serverCount); Assert.Equal(PipeTransmissionMode.Byte, client.TransmissionMode); } }); server.WaitForConnection(); int len1 = server.Read(received1, 0, msg1.Length); Assert.Equal(msg1.Length, len1); Assert.Equal(msg1, received1); // test special cases of buffer lengths = 0 int len0 = server.Read(received0, 0, 0); Assert.Equal(0, len0); server.Write(received0, 0, 0); Task<int> serverTaskRead = server.ReadAsync(received0, 0, 0); serverTaskRead.Wait(); Assert.Equal(0, serverTaskRead.Result); server.WriteAsync(received0, 0, 0).Wait(); } } }
public static void ServerPInvokeChecks() { // calling every API related to server and client to detect any bad PInvokes using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.Out)) { Task clientTask = StartClientAsync(PipeDirection.In); server.WaitForConnection(); Console.WriteLine("server.CanRead = {0}", server.CanRead); Console.WriteLine("server.CanSeek = {0}", server.CanSeek); Console.WriteLine("server.CanTimeout = {0}", server.CanTimeout); Console.WriteLine("server.CanWrite = {0}", server.CanWrite); Console.WriteLine("server.IsAsync = {0}", server.IsAsync); Console.WriteLine("server.IsConnected = {0}", server.IsConnected); Console.WriteLine("server.OutBufferSize = {0}", server.OutBufferSize); Console.WriteLine("server.ReadMode = {0}", server.ReadMode); Console.WriteLine("server.SafePipeHandle = {0}", server.SafePipeHandle); Console.WriteLine("server.TransmissionMode = {0}", server.TransmissionMode); server.Write(new byte[] { 123 }, 0, 1); server.WriteAsync(new byte[] { 124 }, 0, 1).Wait(); server.Flush(); server.WaitForPipeDrain(); clientTask.Wait(); } using (NamedPipeServerStream server = new NamedPipeServerStream("foo", PipeDirection.In)) { Task clientTask = StartClientAsync(PipeDirection.Out); server.WaitForConnection(); Console.WriteLine("server.InBufferSize = {0}", server.InBufferSize); byte[] readData = new byte[] { 0, 1 }; server.Read(readData, 0, 1); server.ReadAsync(readData, 1, 1).Wait(); Assert.Equal(123, readData[0]); Assert.Equal(124, readData[1]); } }