Getting Started

First of all, create a Console Application project.

Install package from nuget

Create a new Class and inherit from Server (my class name is MyServer)

Add following namespaces

using System.Net.Sockets;
using System.Threading.Tasks;
using TcpServerKit.Core;

Then declare the constructor

public MyServer(string ip, int port) : base(ip, port) { }

And implement two abstract tasks

public override async Task ClientExited(TcpClient client)
{
     Console.WriteLine("client exited");
}

public override async Task NewClientJoined(TcpClient client)
{
    Console.WriteLine("new client");
}

The result must be something like this

using System;
using System.Net.Sockets;
using System.Threading.Tasks;
using TcpServerKit.Core;

namespace TCPSERVERKIT_Sample
{
    class MyServer : Server
    {
        public MyServer(string ip, int port) : base(ip, port) { }

        public override async Task ClientExited(TcpClient client)
        {
            Console.WriteLine("Client exited.");
        }

        public override async Task NewClientJoined(TcpClient client)
        {
            Console.WriteLine("New client.");
        }
    }
}

Then create a new object from MyServer and set server IP and port.

var ip = "127.0.0.1";
var port = 3000;
var newServer = new MyServer(ip, port);

Now our server is ready to start, but before that let's add some listeners.

Create a new class and name it MyListener and inherit from ListenersManager

Create one Tasks and set the Listener attribute to it.

[Listener(name:"Login")]
public async Task LoginAsync(string data, TcpClient client)
{
}
💡
Tip: If we set the name of the attribute, the name of the event name witch server listens to changes. If not, the event name will be set with the task name. in there will be "LoginAsync"

In this example we add one listener with name Login. After the client sends a message with the same event name, the Login task will be run.

data is a string data which client sends to the server and client is a TCPClient object of who sends it.

The result must be something like this.

using System.Net.Sockets;
using System.Threading.Tasks;
using TcpServerKit.Attributes;
using TcpServerKit.Manager;

namespace TCPSERVERKIT_Sample
{
    public class MyListener : ListenersManager
    {
        [Listener(name:"Login")]
        public async Task LoginAsync(string data, TcpClient client)
				{
				}
    }
}

Then create a new object from MyListener.

var myListener = new MyListener();

Very well. After adding all of the listeners we can start the server.

newServer.Start();

using System;

namespace TCPSERVERKIT_Sample
{
    class Program
    {
        static void Main(string[] args)
        {
						var ip = "127.0.0.1";
						var port = 3000;
						var newServer = new MyServer(ip, port);

            var myListener = new MyListener();

            newServer.Start();
            Console.ReadKey();
        }
    }
}

There is it. All you need is to run your server.

And don’t forget to put a Console.ReadKey(); to prevent the console from closing.

Now we will work with users and rooms. For that, create a new class with name MyUser and inherit from User then implement constructors. For that we need to import the following namespaces

💡
to send data to an client we must first create new User from it.

using System;
using System.Net.Sockets;
using TcpServerKit.Core;
 
 
public class MyUser : User
{
  public MyUser()
  {
  }

  public MyUser(TcpClient tcpClient) : base(tcpClient)
  {
  }    
}

So, create another class for Room and name it MyRoom and inherit from Room. Implement constructor and functions.

using System.Net.Sockets;
using TcpServerKit.Core;
using TcpServerKit.Core.Tcp;
using TcpServerKit.Manager;
 
 
    public class MyRoom : Room
    {
        public MyRoom(int roundCount) : base(roundCount)
        {
 
        }
 
        public override Task GameCompletedAsync()
        {
            // invoke when game completed
        }
 
        public override Task NewUserJoinedAsync(User user)
        {
            // invoke when new user joined
        }
 
        public override Task RoomReadyForStartAsync(List<User> users)
        {
            // invoke when room ready for start
        }
 
        public override Task RoundStartedAsync(ushort roundId)
        {
            // invoke when new round started
        }
 
        public override Task UserExitedAsync(User user)
        {
            // invoke when an user exit from room or his connection lost
        }
 
        public override Task UserKickedAsync(User user)
        {
            // invoke when an user kicked from room
        }
    }

So after creating our classes, we want to create a new MyUser object

Declare in the LoginAsync task we created earlier.

[Listener(name:"Login")]
public Task LoginAsync(string data, TcpClient client)
{
  var user = new MyUser(client);

  Console.WriteLine($"new user with UniqueId{user.UniqueId} logined");
  Server.Send(user, "Login", "{ \"result\": true, id: " +
      user.UniqueId + "}");
  return Task.CompletedTask;
}

After this, we will join user to a room and start playing the game

Add a new listener and name it JoinAsync.

[Listener(name:"Join")]
public Task JoinAsync(string data, TcpClient client)
{
  Var user = UserManager.FindUser(client);
 
  var result = await RoomManager.JoinAsync(user);
 
  if (!result)
  {
      var room = new MyRoom(4);
      room.UsersCount = new TcpServerKit.Core.Range(2);
      await room.AddUserAsync(user);
  }
  else
  {
      Server.Send(user, "Join", string.Empty);
  }
}

In the first line we find the user with his client object.

Next line we will join the user to a random room and it returns true value if the user joins successfully.

Next line, if the result is false create a new room and then join the user to it. Number 4 means the number of rounds of the game we're going to play.

💡
Tip: the default round value is 2.

Next line we specify how many users can join this room. it can be a fixed value or a range of values.

room.UsersCount = new TcpServerKit.Core.Range(2, 4);

Next line we add the user to the room.

After that NewUserJoinedAsync task will be run.

public override Task NewUserJoinedAsync(User user)
{
  Console.WriteLine($"New user with UniqueId{user.UniqueId} joined.");
  return Task.CompletedTask;
}

After that all users join the room RoomReadyForStartAsync task will be run.

public override Task RoomReadyForStartAsync(List<User> users)
{
    Console.WriteLine("RoomReadyForStart");
    return Task.CompletedTask;
}

if we specify users count as a ranged value, in the previous example our range is between 2 and 4. If users who join to room are 3 or 2, we can start the game but the room is not full yet. For that we can check if all users joined the room with AllUsersJoined.

It returns true if all users joined and the room is full of users.

if (Room.AllUsersJoined)
{
    Console.WriteLine("All user joined.");
}