Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class PipeClient : IDisposable
- {
- private readonly string _pipeName;
- private NamedPipeClientStream _pipeStream;
- private StreamReader _streamReader;
- private byte[] _buffer;
- private object _pipeState = new object();
- public event MessageRecievedHandler OnMessageRecieved;
- /// <summary>
- /// Gets the underlying <c>PipeStream</c> object.
- /// </summary>
- public NamedPipeClientStream PipeStream { get { return _pipeStream; } }
- /// <summary>
- /// Gets a value indicating whether the <see cref="PipeStream"/> object is connected or not.
- /// </summary>
- public bool IsConnected { get { return _pipeStream.IsConnected; } }
- /// <summary>
- /// Main constructor.
- /// </summary>
- /// <param name="pipeName">The name of the channel being created.</param>
- public PipeClient(string pipeName)
- {
- if (String.IsNullOrEmpty(pipeName))
- {
- throw new IOException("Null or empty pipe name");
- }
- else
- {
- this._pipeName = pipeName;
- }
- }
- public bool ConnectAndWaitForMessage()
- {
- if (_pipeStream != null) return false;
- try
- {
- _pipeStream = new NamedPipeClientStream(".", this._pipeName, PipeDirection.In, PipeOptions.Asynchronous);
- _pipeStream.Connect();
- _buffer = new Byte[255];
- _pipeStream.BeginRead(_buffer, 0, _buffer.Length, PipeReadCallback, _pipeState);
- return true;
- }
- catch
- {
- //TODO
- return false;
- }
- }
- private void PipeReadCallback(IAsyncResult ar)
- {
- int bytesRead = 0;
- // if port serial is open and..
- if (_pipeStream.IsConnected)
- {
- // the stream can read then..
- if (_pipeStream.CanRead)
- {
- // wait for asynchronous read to be completed
- bytesRead = _pipeStream.EndRead(ar);
- //_pipeStream.Flush();
- }
- }
- if (bytesRead > 0)
- {
- if (OnMessageRecieved != null)
- OnMessageRecieved(this, new MessageRecievedEventArgs(_buffer));
- }
- }
- public void Dispose()
- {
- throw new NotImplementedException();
- }
- }
- public delegate void ClientConnectedEventHandler(object sender, PipeConnection connection);
- /// <summary>
- /// The class provides server-side tools for client-server interaction by named pipes.
- /// </summary>
- public class PipeServer
- {
- private readonly string _pipeName;
- private NamedPipeServerStream _pipeStream;
- private bool isListeningToClients = false;
- private List<PipeConnection> connectionsList;
- public event ClientConnectedEventHandler OnClientConnected;
- /// <summary>
- /// Returns the number of clients connected.
- /// </summary>
- public int ClientsCount
- {
- get
- {
- return connectionsList.Count;
- }
- }
- /// <summary>
- /// Creates a new instance of the class PipeServer.
- /// </summary>
- /// <param name="pipeName">Name of the created named pipe.</param>
- public PipeServer(string pipeName)
- {
- if (String.IsNullOrEmpty(pipeName))
- {
- throw new IOException("Null or empty pipe name");
- }
- else
- {
- this._pipeName = pipeName;
- this.isListeningToClients = true;
- this.connectionsList = new List<PipeConnection>();
- ListenForPipeClients();
- }
- }
- /// <summary>
- /// Sends a message to all connected clients. Updates the list of connected.
- /// </summary>
- /// <param name="message">Text message to send.</param>
- public void SendMessage(string message)
- {
- if (!this.isListeningToClients || connectionsList.Count == 0)
- return;
- List<PipeConnection> connListTmp = new List<PipeConnection>();
- byte[] _buffer = Encoding.UTF8.GetBytes(message);
- foreach (PipeConnection conn in connectionsList)
- {
- if (conn.IsConnected && conn.CanWrite)
- {
- try
- {
- connListTmp.Add(conn);
- conn.BaseStream.BeginWrite(_buffer, 0, _buffer.Length, new AsyncCallback(OnMessageAsyncSend), conn.BaseStream);
- }
- catch (Exception e)
- {
- Console.WriteLine("Error occures: {0}.", e.Message);
- }
- }
- else conn.Close();
- }
- connectionsList = connListTmp;
- }
- /// <summary>
- /// Create new NamedPipeServerStream for listening to pipe client connection
- /// </summary>
- private void ListenForPipeClients()
- {
- if (!this.isListeningToClients)
- return;
- try
- {
- if (_pipeStream == null)
- _pipeStream = new NamedPipeServerStream(_pipeName, PipeDirection.Out, 5, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
- IAsyncResult result = _pipeStream.BeginWaitForConnection(OnPipeConnected, _pipeStream);
- Console.WriteLine("Waiting for client connection...");
- }
- catch (ObjectDisposedException)
- {
- //// Catch ObjectDisposedException if server was stopped. Then do nothing.
- }
- catch (Exception e)
- {
- Console.WriteLine("Error occures: {0}. Restart pipe server...", e.Message);
- //ListenForPipeClients();
- }
- }
- /// <summary>
- /// Async callback on client connected action
- /// </summary>
- /// <param name="asyncResult">Async result</param>
- private void OnPipeConnected(IAsyncResult asyncResult)
- {
- using (var conn = (NamedPipeServerStream)asyncResult.AsyncState)
- {
- try
- {
- conn.EndWaitForConnection(asyncResult);
- Console.WriteLine("Client connected.");
- PipeConnection clientConnection = new PipeConnection(conn);
- connectionsList.Add(clientConnection);
- if (OnClientConnected != null)
- OnClientConnected(this, clientConnection);
- }
- catch (Exception e)
- {
- Console.WriteLine(e.Message);
- }
- }
- ListenForPipeClients();
- }
- private void OnMessageAsyncSend(IAsyncResult ar)
- {
- using (var conn = (NamedPipeServerStream)ar.AsyncState)
- {
- try
- {
- conn.EndRead(ar);
- conn.Flush();
- Console.WriteLine("Message sent successfully!");
- }
- catch (Exception e)
- {
- Console.WriteLine("Error occures: {0}.", e.Message);
- }
- }
- }
- public void StopListening()
- {
- if (!this.isListeningToClients)
- return;
- this.isListeningToClients = false;
- Console.WriteLine("Close all active connections...");
- if (connectionsList.Count > 0)
- {
- foreach (PipeConnection conn in connectionsList)
- {
- if (conn.IsConnected)
- conn.Close();
- }
- }
- }
- }
- public class PipeConnection
- {
- /// <summary>
- /// Gets the connection's unique identifier.
- /// </summary>
- public readonly int Id;
- /// <summary>
- /// Gets the connection's name.
- /// </summary>
- //public string Name { get; }
- /// <summary>
- /// Gets the underlying <c>PipeStream</c> object.
- /// </summary>
- public PipeStream BaseStream { get; private set; }
- /// <summary>
- /// Gets a value indicating whether the <see cref="BaseStream"/> object is connected or not.
- /// </summary>
- /// <returns>
- /// <c>true</c> if the <see cref="BaseStream"/> object is connected; otherwise, <c>false</c>.
- /// </returns>
- public bool IsConnected
- {
- get { return BaseStream.IsConnected; }
- }
- /// <summary>
- /// Gets a value indicating whether the current stream supports read operations.
- /// </summary>
- /// <returns>
- /// <c>true</c> if the stream supports read operations; otherwise, <c>false</c>.
- /// </returns>
- public bool CanRead
- {
- get { return BaseStream.CanRead; }
- }
- /// <summary>
- /// Gets a value indicating whether the current stream supports write operations.
- /// </summary>
- /// <returns>
- /// <c>true</c> if the stream supports write operations; otherwise, <c>false</c>.
- /// </returns>
- public bool CanWrite
- {
- get { return BaseStream.CanWrite; }
- }
- /// <summary>
- /// Constructs a new <c>PipeConnection</c> object that reads from and writes to the given <paramref name="stream"/>.
- /// </summary>
- /// <param name="stream">Stream to read from and write to</param>
- public PipeConnection(PipeStream stream)
- {
- BaseStream = stream;
- }
- /// <summary>
- /// Closes the current stream and releases any resources (such as sockets and file handles) associated with the current stream.
- /// </summary>
- public void Close()
- {
- BaseStream.Close();
- BaseStream.Dispose();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement