GithubHelp home page GithubHelp logo

quaint-studios / sustenet Goto Github PK

View Code? Open in Web Editor NEW
5.0 4.0 0.0 7.09 MB

Sustenet is a C# networking solution for Unity3D that has a primary focus on scaling by allowing multiple servers to work together.

License: GNU Affero General Public License v3.0

C# 100.00%
c-sharp networking netcore sockets server client-server client unity3d unity unity-networking

sustenet's Introduction

Sustenet

A C# networking solution for Unity3D that has a primary focus on scaling by allowing multiple servers to work together.

.NET Core CodeFactor

Vision

This is a rough vision of where this project is headed, a more detailed layout will eventually be added.

The goal for Sustenet is to develop a connetion of servers. There are four major components in Sustenet.

  • The Master server is where all clusters go to be registered. There should really only be one Master Server. But I can't stop you if you want to do something more with it.

  • The Cluster would be considered your traditional server. You load Sustenet as a Cluster and it contains some configurations:

    • Key - The Cluster has a key in it, much like the SSH key you place on a server. Each Cluster should have a unique key. But, like I said, I can't stop you. You can reuse keys if you'd like. Just be aware that if one key is compromised, they all are. I will need some more research on how much security is required in an instance like this. Or what other approaches are an option.
    • Master Server IP - This is just telling the Cluster what IP to register to.
    • [Master Server Port = 6256] - Again, just some information to properly connect to the Master Server.
    • [Connection Limit = 0] - This is an optional property. Since it's set to 0, no connection limit is being enforced.
    • more soon...
  • The Fragment is used to give different settings to certain areas in a Cluster. This includes the size of the Fragment in-game, the amount of players in it before the settings might change, keeping track of which players are in this Fragment, and update-rates.

  • The Client is simply a Client. They'll connect to the Master server and have two options:

    • Login immediately, joining whatever Cluster they've been automatically allocated to, based on how much traffic the other Clusters are experiencing or based on their ping.
    • Manaully select a cluster, browsing their names and other information. If there's a connection limit, then lock access to join that server.

    That's it. After that, they'll just send and receive messages from their Cluster and the Cluster will handle swapping the player between Fragments based on their position.

Sustenet is aiming to improve this methodology over time. It's a learning experience. The structure may change over time. This will be the route taken for now though.

Collaboration

While I am still in the process of designing the structure of this project, I will not be actively accepting any collaborative efforts via pull requests. I am, however, open to being pointed in certain directions. Articles and documentation on specific issues are greatly appreciated. Even discussing it directly is welcome. If you're interested in that, feel free to join my Discord. You can discuss more about it in the #sustenet channel.

sustenet's People

Contributors

makosai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

sustenet's Issues

Running a client via a DLL does not callback after BeginConnect() successfully connects.

Describe the bug
Importing the DLL into Unity creates some issues. Using only the source code results in everything executing fine. I want to support both the DLL and importing the source code. In the DLL... BeginConnect() does not work as intended. This is when it's ran in Unity via a DLL. When the client is ran via an executable, the command line, or in Visual Studio then it runs fine.

The AsyncCallback never happens in BeginConnect(). But it connects! It just doesn't callback for some odd reason. I've asked around and did some research the for about a full day. Not getting very far. This is the last bit to move to the next phase.

You can find information on it here: Client.cs & BaseClient.cs.

BaseClient contains BeginConnect(). Client is what contains added functionality. Unity uses Client.

To Reproduce
There are two solutions in the structure branch. One for hosting a server / stress-testing client connections (5000 tested so far). The other for deploying a client only build. If you open SustenetClient.sln and go to the post build script, you can define a project location to automatically output it to. I'll eventually change it to have an option that copies the source code instead of the DLL so compile times are faster.

Steps to reproduce the behavior:

  1. Go to 'SustenetClient.sln'
  2. Optional: Go to the post build settings and change the directory to someplace that exists, preferably a test project.
  3. Build the project, copy the DLL if it wasn't done for you automatically with step 2.
  4. Declare a Sustenet.Clients.Client client and initialize it Start().
  5. In Update() call ThreadManager.UpdateMain().

Expected behavior
Calling Connect() should result in ConnectCallback triggering like it does when a .cs file is used instead of a DLL.

Desktop (please complete the following information):

  • OS: Windows 10

Additional context
The code below can be used to get a quick setup with the DLL attached, or you can still build your own DLL and use the code as well.

SustenetClient.zip (DLL) ./TestUnityProject/Sustenet/SustenetClient.dll

./TestUnityProject/Sustenet/ClientManager.cs

using UnityEngine;
using UnityEngine.UI;
using Sustenet.Transport;

public class ClientManager : MonoBehaviour
{
    public Client client;
    public Button btn;

    // Start is called before the first frame update
    void Start()
    {
        client = new Client();

        btn.onClick.AddListener(() => client.Connect());
    }

    // Update is called once per frame
    void Update()
    {
        ThreadManager.UpdateMain();
        Debug.Log(client);
    }
}

./TestUnityProject/Sustenet/Client.cs

using System.Collections.Generic;
using UnityEngine;
using Sustenet.Network;

public class Client : Sustenet.Clients.Client
{
    public Client() : base(debug: false) { }

    protected override void InitializeClientData()
    {
        Debug.Log("Initializing...");

        tcp.onConnected.Run += () => {
            Debug.Log("Successfully connected to the master server.");
        };

        tcp.onReceived.Run += (data) => {
            Debug.Log("Testing onReceived: " + data);
        };

        tcp.onDebug.Run += (msg) => DebugClient(msg);

        tcp.onDebug.RaiseEvent("Testing onDebug");

        packetHandlers = new Dictionary<int, PacketHandler>()
        {
            { (int)ServerPackets.welcome, this.Welcome }
        };
    }

    protected void DebugClient(string msg)
    {
        Debug.Log($"Client#{id}: {msg}");
    }
}

Stress testing the application results in failures.

Describe the bug
If a large amount of clients are joining and leaving the Master Server, the program will eventually hang.

To Reproduce
Steps to reproduce the behavior:

  1. sustenet --master to start the Master Server.
  2. sustenet --client=1000 to start 1000 connections.
  3. Close the client while they're still joining.
  4. The Master Server will stop receiving connections until it's restarted.

Expected behavior
The Master Server should dispose of Clients when they disconnect and should be able to properly handle a large amount of.

Desktop (please complete the following information):

  • OS: Windows 10 & Debian Linux

Dispose() on BaseClient needs improvement for memory management.

Describe the bug
Resources aren't be disposed of thoroughly. The main issue revolves around the BaseEvent event ... delegate { } not being disposed of properly when a BaseClient is removed from the Dictionary.

To Reproduce

  1. sustenet --master.
  2. sustenet --client=1000 to connect to the Master Server.
  3. Inspect the memory.
  4. Close the client.
  5. Inspect the memory and watch TcpHandlers, BaseEvents, and more fail to be cleaned up when Dispose() is called.

Expected behavior
The BaseClient should release everything it created on Dispose().

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.