internal NamedPipeConnection(int id, string name, PipeStream serverStream) { Id = id; Name = name; Handle = serverStream.SafePipeHandle; _streamWrapper = new PipeStreamWrapper <TRead, TWrite>(serverStream); }
internal NamedPipeConnection(int id, string name, PipeStream serverStream, ICustomSerializer <TRead> serializerRead, ICustomSerializer <TWrite> serializerWrite) { Id = id; Name = name; Handle = serverStream.SafePipeHandle; _streamWrapper = new PipeStreamWrapper <TRead, TWrite>(serverStream, serializerRead, serializerWrite); }
internal PipeConnection(int id, string name, PipeStream stream, IFormatter formatter) { Id = id; Name = name; PipeStreamWrapper = new PipeStreamWrapper(stream); Formatter = formatter; }
/// <summary> /// Dispose internal resources /// </summary> public void Dispose() { ReadWorker?.Dispose(); ReadWorker = null; PipeStreamWrapper.Dispose(); }
/// <summary> /// Dispose internal resources /// </summary> public async ValueTask DisposeAsync() { if (ReadWorker != null) { await ReadWorker.DisposeAsync().ConfigureAwait(false); ReadWorker = null; } await PipeStreamWrapper.DisposeAsync(); }
/// <summary> /// Writes the specified <paramref name="value"/> and waits other end reading /// </summary> /// <param name="value"></param> /// <param name="cancellationToken"></param> public async Task WriteAsync(T value, CancellationToken cancellationToken = default) { if (!IsConnected || !PipeStreamWrapper.CanWrite) { throw new InvalidOperationException("Client is not connected"); } var bytes = await Formatter.SerializeAsync(value, cancellationToken).ConfigureAwait(false); await PipeStreamWrapper.WriteAsync(bytes, cancellationToken).ConfigureAwait(false); }
private void WaitForConnection(string pipeName, PipeSecurity pipeSecurity) { NamedPipeServerStream handshakePipe = null; NamedPipeServerStream dataPipe = null; NamedPipeConnection <TRead, TWrite> connection = null; var connectionPipeName = GetNextConnectionPipeName(pipeName); try { // Send the client the name of the data pipe to use handshakePipe = PipeServerFactory.CreateAndConnectPipe(pipeName, pipeSecurity); var handshakeWrapper = new PipeStreamWrapper <string, string>(handshakePipe); handshakeWrapper.WriteObject(connectionPipeName); handshakeWrapper.WaitForPipeDrain(); handshakeWrapper.Close(); // Wait for the client to connect to the data pipe dataPipe = PipeServerFactory.CreatePipe(connectionPipeName, pipeSecurity); dataPipe.WaitForConnection(); // Add the client's connection to the list of connections connection = ConnectionFactory.CreateConnection <TRead, TWrite>(dataPipe); connection.ReceiveMessage += ClientOnReceiveMessage; connection.Disconnected += ClientOnDisconnected; connection.Error += ConnectionOnError; connection.Open(); if (System.Threading.Monitor.TryEnter(_connections, 10000)) { try { _connections.Add(connection); } finally { System.Threading.Monitor.Exit(_connections); } } ClientOnConnected(connection); } // Catch the IOException that is raised if the pipe is broken or disconnected. catch (Exception e) { Console.Error.WriteLine("Named pipe is broken or disconnected: {0}", e); Cleanup(handshakePipe); Cleanup(dataPipe); ClientOnDisconnected(connection); } }
private void WaitForConnection(string pipeName) { NamedPipeServerStream handshakePipe = null; NamedPipeServerStream dataPipe = null; NamedPipeConnection <TRead, TWrite> connection = null; var connectionPipeName = GetNextConnectionPipeName(pipeName); try { // Send the client the name of the data pipe to use handshakePipe = PipeServerFactory.CreateAndConnectPipe(pipeName); var handshakeWrapper = new PipeStreamWrapper <string, string>(handshakePipe); handshakeWrapper.WriteObject(connectionPipeName); // Wait for the client to connect to the data pipe dataPipe = PipeServerFactory.CreatePipe(connectionPipeName); dataPipe.WaitForConnection(); // Client has now connected (Which means that they found our data pipe) // We can now close the handshake pipe handshakeWrapper.Close(); // Add the client's connection to the list of connections connection = ConnectionFactory.CreateConnection <TRead, TWrite>(dataPipe); connection.ReceiveMessage += ClientOnReceiveMessage; connection.Disconnected += ClientOnDisconnected; connection.Error += ConnectionOnError; connection.Open(); lock (_connections) { _connections.Add(connection); } ClientOnConnected(connection); } // Catch the IOException that is raised if the pipe is broken or disconnected. catch (Exception e) { Console.Error.WriteLine("Named pipe is broken or disconnected: {0}", e); Cleanup(handshakePipe); Cleanup(dataPipe); ClientOnDisconnected(connection); } }
private void WaitForConnection(string pipeName, PipeSecurity pipeSecurity) { NamedPipeServerStream handshakePipe = null; NamedPipeServerStream dataPipe = null; NamedPipeConnection <TRead, TWrite> connection = null; var connectionPipeName = GetNextConnectionPipeName(pipeName); Console.WriteLine(connectionPipeName); try { // Send the client the name of the data pipe to use将要使用的数据管道的名称发送给客户机 handshakePipe = PipeServerFactory.CreateAndConnectPipe(pipeName, pipeSecurity); var handshakeWrapper = new PipeStreamWrapper <string, string>(handshakePipe); handshakeWrapper.WriteObject(connectionPipeName); handshakeWrapper.WaitForPipeDrain(); handshakeWrapper.Close(); // Wait for the client to connect to the data pipe等待客户机连接到数据管道 dataPipe = PipeServerFactory.CreatePipe(connectionPipeName, pipeSecurity); dataPipe.WaitForConnection(); // Add the client's connection to the list of connections将客户端连接添加到连接列表中 connection = ConnectionFactory.CreateConnection <TRead, TWrite>(dataPipe); connection.ReceiveMessage += ClientOnReceiveMessage; connection.Disconnected += ClientOnDisconnected; connection.Error += ConnectionOnError; connection.Open(); lock (_connections) { _connections.Add(connection); } ClientOnConnected(connection); } // Catch the IOException that is raised if the pipe is broken or disconnected. catch (Exception e) { Console.Error.WriteLine("Named pipe is broken or disconnected: {0}", e); Cleanup(handshakePipe); Cleanup(dataPipe); ClientOnDisconnected(connection); } }
private void WaitForConnection(string p_PipeName) { NamedPipeServerStream s_HandshakePipe = null; NamedPipeServerStream s_DataPipe = null; PipeConnection s_Connection = null; var s_ConnectionPipeName = GetNextConnectionPipeName(p_PipeName); try { s_HandshakePipe = PipeServerFactory.CreateAndConnectPipe(p_PipeName); var s_HandshakeWrapper = new PipeStreamWrapper(s_HandshakePipe); s_HandshakeWrapper.WriteMessage(new PipeMessage() { Module = "SM", Type = "HS", Content = s_ConnectionPipeName }); s_HandshakeWrapper.WaitForPipeDrain(); s_HandshakeWrapper.Close(); s_DataPipe = PipeServerFactory.CreatePipe(s_ConnectionPipeName); s_DataPipe.WaitForConnection(); s_Connection = ConnectionFactory.CreateConnection(s_DataPipe); s_Connection.ReceiveMessage += ClientOnReceiveMessage; s_Connection.Disconnected += ClientOnDisconnected; s_Connection.Open(); lock (m_Connections) m_Connections.Add(s_Connection); ClientOnConnected(s_Connection); } catch (Exception) { Cleanup(s_HandshakePipe); Cleanup(s_DataPipe); ClientOnDisconnected(s_Connection); } }
/// <summary> /// Begins reading from and writing to the named pipe on a background thread. /// This method returns immediately. /// </summary> public void Start() { if (IsStarted) { throw new InvalidOperationException("Connection already started"); } ReadWorker = new TaskWorker(async cancellationToken => { while (!cancellationToken.IsCancellationRequested && IsConnected) { try { var bytes = await PipeStreamWrapper.ReadAsync(cancellationToken).ConfigureAwait(false); if (bytes == null && !IsConnected) { break; } var obj = await Formatter.DeserializeAsync <T>(bytes, cancellationToken).ConfigureAwait(false); OnMessageReceived(obj); } catch (OperationCanceledException) { OnDisconnected(); throw; } catch (Exception exception) { OnExceptionOccurred(exception); } } OnDisconnected(); }, OnExceptionOccurred); }
internal NamedPipeConnection(int id, string name, PipeStream serverStream, ISerializer <TRead> deserializer, ISerializer <TWrite> serializer) { Id = id; Name = name; _streamWrapper = new PipeStreamWrapper <TRead, TWrite>(serverStream, deserializer, serializer); }
private void WaitForConnection() { LogDebug("WaitForConnection"); NamedPipeServerStream handshakePipe = null; NamedPipeServerStream dataPipe = null; NamedPipeConnection <TRead, TWrite> connection = null; var connectionPipeName = GetNextConnectionPipeName(); try { dataPipe = CreatePipe(connectionPipeName); LogDebug("dataPipe created"); // Send the client the name of the data pipe to use LogDebug("Send the client the name of the data pipe to use"); handshakePipe = CreateAndConnectPipe(); LogDebug("handshakePipe created"); var handshakeWrapper = new PipeStreamWrapper <string, string>(handshakePipe); LogDebug("handshakeWrapper created"); handshakeWrapper.SetLogger(_logger); handshakeWrapper.WriteObject(connectionPipeName); handshakeWrapper.WaitForPipeDrain(); handshakeWrapper.Close(); LogDebug("handshakeWrapper closed"); // Wait for the client to connect to the data pipe LogDebug("Wait for the client to connect to the data pipe"); dataPipe.WaitForConnection(); LogDebug("Add the client's connection to the list of connections"); // Add the client's connection to the list of connections connection = ConnectionFactory.CreateConnection <TRead, TWrite>(dataPipe); connection.ReceiveMessage += ClientOnReceiveMessage; connection.Disconnected += ClientOnDisconnected; connection.Error += ConnectionOnError; connection.Open(); LogDebug("Open connection"); lock (_connections) { _connections.Add(connection); } ClientOnConnected(connection); } // Catch the IOException that is raised if the pipe is broken or disconnected. catch (Exception e) { LogError(e, "Named pipe is broken or disconnected"); Console.Error.WriteLine("Named pipe is broken or disconnected: {0}", e); LogDebug("Cleanup handshakePipe"); Cleanup(handshakePipe); LogDebug("Cleanup dataPipe"); Cleanup(dataPipe); ClientOnDisconnected(connection); } }
internal PipeConnection(int p_ID, string p_Name, PipeStream p_ServerStream) { ID = p_ID; Name = p_Name; m_StreamWrapper = new PipeStreamWrapper(p_ServerStream); }
/// <summary> /// Begins listening for client connections in a separate background thread. /// This method waits when pipe will be created(or throws exception). /// </summary> /// <exception cref="InvalidOperationException"></exception> /// <exception cref="IOException"></exception> public async Task StartAsync(CancellationToken cancellationToken = default) { if (IsStarted) { throw new InvalidOperationException("Server already started"); } await StopAsync(cancellationToken); var source = new TaskCompletionSource <bool>(); using var registration = cancellationToken.Register(() => source.TrySetCanceled(cancellationToken)); ListenWorker = new TaskWorker(async token => { while (!token.IsCancellationRequested) { try { var connectionPipeName = $"{PipeName}_{++NextPipeId}"; // Send the client the name of the data pipe to use try { #if NETSTANDARD2_0 using var serverStream = CreatePipeStreamFunc?.Invoke(PipeName) ?? PipeServerFactory.Create(PipeName); #else await using var serverStream = CreatePipeStreamFunc?.Invoke(PipeName) ?? PipeServerFactory.Create(PipeName); #endif PipeStreamInitializeAction?.Invoke(serverStream); source.TrySetResult(true); await serverStream.WaitForConnectionAsync(token).ConfigureAwait(false); await using var handshakeWrapper = new PipeStreamWrapper(serverStream); await handshakeWrapper.WriteAsync(Encoding.UTF8.GetBytes(connectionPipeName), token) .ConfigureAwait(false); } catch (Exception exception) { if (WaitFreePipe) { throw; } source.TrySetException(exception); break; } // Wait for the client to connect to the data pipe var connectionStream = CreatePipeStreamFunc?.Invoke(connectionPipeName) ?? PipeServerFactory.Create(connectionPipeName); PipeStreamInitializeAction?.Invoke(connectionStream); try { await connectionStream.WaitForConnectionAsync(token).ConfigureAwait(false); } catch { #if NETSTANDARD2_0 connectionStream.Dispose(); #else await connectionStream.DisposeAsync().ConfigureAwait(false); #endif throw; } // Add the client's connection to the list of connections var connection = ConnectionFactory.Create <T>(connectionStream, Formatter); connection.MessageReceived += (sender, args) => OnMessageReceived(args); connection.Disconnected += (sender, args) => OnClientDisconnected(args); connection.ExceptionOccurred += (sender, args) => OnExceptionOccurred(args.Exception); connection.Start(); Connections.Add(connection); OnClientConnected(new ConnectionEventArgs <T>(connection)); } catch (OperationCanceledException) { throw; } // Catch the IOException that is raised if the pipe is broken or disconnected. catch (IOException) { await Task.Delay(TimeSpan.FromMilliseconds(1), token).ConfigureAwait(false); } catch (Exception exception) { OnExceptionOccurred(exception); break; } } }, OnExceptionOccurred); try { await source.Task.ConfigureAwait(false); } catch (Exception) { await StopAsync(cancellationToken); throw; } }
internal NamedPipeConnection(int id, string name, PipeStream serverStream) { this.Id = id; this.Name = name; this._streamWrapper = new PipeStreamWrapper <TRead, TWrite>(serverStream); }