Esempio n. 1
0
 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);
 }
Esempio n. 3
0
 internal PipeConnection(int id, string name, PipeStream stream, IFormatter formatter)
 {
     Id   = id;
     Name = name;
     PipeStreamWrapper = new PipeStreamWrapper(stream);
     Formatter         = formatter;
 }
Esempio n. 4
0
        /// <summary>
        /// Dispose internal resources
        /// </summary>
        public void Dispose()
        {
            ReadWorker?.Dispose();
            ReadWorker = null;

            PipeStreamWrapper.Dispose();
        }
Esempio n. 5
0
        /// <summary>
        /// Dispose internal resources
        /// </summary>
        public async ValueTask DisposeAsync()
        {
            if (ReadWorker != null)
            {
                await ReadWorker.DisposeAsync().ConfigureAwait(false);

                ReadWorker = null;
            }

            await PipeStreamWrapper.DisposeAsync();
        }
Esempio n. 6
0
        /// <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);
        }
Esempio n. 7
0
        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);
            }
        }
Esempio n. 8
0
        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);
            }
        }
Esempio n. 9
0
        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);
            }
        }
Esempio n. 10
0
        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);
            }
        }
Esempio n. 11
0
        /// <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);
        }
Esempio n. 12
0
 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);
            }
        }
Esempio n. 14
0
 internal PipeConnection(int p_ID, string p_Name, PipeStream p_ServerStream)
 {
     ID              = p_ID;
     Name            = p_Name;
     m_StreamWrapper = new PipeStreamWrapper(p_ServerStream);
 }
Esempio n. 15
0
        /// <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;
            }
        }
Esempio n. 16
0
 internal NamedPipeConnection(int id, string name, PipeStream serverStream)
 {
     this.Id             = id;
     this.Name           = name;
     this._streamWrapper = new PipeStreamWrapper <TRead, TWrite>(serverStream);
 }