Post

PipesServer

A named pipe server that manages connections from multiple PipesClient instances.


Remarks

The PipesServer class wraps the NamedPipeServerStream class, and manages multiple connections from clients. Messages can be received from clients, or broadcast to individual or all clients. The server establishes client identities through a handshake, and names those clients for the duration of their connection.


Constructors

SyntaxDescription
PipesServer(string sID)Server constructor. sID is the identity of the server.

Events

IdentifierTypeDescription
ClientConnectedPipeConnectionEventIndicate when client has connected.
ClientDisconnectedPipeConnectionEventIndicate when client has disconnected.
ClientMessagePipeConnectionMessageEventIndicate reception of client message.
ErrorPipeExceptionEventHandlerIndicate error has occurred.

Methods

MethodReturnsDescription
IsRunning()boolIndicates if the server has been started and is currently running.
Send(PipeMessage message)voidSends a message to all clients connected to the server.
Send(PipeMessage message, string clientID)voidSends a message to a specific client from the list of connections.
Start()voidStarts the server.
Stop()voidStop the server, sending disconnect events to each client, and shutting down the current active listener.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using Nova.IPC.Pipes;
using System.IO;

public class PipeServer
{

  private PipesServer server;

  public PipeServer(string pipeName)
  {
    server = new PipesServer(pipeName);
    server.ClientConnected += OnClientConnected;
    server.ClientDisconnected += OnClientDisconnected;
    server.ClientMessage += OnClientMessage;
    server.Error += OnError;
    server.Start();
    while (KeepRunning)
    {
      // Do nothing - wait for user to press 'q' key
    }
    server.Stop();
  }

  // Receives console key input from user.
  private bool KeepRunning
  {
    get
    {
      var key = Console.ReadKey();
      if (key.Key == ConsoleKey.Q) return false;
      else if (key.Key == ConsoleKey.S)
      {
        //PipeMessage sent by this server have a MsgCode of '1'.
        //The client should know what that code means, and how to interpret the associate MsgData
        PipeMessage pm = new PipeMessage();
        pm.MsgCode='1';
        pm.MsgData=new SomeObject().Serialize();
        server.Send(pm);
      }
      return true;
    }
  }

  private void OnClientConnected(PipesConnection connection)
  {
    Console.WriteLine("Client Connected: "+connection.ID);
    PipeMessage pm = new PipeMessage();
    pm.EncodeString("Welcome!");
    connection.Send(pm);
  }

  private void OnClientDisconnected(PipesConnection connection)
  {
    Console.WriteLine("Client {0} disconnected", connection.ID);
  }

  private void OnClientMessage(PipesConnection connection, PipeMessage message)
  {
    //Note that the server will only process string messages from the client. All other messages
    //remain unprocessed (other than to notify the user that they were received).
    switch (message.MsgCode)
    {
      case '0':
        Console.WriteLine("Client {0} says: {1}", connection.ID,message.DecodeString());
        break;
      default:
        Console.WriteLine("Server received unrecognized message code from {0}: {1}", connection.ID, message.MsgCode);
        break;
    }
  }

  private void OnError(Exception exception)
  {
    Console.Error.WriteLine("ERROR: {0}", exception);
  }

  public static void Main()
  {
    Console.WriteLine("Running in SERVER mode");
    Console.WriteLine("Press 's' to send an object message to the client");
    Console.WriteLine("Press 'q' to exit");
    new PipeServer("TestServer");
  }

}

// Stands in for your own message payload type.
public class SomeObject
{
  public int intData = 1;
  public double doubleData = 2.5;
  public string strData = "three";

  public byte[] Serialize()
  {
    using (MemoryStream stream = new MemoryStream())
    using (BinaryWriter writer = new BinaryWriter(stream))
    {
      writer.Write(intData);
      writer.Write(doubleData);
      writer.Write(strData);
      return stream.ToArray();
    }
  }

  public void Deserialize(byte[] data)
  {
    using (BinaryReader reader = new BinaryReader(new MemoryStream(data)))
    {
      intData = reader.ReadInt32();
      doubleData = reader.ReadDouble();
      strData = reader.ReadString();
    }
  }
}
This post is licensed under CC BY 4.0 by the author.

Trending Tags