Skip to content

Tcp.NET provides an easy-to-use and customizable Tcp Server and Tcp Client. The server is created using a TcpListener. The server and client can be used for non-SSL or SSL connections and authentication (including client and server ssl certification validation) is provided for identifying the clients connected to your server. Both client and ser…

License

LiveOrDevTrying/Tcp.NET

Repository files navigation

Tcp.NET provides a robust, performant, easy-to-use, and extendible Tcp server and Tcp client with included authorization / authentication to identify clients connected to your server. All Tcp.NET packages referenced in this documentation are available on the NuGet package manager as separate packages (Tcp.NET.Client or Tcp.NET.Server) or in 1 aggregate package (Tcp.NET). It has a sister-package called WebsocketsSimple which follows the same patterns but for Websocket Clients and Servers.

Image of Tcp.NET Logo

Table of Contents


Client

TcpNETClient

First install Tcp.NET.Client NuGet package using the NuGet package manager:

install-package Tcp.NET.Client

This will add the most-recent version of Tcp.NET.Client package to your specified project.

Create a variable of type ITcpNETClient with the included implementation TcpNETClient.

Signature:

  • TcpNETClient(ParamsTcpClient parameters) : ITcpNETClient

ParamsTcpClientByes can be used instead to specify EndOfLineCharacters, PingCharacters, and PongCharacters as byte arrays:

  • TcpNETClient(ParamsTcpClientBytes parameters) : ITcpNETClient

Example ParamsTcpClient:

    ITcpNETClient client = new TcpNETClient(new ParamsTcpClient("connect.tcp.net", 8989, "\r\n", isSSL: false);

Example ParamsTcpClientBytes:

    var eol = System.Encoding.UTF8.GetBytes("\r\n");
    ITcpNETClient client = new TcpNETClient(new ParamsTcpClientBytes("connect.tcp.net", 8989, eol, isSSL: false);

Parameters

  • ParamsTcpClient - Required - Contains the following connection detail data:
    • Host - int - Required - The host or URI of the Tcp server instance to connect (e.g. connect.tcp.net, localhost, 127.0.0.1, etc).
    • Port - int - Required - The port of the Tcp server instance to connect (e.g. 6660, 7210, 6483).
    • EndOfLineCharacters - string - Required - The Tcp protocol does not automatically include line termination symbols, but it has become common practice in many applications that the end-of-line symbol is \r\n which represents an Enter key for many operating systems. It is recommended you use \r\n as the line termination symbol.
    • Token - string - Optional - Optional parameter used by TcpNETServerAuth for authenticating a user. Defaults to null.
      • Generating and validating a token is outside the scope of this document, but for more information, check out OAuthServer.NET or IdentityServer4 for robust, easy-to-implemnt, and easy-to-use .NET identity servers.
      • A token can be any string. If wanting to use certificates, load the certs as a byte array, base64 encode them, and pass them as a string.
    • IsSSL - bool - Optional - Flag specifying if the connection should be made using SSL encryption when connecting to the server. Defaults to true.
    • OnlyEmitBytes - bool - Optional - Flag specifying if TcpNETClient should decode messages (Encoding.UTF8.GetString()) and return a string in MessageEvent or return only the raw byte array received. Defaults to false.
    • UsePingPong - bool - Optional - Flag specifying if the connection will listen for PingCharacters and return PongCharacters. If using TcpNETServer or TcpNETServerAuth, ping/pong is enabled by default. If UsePingPong is set to false, the connection will be servered after the server's next ping cycle. Defaults to true.
    • PingCharacters - string - Optional - String specifying what string TcpNETClient will be listening for from the server to verify the connection is still alive. When this string is received, PongCharacters will immediately be returned. An overload is included where PingCharacters and PongCharacters are byte arrays and called PingBytes and PongBytes. Defaults to "ping".
    • PongCharacters - string - Optional - String specifying what string TcpNETClient will send to the server immediately after PingCharacters is received. An overload is included where PingCharacters and PongCharacters are byte arrays and called PingBytes and PongBytes. Defaults to "pong".
    • UseDisconnectBytes - bool - Optional - When TcpNETClient gracefully disconnects from the server (DisconnectAsync()), this flag specifies if the DisconnectBytes should be first sent to the server to signal a disconnect event. Defaults to true.
    • DisconnectBytes - byte[] - Optional - If UseDisconnectBytes is true, this byte array allows a custom byte array to be sent to the server to signal a client invoked disconnect. This is the default behaviour for TcpNETServer and TcpNETServerAuth. If UseDisconnectBytes is true and DisconnectBytes is either null or an empty byte array, defaults to byte[] { 3 }.
  • ParamsTcpClientByes can be used instead to specify EndOfLineCharacters, PingCharacters, and PongCharacters as byte arrays:
    • EndOfLineBytes - byte[] - Required - Defaults to byte[] { 13, 10 }.
    • PingBytes - byte[] - Optional - Defaults to byte[] { 112, 105, 110, 103 }.
    • PongBytes - byte[] - Optional - Defaults to byte[] { 112, 111, 110, 103 }.

Token

An optional parameter called Token is included in the constructor for ParamsTcpClient to authorize your client with TcpNETServerAuth or a custom Tcp server. Upon a successful connection to the server, the Token you specify and the EndOfLineCharacters or **EndOfLineBytes**will immediately and automatically be sent to the server.

If you are creating a manual Tcp connection to an instance of TcpNETServerAuth, the first message you must send to the server is your Token followed by EndOfLineCharacters or EndOfLineBytes. This could look similar to the following:

Example:

    yourOAuthTokenGoesHere\r\n

Events

3 events are exposed on the ITcpNETClient interface: MessageEvent, ConnectionEvent, and **ErrorEvent*. These event signatures are below:

Signatures:

  • void MessageEvent(object sender, TcpMessageClientEventArgs args);
    • Invoked when a message is sent or received.
  • void ConnectionEvent(object sender, TcpConnectionClientEventArgs args);
    • Invoked when TcpNETClient connects or disconnects from a server.
  • void ErrorEvent(object sender, TcpErrorClientEventArgs args);
    • Wraps all logic in TcpNETClient with try catch statements and outputs the specific error(s).

Example:

    client.MessageEvent += OMessageEvent;
    client.ConnectionEvent += OnConnectionEvent;
    client.ErrorEvent += OnErrorEvent

SSL

SSL is enabled by default for TcpNETClient, but if you would like to disable SSL, set the IsSSL flag in ParamsTcpClient to true. In order to connect successfully to an SSL server, the server must have a valid, non-expired SSL certificate where the certificate's issued hostname matches the host specified in ParamsTcpClient.

Please note that a self-signed certificate or one from a non-trusted Certified Authority (CA) is not considered a valid SSL certificate.

Connect to a Tcp Server

To connect to a Tcp Server, invoke the ConnectAsync() method.

Signature:

  • Task<bool> ConnectAsync(CancellationToken cancellationToken = default)

Example:

    await client.ConnectAsync();

Send a Message to the Server

2 functions are exposed to send messages to the server:

Signatures:

  • Task<bool> SendAsync(string message, CancellationToken cancellationToken = default)
    • Send the specified string to the server.
  • Task<bool> SendAsync(byte[] message, CancellationToken cancellationTokenn = default)
    • Send the specified byte array to the server.

Example:

    await client.SendAsync("Hello World");

Ping

A TcpNETServer or TcpNETServerAuth will send a ping message to every client at a specified interval defined to verify which connections are still alive. If a client fails to detect the PingCharacters or PingBytes and/or respond with the PongCharacters or PongBytes, during the the next ping cycle, the connection will be severed and disposed. However, if you are using TcpNETClient, the ping / pong messages are digested and handled and will not be emit by MessageEvent. This means you do not need to worry about ping and pong messages if you are using TcpNETClient.

If you are creating your own Tcp connection, you should incorporate logic to listen for PingCharacters or PingBytes. If received, immediately respond with a message containing PongCharacters or PingBytes followed by the EndOfLineCharacters or EndOfLineBytes. This could look similar to the following:

Sent by Server:

    ping\r\n

Response by Client:

    pong\r\n

Note: Failure to implement this logic will result in a connection being severed in up to approximately 240 seconds.

Disconnect from the Server

To disconnect from the server, invoke the DisconnectAsync() method.

Signature:

  • Task<bool> DisconnectAsync(CancellationToken cancellationToken = default)
    • Disconnect from the connect Tcp Server

Example:

    await client.DisconnectAsync();

Disposal

At the end of usage, be sure to call the Dispose() method on TcpNETClient to free allocated memory and resources.

Signature:

  • void Dispose()
    • Close the connection and free allocated memory, resources, and event handlers.

Example:

    client.Dispose();

Server

First install the Tcp.NET.Server package using the NuGet package manager:

install-package Tcp.NET.Server

This will add the most-recent version of the Tcp.NET.Server package to your project.

There are 2 different types of Tcp Servers.


TcpNETServer

Create a variable of type ITcpNETServer with the included implementation TcpNETServer. The included implementation includes multiple constructors for SSL connections and non-SSL connections:

Signatures:

  • TcpNETServer(ParamsTcpServer parameters) : ITcpNETServer
  • TcpNETServer(ParamsTcpServer parameters, byte[] certificate, string certificatePassword) : ITcpNETServer

ParamsTcpServerBytes can be used instead to specify EndOfLineCharacters, PingCharacters, and PongCharacters as byte arrays

  • TcpNETServer(ParamsTcpServerBytes parameters) : ITcpNETServer
  • TcpNETServer(ParamsTcpServerBytes parameters, byte[] certificate, string certificatePassword) : ITcpNETServer

Example non-SSL server:

    ITcpNETServer server = new TcpNETServer(new ParamsTcpServer(8989, "\r\n", connectionSuccesString:"Connected Successfully"));

Example SSL server:

    byte[] certificate = File.ReadAllBytes("cert.pfx");
    string certificatePassword = "yourCertificatePassword";

    ITcpNETServer server = new TcpNETServer(new ParamsTcpServer(8989, "\r\n", connectionSuccessString: "Connected Successfully"), certificate, certificatePassword);

Example SSL server with ParamsTcpServerBytes:

    byte[]  eol = System.Encoding.UTF8.GetBytes("\r\n");

    byte[] certificate = File.ReadAllBytes("cert.pfx");
    string certificatePassword = "yourCertificatePassword";

    ITcpNETServer server = new TcpNETServer(new ParamsTcpServerBytes(8989, eol, connectionSuccessString: "Connected Successfully"), certificate, certificatePassword);

Parameters

  • ParamsTcpServer - Required - Contains the following connection detail data:
    • Port - int - Required - The port that the Tcp server will listen on (e.g. 6660, 7210, 6483).
    • EndOfLineCharacters - string - Required - Tcp does not automatically include line termination ends, however in many applications the end-of-line symbol is \r\n which represents an Enter key for many operating systems. We recommend you use \r\n as the line termination symbol.
    • ConnectionSuccessString - string - Optional - The string that will be sent to a newly successful connected client. Defaults to null.
    • OnlyEmitBytes - bool - Optional - Flag specifying if TcpNETServer should decode messages (Encoding.UTF8.GetString()) and return a string in MessageEvent or return only the raw byte array received. Defaults to false.
    • PingIntervalSec - int - Optional - Int representing how often the server will send all connected clients PingCharacters. Clients need to immediately response with PongCharacters or the connection will be severed at the next ping cycle. If you would like to disable the ping service on your Tcp server, set this value to 0. Defaults to true.
    • PingCharacters - string - Optional - String specifying what string TcpNETServer will send to each connected client to verify the connection is still alive. When a client receives this string, they will immediately need to respond with PongCharacters or the connection will be severed during the next ping cycle.. An overload is included where PingCharacters and PongCharacters are byte arrays and called PingBytes and PongBytes. Defaults to "ping".
    • PongCharacters - string - Optional - String specifying what string TcpNETServer will listen for following a ping cycle to specify that the connection is still alive. Clients need to immediately send PongCharacters to the server after receiving PingCharacters or the connection will be severed after the next ping cycle. An overload is included where PingCharacters and PongCharacters are byte arrays and called PingBytes and PongBytes. Defaults to "pong".
    • UseDisconnectBytes - bool - Optional - When TcpNETServer gracefully disconnects a connection (DisconnectConnectionAsync()), this flag specifies if the DisconnectBytes should be first sent to the client to signal a disconnect event. Defaults to true.
    • DisconnectBytes - byte[] - Optional - If UseDisconnectBytes is true, this byte array allows a custom byte array to be sent to the client to signal a server invoked disconnect. This is the default behaviour for TcpNETServer and TcpNETServerAuth. If UseDisconnectBytes is true and DisconnectBytes is either null or an empty byte array, defaults to byte[] { 3 }.
  • ParamsTcpServerBytes can be used instead to specify EndOfLineCharacters, PingCharacters, and PongCharacters as byte arrays:
    • EndOfLineBytes - byte[] - Required - Defaults to byte[] { 13, 10 }.
    • PingBytes - byte[] - Optional - Defaults to byte[] { 112, 105, 110, 103 }.
    • PongBytes - byte[] - Optional - Defaults to byte[] { 112, 111, 110, 103 }.
  • Certificate - byte[] - Optional - A byte array containing a SSL certificate with private key if the server will be hosted on Https.
  • CertificatePassword - string - Optional - The private key of the SSL certificate if the server will be hosted on Https.

Events

4 events are exposed on the ITcpNETServer interface: MessageEvent, ConnectionEvent, ErrorEvent, and ServerEvent. These event signatures are below:

Signatures:

  • void MessageEvent(object sender, TcpMessageServerEventArgs args);
    • Invoked when a message is sent or received.
  • void ConnectionEvent(object sender, TcpConnectionServerEventArgs args);
    • Invoked when a Tcp client is connecting, connects, or disconnects from the server.
  • void ErrorEvent(object sender, TcpErrorServerEventArgs args);
    • Wraps all internal logic with try catch statements and outputs the specific error(s).
  • void ServerEvent(object sender, ServerEventArgs args);
    • Invoked when the Tcp server starts or stops.

Examples:

    server.MessageEvent += OnMessageEvent;
    server.ConnectionEvent += OnConnectionEvent;
    server.ErrorEvent += OnErrorEvent;
    server.ServerEvent += OnServerEvent;

SSL

To enable SSL, use the provided SSL server constructor and specify your SSL certificate as a byte array and your certificate's private key as a string.

Signatures:

  • TcpNETServer(ParamsTcpServer parameters, byte[] certificate, string certificatePassword);
  • TcpNETServer(ParamsTcpServerBytes parameters, byte[] certificate, string certificatePassword);

The SSL Certificate MUST match the domain where the Tcp Server is hosted or clients will not able to connect to the Tcp Server.

Example:

    byte[] certificate = File.ReadAllBytes("cert.pfx");
    string certificatePassword = "yourCertificatePassword";

    ITcpNETServer server = new TcpNETServer(new ParamsTcpServer(8989, "\r\n", connectionSuccessString: "Connected Successfully"), certificate, certificatePassword);

In order to allow successful SSL connections, you must have a valid, non-expired SSL certificate. There are many sources for SSL certificates and some of them are open-source (Let's Encrypt).

Note: A self-signed certificate or one from a non-trusted CA is not considered a valid SSL certificate.

Start the Server

To start the server, call the StartAsync() method to instruct the server to begin listening for messages.

Signature:

  • Task StartAsync(CancellationToken cancellationToken = default);
    • Start the Tcp server and begin listening on the specified port

Example:

    await server.StartAsync();

Send a Message

3 functions are exposed to send messages to connections:

Signatures:

  • Task<bool> SendToConnectionAsync(string message, ConnectionTcpServer connection, CancellationToken cancellationToken = default);
    • Send the message string to the specified connection.
  • Task<bool> SendToConnectionAsync(byte[] message, ConnectionTcpServer connection, CancellationToken cancellationToken = default);
    • Send the byte array to the specified connection.
  • Task<bool> BroadcastToAllConnectionsAsync(string message, CancellationToken cancellationToken = default);
    • Send the message string to all connectionsn.
  • Task<bool> BroadcastToAllConnectionsAsync(byte[] message, CancellationToken cancellationToken = default);
    • Send the byte array to all connections.

ConnectionTcpServer represents a connected client to the server. These are exposed in ConnectionEvent, can be retrieved from Connections inside of TcpNETServer, or by extending TcpNETServer and using the this._connectionManager object.

An example to send a message to a specific connection could be:

    ConnectionTcpServer connection = server.Connections.FirstOrDefault(x => x.ConnectionId = "desiredConnectionId");

    if (connection != null) {
        await server.SendToConnectionAsync("YourDataPayload", connection);
    }

Ping

TcpNETServer will send a ping message to every client at a specified interval defined by PingIntervalSec (defaults to 120 sec, in ParamsTcpServer) to verify which connections are still alive. If a client fails to detect the PingCharacters or PingBytes and/or respond with the PongCharacters or PongBytes, during the the next ping cycle, the connection will be severed and disposed. However, if you are using TcpNETClient, the ping / pong messages are digested and handled and will not be emit by MessageEvent. This means you do not need to worry about ping and pong messages if you are using TcpNETClient.

If you would like to disable the ping / pong feature, set the PingIntervalSec defined in ParamsTcpServer to 0.

If you are creating your own Tcp connection and PingIntervalSec is greater than 0, you should incorporate logic to listen for PingCharacters or PingBytes. If received, immediately respond with a message containing PongCharacters or PingBytes followed by the EndOfLineCharacters or EndOfLineBytes. This could look similar to the following:

Sent by Server:

    ping\r\n

Response by Client:

    pong\r\n

Disconnect a Connection

To disconnect a connection from the server, invoke the function DisconnectConnectionAsync(ConnectionTcpServer connection).

Signature:

  • Task<bool> DisconnectionConnectionAsync(ConnectionTcpServer connection, CancellationToken cancellationToken = default)

Example:

    await DisconnectConnectionAsync(connection);

ConnectionTcpServer represents a connected client to the server. These are exposed in ConnectionEvent, can be retrieved from Connections inside of TcpNETServer, or by extending TcpNETServer and using the this._connectionManager object.

Stop the Server

To stop the server, call the StopAsync() method.

Signature:

  • Task StopAsync(CancellationToken cancellationToken = default);

Example:

    await server.StopAsync();

Disposal

After stopping the server, if you are not going to start the server again, call the Dispose() method to free all allocated memory and resources.

Signatures:

  • void Dispose();

Example:

    server.Dispose();

TcpNETServerAuth<T>

TcpNETServerAuth includes authentication for identifying your connections / users.

You will need to define your UserService, so make a new class that implements IUserService. This object includes a generic, T, which represents the datatype of your user unique Id. For example, T could be an int, a string, a long, or a guid - this depends on the datatype of the unique Id you have set for your user. This generic allows the ITcpNETServerAuth<T> implementation to allow authentication and identification of users for any user systems.

Signature:

    public interface IUserService<UId>
    {
        Task<bool> IsValidTokenAsync(string token, CancellationToken cancellationToken = default);
        Task<UId> GetIdAsync(string token, CancellationToken cancellationToken = default);
    }

Example:

    public class UserService : IUserService<long>
    {
        public Task<long> GetIdAsync(string token, CancellationToken cancellationToken = default)
        {
            return Task.FromResult(1);
        }

        public Task<bool> IsValidTokenAsync(string token, CancellationToken cancellationToken = default)
        {
            return token == "testToken" ? Task.FromResult(true) : Task.FromResult(false);
        }
    }

Implement the GetIdAsync() and IsValidTokenAsync() methods to validate the Token that was passed. Generating and validating a token is outside the scope of this document, but for more information, check out OAuthServer.NET or IdentityServer4 for robust, easy-to-implemnt, and easy-to-use .NET identity servers.

Next, create a variable of type ITcpNETServerAuth<T> with the included implementation TcpNETServerAuth<T> where T is the same type as you defined in IUserService. The included implementation includes multiple constructors for SSL connections and non-SSL connections:

Signatures:

  • TcpNETServerAuth<T>(ParamsTcpServerAuth parameters, IUserService<T> userService) : ITcpNETServerAuth<T>
  • TcpNETServerAuth<T>(IParamsTcpServerAuth parameters, IUserService<T> userService, byte[] certificate, string certificatePassword) : ITcpNETSreverAuth<T>

All connection objects will contain an UserId which represents the unique identifier for the authenticated user and are exposed from the included events.

ParamsTcpServerAuthBytes can be used instead to specify EndOfLineCharacters, PingCharacters, and PongCharacters as byte arrays:

  • TcpNETServerAuth<T>(ParamsTcpServerAuthBytes parameters) : ITcpNETServerAuth<T>
  • TcpNETServerAuth<T>(ParamsTcpServerAuthBytes parameters, byte[] certificate, string certificatePassword) : ITcpNETServerAuth<T>

Example non-SSL server:

    ITcpNETServerAuth<long> server = new TcpNETServerAuth<long>(new ParamsTcpServerAuth(8989, "\r\n", connectionSuccessString: "Connected Successfully", connectionUnauthorizedString: "Connection not authorized"), new UserService());

Example SSL server:

    byte[] certificate = File.ReadAllBytes("yourCert.pfx");
    string certificatePassword = "yourCertificatePassword";

    ITcpNETServerAuth<long> server = new ITcpNETServerAuth<long>(new ParamsTcpServerAuth(8989, "\r\n", connectionSuccessString: "Connected Successfully", connectionUnauthorizedString: "Connection not authorized"), new UserService(), certificate, certificatePassword);

Example SSL server with ParamsTcpServerAuthBytes:

    byte[]  eol = System.Encoding.UTF8.GetBytes("\r\n");

    byte[] certificate = File.ReadAllBytes("yourCert.pfx");
    string certificatePassword = "yourCertificatePassword";

    ITcpNETServerAuth<long> server = new ITcpNETServerAuth<long>(new ParamsTcpServerAuthBytes(8989, eol, connectionSuccessString: "Connected Successfully", connectionUnauthorizedString: "Connection not authorized"), new UserService(), certificate, certificatePassword);

Parameters

  • ParamsTcpServerAuth - Required - Contains the following connection detail data:
    • Port - int - Required - The port that the Tcp server will listen on (e.g. 6660, 7210, 6483).
    • EndOfLineCharacters - string - Required - Tcp does not automatically include line termination ends, however in many applications the end-of-line symbol is \r\n which represents an Enter key for many operating systems. We recommend you use \r\n as the line termination symbol.
    • ConnectionSuccessString - string - Optional - The string that will be sent to a newly successful connected client. Defaults to null.
    • ConnectionUnauthorizedString - string - Optional - The string that will be sent to a client if they fail authentication. Defaults to null.
    • OnlyEmitBytes - bool - Optional - Flag specifying if TcpNETServer should decode messages (Encoding.UTF8.GetString()) and return a string in MessageEvent or return only the raw byte array received. Defaults to false.
    • PingIntervalSec - int - Optional - Int representing how often the server will send all connected clients PingCharacters. Clients need to immediately response with PongCharacters or the connection will be severed at the next ping cycle. If you would like to disable the ping service on your Tcp server, set this value to 0. Defaults to true.
    • PingCharacters - string - Optional - String specifying what string TcpNETServer will send to each connected client to verify the connection is still alive. When a client receives this string, they will immediately need to respond with PongCharacters or the connection will be severed during the next ping cycle.. An overload is included where PingCharacters and PongCharacters are byte arrays and called PingBytes and PongBytes. Defaults to "ping".
    • PongCharacters - string - Optional - String specifying what string TcpNETServer will listen for following a ping cycle to specify that the connection is still alive. Clients need to immediately send PongCharacters to the server after receiving PingCharacters or the connection will be severed after the next ping cycle. An overload is included where PingCharacters and PongCharacters are byte arrays and called PingBytes and PongBytes. Defaults to "pong".
    • UseDisconnectBytes - bool - Optional - When TcpNETServerAuth gracefully disconnects a connection (DisconnectConnectionAsync()), this flag specifies if the DisconnectBytes should be first sent to the client to signal a disconnect event. Defaults to true.
    • DisconnectBytes - byte[] - Optional - If UseDisconnectBytes is true, this byte array allows a custom byte array to be sent to the client to signal a server invoked disconnect. This is the default behaviour for TcpNETServerAuth and TcpNETServerAuth. If UseDisconnectBytes is true and DisconnectBytes is either null or an empty byte array, defaults to byte[] { 3 }.
  • ParamsTcpServerAuthBytes can be used instead to specify EndOfLineCharacters, PingCharacters, and PongCharacters as byte arrays:
    • EndOfLineBytes - byte[] - Required - Defaults to byte[] { 13, 10 }.
    • PingBytes - byte[] - Optional - Defaults to byte[] { 112, 105, 110, 103 }.
    • PongBytes - byte[] - Optional - Defaults to byte[] { 112, 111, 110, 103 }.
  • IUserService<T> - Required - This interface for a User Service class will need to be implemented. This interface specifies 21 functions, GetIdAsync() and IsValidTokenAsync(string token), which will be invoked when the server receives an Token from a new connection. For more information regarding the User Service class, please see IUserService` below.
  • Certificate - byte[] - Optional - A byte array containing the exported SSL certificate with private key if the server will be hosted on Https.
  • CertificatePassword - string - Optional - The private key of the exported SSL certificate if the server will be hosted on Https.

IUserService<T>

This is an interface contained in PHS.Networking.Server. The constructor for TcpNETServerAuth<T> requires an IUserService<T>, and this interface will need to be implemented into a concrete class.

A default implementation is not included with Tcp.NET.Server. You will need to implement this interface and add logic here.

An example implementation using Entity Framework is shown below:

    public class UserServiceTcp : IUserService<long>
    {
        protected readonly ApplicationDbContext _ctx;

        public UserServiceTcp(ApplicationDbContext ctx)
        {
            _ctx = ctx;
        }

        public async Task<long> GetIdAsync(string token, CancellationToken cancellationToken = default)
        {
            // Obfuscate the token in the database
            token = Convert.ToBase64String(Encoding.UTF8.GetBytes(token));
            var user = await _ctx.Users.FirstOrDefaultAsync(s => s.OAuthToken == token);
            return user != null ? user.Id : (default);
        }

        public Task<bool> IsValidTokenAsync(string token, CancellationToken cancellationToken = default)
        {
            // Obfuscate the token in the database
            token = Convert.ToBase64String(Encoding.UTF8.GetBytes(token));
            return await _ctx.Users.Any(s => s.OAuthToken == token);
        }
    }

Because you are responsible for creating the logic in GetIdAsync(string token) and IsValidTokenAsync(string token), the data could reside in many stores including (but not limited to) in-memory, database, identity system, or auth systems.

All connection objects will contain an UserId which represents the unique identifier for the authenticated user and are exposed from the included events.

Events

4 events are exposed on the ITcpNETServerAuth<T> interface: MessageEvent, ConnectionEvent, ErrorEvent, and ServerEvent. These event signatures are below:

Signatures:

  • void MessageEvent(object sender, TcpMessageServerAuthEventArgs<T> args);
    • Invoked when a message is sent or received.
  • void ConnectionEvent(object sender, TcpConnectionServerAuthEventArgs<T> args);
    • Invoked when a Tcp client is connecting, connects, or disconnects from the server.
  • void ErrorEvent(object sender, TcpErrorServerAuthEventArgs<T> args);
    • Wraps all internal logic with try catch statements and outputs the specific error(s).
  • void ServerEvent(object sender, ServerEventArgs args);
    • Invoked when the Tcp server starts or stops.

Examples:

    server.MessageEvent += OMessageEvent;
    server.ConnectionEvent += OnConnectionEvent;
    server.ErrorEvent += OnErrorEvent;
    server.ServerEvent += OnServerEvent;

SSL

To enable SSL, use the provided SSL server constructor and specify your SSL certificate as a byte array and your certificate's private key as a string.

Signatures:

  • TcpNETServerAuth<T>(ParamsTcpServerAuth parameters, IUserManager<T> userManager, byte[] certificate, string certificatePassword);
  • TcpNETServerAuth<T>(ParamsTcpServerAuthBytes parameters, IUserManager<T> userManager, byte[] certificate, string certificatePassword);

The SSL Certificate MUST match the domain where the Tcp Server is hosted or clients will not able to connect to the Tcp Server.

Example:

    byte[] certificate = File.ReadAllBytes("cert.pfx");
    string certificatePassword = "yourCertificatePassword";

    ITcpNETServerAuth<long> server = new TcpNETServerAuth<long>(new ParamsTcpServerAuth(8989, "\r\n", connectionSuccessString: "Connected Successfully"), new UserManager(), certificate, certificatePassword);

In order to allow successful SSL connections, you must have a valid, non-expired SSL certificate. There are many sources for SSL certificates and some of them are open-source (Let's Encrypt).

Note: A self-signed certificate or one from a non-trusted CA is not considered a valid SSL certificate.

Start the Server

To start the server, call the StartAsync() method to instruct the server to begin listening for messages.

Signature:

  • Task StartAsync(CancellationToken cancellationToken = default);
    • Start the Tcp server and begin listening on the specified port

Example:

    await server.StartAsync();

Send a Message

To send messages to connections, 6 methods are exposed:

  • Task<bool> SendToConnectionAsync(string message, IdentityTcpServer<T> connection, CancellationToken cancellationToken = default);
    • Send the message string to the specified connection.
  • Task<bool> SendToConnectionAsync(byte[] message, IdentityTcpServer<T> connection, CancellationToken cancellationToken = default);
    • Send the byte array to the specified connection.
  • Task<bool> SendToUserAsync<T>(string message, T userId, CancellationToken cancellationToken = default)
    • Send the message string to the specified user and their connections currently logged into the server.
  • Task<bool> SendToUserAsync(byte[] message, T userId, CancellationToken cancellationToken = default)
    • Send the byte array string to the specified user and their connections currently logged into the server.
  • Task<bool> BroadcastToAllConnectionsAsync(string message, CancellationToken cancellationToken = default);
    • Send the message string to all connectionsn.
  • Task<bool> BroadcastToAllConnectionsAsync(byte[] message, CancellationToken cancellationToken = default);
    • Send the byte array to all connections.

IdentityTcpServer<T> represents a connected client to the server. These are exposed in ConnectionEvent, can be retrieved from Connections inside of TcpNETServerAuth, or by extending TcpNETServerAuth and using the this._connectionManager object.

An example to send a message to a specific connection could be:

    IdentityTcpServer<T> connection = server.Connections.FirstOrDefault(x => x.ConnectionId = "desiredConnectionId");

    if (connection != null) {
        await server.SendToConnectionAsync("YourDataPayload", connection);
    }

Ping

TcpNETServerAuth will send a ping message to every client at a specified interval defined by PingIntervalSec (defaults to 120 sec, in ParamsTcpServerAuth) to verify which connections are still alive. If a client fails to detect the PingCharacters or PingBytes and/or respond with the PongCharacters or PongBytes, during the the next ping cycle, the connection will be severed and disposed. However, if you are using TcpNETClient, the ping / pong messages are digested and handled and will not be emit by MessageEvent. This means you do not need to worry about ping and pong messages if you are using TcpNETClient.

If you would like to disable the ping / pong feature, set the PingIntervalSec defined in ParamsTcpServerAuth to 0.

If you are creating your own Tcp connection and PingIntervalSec is greater than 0, you should incorporate logic to listen for PingCharacters or PingBytes. If received, immediately respond with a message containing PongCharacters or PingBytes followed by the EndOfLineCharacters or EndOfLineBytes. This could look similar to the following:

Sent by Server:

    ping\r\n

Response by Client:

    pong\r\n

Disconnect a Connection

To disconnect a connection from the server, invoke the function DisconnectConnectionAsync(IdentityTcpServer<T> connection).

Signature:

  • Task<bool> DisconnectionConnectionAsync(IdentityTcpServer<T> connection, CancellationToken cancellationToken = default)

Example:

    await DisconnectConnectionAsync(connection);

IdentityTcpServer<T> represents a connected client to the server. These are exposed in ConnectionEvent, can be retrieved from Connections inside of TcpNETServerAuth, or by extending TcpNETServerAuth and using the this._connectionManager object.

Stop the Server

To stop the server, call the StopAsync() method.

Signature:

  • Task StopAsync(CancellationToken cancellationToken = default);

Example:

    await server.StopAsync();

Disposal

After stopping the server, if you are not going to start the server again, call the Dispose() method to free all allocated memory and resources.

Signatures:

  • void Dispose();

Example:

    server.Dispose();

Additional Information

Tcp.NET was created by Rob Engel - LiveOrDevTrying - and is maintained by Pixel Horror Studios. Tcp.NET is currently implemented in (but not limited to) the following projects: The Monitaur, Allie.Chat, and Gem Wars (currently in development). It is used in the following packages: WebsocketsSimple, NTier.NET, and The Monitaur.

Pixel Horror Studios Logo

About

Tcp.NET provides an easy-to-use and customizable Tcp Server and Tcp Client. The server is created using a TcpListener. The server and client can be used for non-SSL or SSL connections and authentication (including client and server ssl certification validation) is provided for identifying the clients connected to your server. Both client and ser…

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages