Author Topic: Hosting bandwidth and server  (Read 7711 times)

xandeck

  • Jr. Member
  • **
  • Thank You
  • -Given: 1
  • -Receive: 3
  • Posts: 54
    • View Profile
Hosting bandwidth and server
« on: October 25, 2015, 07:35:45 AM »
Hello Aren,

Please, since someone can create a Server Instance and someone can be a host (been the same host and owner, or not), does the host always controls about sending the data between host and clients? I mean, let's say I have the following picture:
- I have a server instance, hosted on Amazon or any other full time 24 hours PC
- I have players A, B, C
- Player A connects and creates a channel (a room, for him to player with friends)
- Player B and C connects to this channel
- Is it the player A who keeps consuming his own bandwidth or is it the server instance?

This can change how I am implementing the game.
Thanks in advance.
« Last Edit: November 01, 2015, 04:29:33 PM by xandeck »

cmifwdll

  • Global Moderator
  • Sr. Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 149
  • Posts: 285
  • TNet Alchemist
    • View Profile
Re: Hosting bandwidth and server
« Reply #1 on: October 25, 2015, 01:23:27 PM »
Packets are sent to the server, and the server then relays them to others.

In my opinion I think the term "host" should be refactored to "operator" to avoid confusion.
  1. Player A calls tno.SendQuickly(rfcID, Target.Others, someData):
  2. * Packet is sent to server
  3. * Server determines who to forward the packet to based on Target parameter
  4. * Server forwards the packet to targets
  5.  
  6. Player A calls tno.SendQuickly(rfcID, Target.Host, someData):
  7. * The RFC is executed locally, no packets sent
  8.  
  9. Player A calls tno.SendQuickly(rfcID, Target.All, someData):
  10. * The RFC is executed locally
  11. * Packet is sent to server
  12. * Server determines who to forward the packet to based on Target parameter
  13. * Server forwards the packet to targets
  14.  
  15. Player B calls tno.SendQuickly(rfcID, Target.Others, someData):
  16. * Packet is sent to server
  17. * Server determines who to forward the packet to based on Target parameter
  18. * Server forwards the packet to targets
  19.  
  20. Player B calls tno.SendQuickly(rfcID, Target.Host, someData):
  21. * Packet is sent to server
  22. * Server determines who to forward the packet to based on Target parameter (Player A in this case)
  23. * Server forwards the packet to Player A
  24.  
  25. Player B calls tno.SendQuickly(rfcID, Target.All, someData):
  26. * The RFC is executed locally
  27. * Packet is sent to server
  28. * Server determines who to forward the packet to based on Target parameter
  29. * Server forwards the packet to targets
  30.  

So, you can really think of the server as a souped-up relay, and the "host" (operator) as a client with a special authoritative designation.

xandeck

  • Jr. Member
  • **
  • Thank You
  • -Given: 1
  • -Receive: 3
  • Posts: 54
    • View Profile
Re: Hosting bandwidth and server
« Reply #2 on: October 25, 2015, 02:18:30 PM »
Thanks for the detailed information @cmifwdll =)
I already know how the message / data is sent to one another (but your info also clarified some points, thanks), but my question really is: what PC will consume bandwidth, mostly?
I mean, the "operator" will take care of all the data to transfer or it will be the master server?
Will player A transfer same amount of data than player B and C (so, really, the master server will have the heavy load)? Or whoever be the host will handle this heavy load?

Thanks

cmifwdll

  • Global Moderator
  • Sr. Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 149
  • Posts: 285
  • TNet Alchemist
    • View Profile
Re: Hosting bandwidth and server
« Reply #3 on: October 25, 2015, 07:40:12 PM »
Again, think of the server as a relay. However you decide to code your game will determine whether player A consumes more bandwidth than player B. Regardless, though, the server will always consume the most because all data passes through it.

xandeck

  • Jr. Member
  • **
  • Thank You
  • -Given: 1
  • -Receive: 3
  • Posts: 54
    • View Profile
Re: Hosting bandwidth and server
« Reply #4 on: October 26, 2015, 12:42:11 PM »
well, ok, thanks, I will check this out as soon as I start to test more.

devomage

  • Sr. Member
  • ****
  • Thank You
  • -Given: 7
  • -Receive: 67
  • Posts: 250
    • View Profile
Re: Hosting bandwidth and server
« Reply #5 on: October 27, 2015, 04:53:10 PM »
related question:

does a RFC communicate client to client?  ive always assumed RFC is still relayed by a server.

cmifwdll

  • Global Moderator
  • Sr. Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 149
  • Posts: 285
  • TNet Alchemist
    • View Profile
Re: Hosting bandwidth and server
« Reply #6 on: October 27, 2015, 08:42:20 PM »
related question:

does a RFC communicate client to client?  ive always assumed RFC is still relayed by a server.

You call RFCs via tno.Send / tno.SendQuickly. Yes, RFCs pass through the server. There's no client to client communication in TNet except for LAN broadcasting.
In case you meant RCCs, yes, those are relayed too. They're basically RFCs with an additional designation.

well, ok, thanks, I will check this out as soon as I start to test more.

If you've coded your game so that your Target parameter in most of your tno.Send / tno.SendQuickly calls is Target.Host, and very rarely target Target.All then of course Player A (the operator) is going to receive more data than Player's B and C, but even then the server will be consuming the *most* because all tno.Send / tno.SendQuickly calls pass through the server regardless of the Target parameter.

In reality there probably won't be much of a difference in how much data Player's A, B, and C send / receive, because you're likely going to be using Target.All / Target.Others just as much as you use Target.Host. This doesn't mean you can get away with generating 10 MB/s of net data though :P be wary of what you're syncing and how often. Aren has offered much advice on this subject. Particularly movement and anim syncs (don't sync the anim state, sync the input and have each client run the anim themselves).

xandeck

  • Jr. Member
  • **
  • Thank You
  • -Given: 1
  • -Receive: 3
  • Posts: 54
    • View Profile
Re: Hosting bandwidth and server
« Reply #7 on: October 28, 2015, 08:59:07 AM »
Hello cmifwdll

Thank you for your tips.
Actually, I am pretty much aware of data sync and how to avoid those lost data and too much bandwitdh use. I was just a little bit lost about some of the send / receive package on TNet.
I am actually having another problem now, I think it is still related to this, if you or Aron could me help, I really appreciate it.

I am sending tno.Send with RFC and sometimes, the message never reaches neither the host or the client.
I have checked other posts and questions.
- I am making channel persistent (but sometimes it fails either with true or false)
- I connect to a channel for a scene load and another channel for players "waiting to play". Then I just change the scenes to play a mission (it is a basic FPS at the moment), but I don't change the channel. Do you know if it is necessary to change the channel each time I change the scene? Or the TNet does it for me?
- I have tested now (it's been 2 days, the game logic is working good) and my main problem is this... sometimes a specific tno.Send does not work (I do believe it is something on my side, because it is only with one of my methods, not all). But I cannot find the damn problem =P

Code:
  1. tno.Send("_Receive_ReadyToStartMatch", Target.AllSaved, _networkProfileActive._nameAlias);

It should receive here:
  1. // ################################################################################################
  2.         /// <summary>
  3.         /// Receive answer that can start the mission
  4.         /// </summary>
  5.         [RFC] void _Receive_ReadyToStartMatch (string pName)
  6.         {
  7.                 MySystem.Instance._SaveLog(this.name, "NETWORK: Received ready to match from " + pName);
  8.  
  9.                 //How many players ready?
  10.                 _playersReady++;
  11.  
  12.                 //Update
  13.                 MySystem.Instance._HudForNetwork_UpdatePlayersReady(_playersReady);
  14.  
  15.                 //If all good, lets start
  16.                 if (_playersReady >= _GetPlayersOnline && _IsHost)
  17.                         _Send_StartMission();
  18.         }

But sometimes it never gets to me... I am also wondering if it is something to do with the server I am creating (using TCP and UDP when possible)...
Any clue? Thanks in advance.


EDIT: Looks like when this happens, after some time, the player just disconnects... maybe it is something with the game creation? Or server?
EDIT2: also, sometimes, it shows "No valid socket" after some messages arrives, in this same code calls
« Last Edit: October 28, 2015, 02:31:25 PM by xandeck »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Hosting bandwidth and server
« Reply #8 on: October 29, 2015, 07:08:27 AM »
Only one instance of your function will be stored.

Think of RFCs as active states. When you set a state with some values, like your player name -- that's the state that everyone else will get. So even if you call the function 100 times, only the latest state is actually stored as you are effectively overwriting your previous state.

If you are trying to do something as simple as a "I am ready" state, this is how you should be doing it:

Each client marks themselves as ready:
  1. TNManager.playerDataNode.SetChild("isReady", true);
  2. TNManager.SyncPlayerData();
You should be subscribed to the TNManager.onPlayerSync delegate if you want to be notified of these sync updates:
  1. void Awake ()
  2. {
  3.     TNManager.onPlayerSync = OnPlayerSync;
  4. }
  5.  
  6. void OnPlayerSync (Player p)
  7. {
  8.     Debug.Log(p.name + " is " + (p.dataNode.GetChild<bool>("isReady") ? "ready" : "not ready"));
  9. }
You can iterate through all players and check their status at any time:
  1. for (int i = 0; i < TNManager.players.size; ++i)
  2. {
  3.     Player p = TNManager.players[i];
  4.     Debug.Log(p.name + " is " + (p.dataNode.GetChild<bool>("isReady") ? "ready" : "not ready"));
  5. }
No RFCs needed.

xandeck

  • Jr. Member
  • **
  • Thank You
  • -Given: 1
  • -Receive: 3
  • Posts: 54
    • View Profile
Re: Hosting bandwidth and server
« Reply #9 on: October 29, 2015, 11:33:41 AM »
Perfect, Aren, thank you very much for this.
By the way, do you know if the "disconnecting" problem has anything to do with this?
« Last Edit: November 01, 2015, 04:29:49 PM by xandeck »

xandeck

  • Jr. Member
  • **
  • Thank You
  • -Given: 1
  • -Receive: 3
  • Posts: 54
    • View Profile
Re: Hosting bandwidth and server
« Reply #10 on: October 29, 2015, 01:14:12 PM »
hello Aron,
the way you sent about the "set ready" is better... but it did not solve my problem =(
Even using

  1. TNManager.playerDataNode.SetChild("_isReady", _networkIamReady);
  2. TNManager.SyncPlayerData();
  3.  

looks like the other player never receives the message (it does not matter if it is by your method or a RFC).
And then, after a few seconds (sometimes more than 20), client disconnects... I am testing in the same PC, 2 same builds... but I also tested through online with other people. Same problem. Something is making my connection to drop or something like that...

EDIT: ok, I'm about to give up =( (I was reading and searching for this more than 3h now).
It does not simply work...
Sending RFC, or doing the "SyncPlayerData" does not work... one or more players never receives the message. And sometimes, after a few seconds (or not at all), the client disconnects, no callback message, nothing. The "No valid socket" sometimes shows, sometimes not...
And the crazy part is: the players who could send messages, it still can send messages (everyone receives) and the ones who could not send, still cannot send... what the hell
It appears that, somehow, some players got blocked for sending messages (RFC, RCC, anything)...
« Last Edit: October 29, 2015, 02:34:20 PM by xandeck »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Hosting bandwidth and server
« Reply #11 on: October 29, 2015, 03:32:23 PM »
It sounds like the issue lies elsewhere. Try it in a very simple clean project. What else are you sending there, and how? Do you use SendQuickly or Send? Disconnect implies timing out, and timing out can happen if the client begins sending a packet but then never finishes (for example calling BeginSend, then never calling EndSend). You may also have a problem where you are sending stuff in Update(), thus spamming the network, effectively DDoS-ing yourself.

P.S. What version of TNet?

xandeck

  • Jr. Member
  • **
  • Thank You
  • -Given: 1
  • -Receive: 3
  • Posts: 54
    • View Profile
Re: Hosting bandwidth and server
« Reply #12 on: October 29, 2015, 03:53:42 PM »
Hello Aren,

I am using both Send and SendQuickly, the second one just for position and animation.
No sync calls on update, for sure.
Last version is 2.1.1

I am sending normal string or int, nothing else...
Also, many problems seems to start, sometimes, after the "TNManager.CreateEx"... I will try with a clean project, but I really need this one working on the current project...
Thanks
« Last Edit: November 01, 2015, 04:29:55 PM by xandeck »

xandeck

  • Jr. Member
  • **
  • Thank You
  • -Given: 1
  • -Receive: 3
  • Posts: 54
    • View Profile
Re: Hosting bandwidth and server
« Reply #13 on: October 29, 2015, 04:12:47 PM »
Aren,

Is there a way to check if there is a package sending "forever"? Or to stop a send package and try again?
I cannot try in a very clean project, to replicate this it will give me too much work. But normal create and send seems to work.
I still think it is something as you said, with sending and receiving.
What is happening:
- Player A send chat to all: Player A and player B receives
- Player B send chat to all: Player B receives, player A never receives =/
- Player A send chat to all: Player A and player B receives again, normal

EDIT: ok, I discovered something interesting
If I use the "development build" on Unity, there are more problems.
If I don't use, I still receive some "[TNet] Trying to execute RFC #4 on TNObject #16777215 before it has been created." but it works after a few seconds.
So, if I use "dev build" it stops on the first message and all the game get broken.
This only happens with the "TNManager.CreateEx", so maybe I am doing something wrong... but it just works with those warning messages =/

  1. // ################################################################################################
  2.         /// <summary>
  3.         /// Creates character
  4.         /// </summary>
  5.         public void _Send_CreatePlayerCharacter (Vector3 pos, Quaternion rot, string unitName, _CharacterData charInfo)
  6.         {
  7.                
  8.                 TNManager.CreateEx(12, false, _MissionSceneManager.Instance._charactersPrefabs[(int)_CharacterType.allyNpc], pos, rot, unitName, (int)charInfo._weaponPrimary, (int)charInfo._weaponSecondary, (int)charInfo._gadget1, (int)charInfo._gadget2);
  9.         }
  10.  
  11. // ################################################################################################
  12.         /// <summary>
  13.         /// Step 2: Create a function that will be called when the unit creation packet arrives.
  14.         /// Make sure that this script is attached to the same game object as TNManager or one of its children,
  15.         /// or that you registered this MonoBehaviour by calling TNManager.AddRCCs!
  16.         /// </summary>
  17.         [RCC(12)] static GameObject _Receive_CreatePlayerCharacter (GameObject prefab, Vector3 pos, Quaternion rot, string unitName, int gun1, int gun2, int gad1, int gad2)
  18.         {
  19.                
  20.                 //Cria personagem na tela
  21.                 GameObject objCreated = (GameObject) Instantiate(prefab, pos, rot);
  22.                 objCreated.name = unitName;
  23.                
  24.                 //Pega script e cria arma para ele
  25.                 _CharacterPlayerController playerScript = objCreated.GetComponent<_CharacterPlayerController>();
  26.                
  27.                 //Pega items a dar para jogador
  28.                 _ItemData playerGun1Weapon = _ItemsManager.Instance._itemsList[gun1];
  29.                 _ItemData playerGun2Weapon = _ItemsManager.Instance._itemsList[gun2];
  30.                 _ItemData itemExtra1 = _ItemsManager.Instance._itemsList[gad1];
  31.                 _ItemData itemExtra2 = _ItemsManager.Instance._itemsList[gad2];
  32.                
  33.                 _CharacterData tempPlayer = new _CharacterData();
  34.                 tempPlayer = Instance._networkProfileActive._soldiersList[0];
  35.                
  36.                 //CHECA ERROS
  37.                 if (tempPlayer._alias == "")
  38.                 {
  39.                         Debug.Log("ERROR: character to create NOT FOUND");
  40.                         return objCreated;
  41.                 }
  42.                
  43.                 //Seta jogador local
  44.                 playerScript._PrepareForStartLocal(tempPlayer, playerGun1Weapon, playerGun2Weapon, itemExtra1, itemExtra2);
  45.                
  46.                 //AVISA EVENTOS
  47.                 _MissionSceneManager.Instance._CallPlayerCreated();
  48.                
  49.                 return objCreated;
  50.         }
  51.  

EDIT2: ok, can confirm this, many of the problems are related to the "TNManager.CreateEx"
Either I am doing something wrong (you can see above) or it is broken
« Last Edit: October 30, 2015, 09:11:58 AM by xandeck »

xandeck

  • Jr. Member
  • **
  • Thank You
  • -Given: 1
  • -Receive: 3
  • Posts: 54
    • View Profile
Re: Hosting bandwidth and server
« Reply #14 on: October 30, 2015, 01:44:38 PM »
Hello Aren,

Ok, I found some problems on my side and I was able to solve almost everything, but I need a better direction how to make it right, because my workaround is not the best one for sure.
- I was calling LoadLevel (from TNet) from both Host and Client, but I think only the host needs to call, right? I think this alone solved many sync problems (whatever this means)
- The game, somehow, was trying to call RFC methods with objects not ready in scene... I could delay this (I added some timers) but I still don't know how to know who is ready... how can I know?
- Even now, sometimes, that same problem happens: player A never receives message from other players (but now is rare, I think it has to do with my network connection)
There are other minor things that I need to check, but now it is playable.