Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Sending Messages to other clients

Discussion in 'Multiplayer' started by robochase, Sep 23, 2015.

  1. robochase

    robochase

    Joined:
    Mar 1, 2014
    Posts:
    242
    I'm trying to make a two player game where one player is the server. I want both players to send messages to each other but I'm really have trouble getting two-way communication going. just a few questions -

    does the server player have to send his message to the other player via NetworkServer.SendToAll?

    does the client player have to send his message to the server player via m_client.Send?

    if i wanted to add more players, is it possible to do sort of a peer-to-peer setup, where any player can send a direct message to anyone at any time, or does it have to funnel through the server player?
     
  2. TehGM

    TehGM

    Joined:
    Nov 15, 2013
    Posts:
    89
    You can send network message directly to one connection using NetworkServer.SendToClient.
    Any message player-player has to go through server, currently. It's probably for security reasons. I am not even sure if players have reference to connection to another player. Server has it all.

    Edit: Changed Send to SendToClient. Sorry, my bad, didn't have any docs or VS open, used just my memory.
     
    Last edited: Sep 25, 2015
  3. robochase

    robochase

    Joined:
    Mar 1, 2014
    Posts:
    242
    NetworkServer.Send doesn't exist in the docs :(

    My first attempt at this actually used NetworkServer.SendToAll...both server and the client player would call this function to send a message. What I was seeing in my logs though, was that only the server player's message would actually go through (meaning, the server player would call NetworkServer.SendToAll, and the client player would receive the message). the client player would call the same function, but the server player would NOT get the message. Maybe I didn't set it up right? i feel like i'm missing some mundane detail, or perhaps fundamentally misunderstanding something.
     
  4. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    836
  5. robochase

    robochase

    Joined:
    Mar 1, 2014
    Posts:
    242
    ok i got to fiddle with this some more tonight. something just isn't...right.

    when the server fires up, NetworkClient.allClients has one NetworkClient in it, with a connection id of -1.
    the server starts listening for Connect messages like so -
    NetworkServer.RegisterHandler(MsgType.Connect, ClientConnected);

    when a client connects, i DO see ClientConnected getting called, but NetworkClient.allClients still only has one NetworkClient in it - the one with a connection id of -1.

    Basically I can't call NetworkServer.SendToClient to send my message because i don't have a connection id to send it to.

    Do I need to manually create a NetworkClient when a new client connects to the server?
     
  6. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    836
    NetworkClient.allClients is not quite what you're looking for. To quote the docs

    This is a list on the client's end of how many client instances it has connected. What you are looking for would be NetworkServer.connections.

    Since I haven't seen your code and don't know specifically what's going wrong, here's a super simple class that connects a client to a listening server.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.Networking;
    4. using System.Collections;
    5.  
    6. public class QuickNetTest : MonoBehaviour {
    7.  
    8.     NetworkClient client;
    9.  
    10.     void InitializeClient()
    11.     {
    12.         client = new NetworkClient();
    13.         client.RegisterHandler(MsgType.Connect, OnClientConnect);
    14.  
    15.         client.Connect(inputHost, 7777);
    16.     }
    17.  
    18.     void InitializeServer()
    19.     {
    20.         NetworkServer.Listen(7777);
    21.  
    22.         NetworkServer.RegisterHandler(MsgType.Connect, OnServerConnect);
    23.     }
    24.  
    25.     void OnServerConnect(NetworkMessage netMsg)
    26.     {
    27.         Debug.Log(string.Format("Client has connected to server with connection id: {0}", netMsg.conn.connectionId));
    28.  
    29.         NetworkServer.SetClientReady(netMsg.conn);
    30.     }
    31.  
    32.     void OnClientConnect(NetworkMessage netMsg)
    33.     {
    34.         Debug.Log(string.Format("Client has connected to server"));
    35.     }
    36.  
    37.     string inputHost = "localhost";
    38.  
    39.     void OnGUI()
    40.     {
    41.         if (!NetworkServer.active)
    42.         {
    43.             if (GUI.Button(new Rect(400, 20, 200, 20), "Init Server"))
    44.             {
    45.                 InitializeServer();
    46.             }
    47.         }
    48.  
    49.         if (client == null || !client.isConnected)
    50.         {
    51.             if (GUI.Button(new Rect(100, 20, 200, 20), "Client Connect"))
    52.             {
    53.                 InitializeClient();
    54.             }
    55.  
    56.             inputHost = GUI.TextField(new Rect(100, 60, 200, 20), inputHost);
    57.         }
    58.     }
    59. }
    60.  
    Note that UNet using a naming schema of prefixing network message handlers with "OnClient" and "OnServer" depending on where they are run. I.e., OnServerConnect is ran on the server when a client connects.
     
  7. robochase

    robochase

    Joined:
    Mar 1, 2014
    Posts:
    242
    oh i missed that part about NetworkClient.allClients. that disclaimer didn't show up in the tooltip in MonoDevelop I think :/

    as for your example, i've got pretty much what you've got, and i do have the client connecting to the server fine. the problem comes later when i'm trying to send my own messages (right now i'm just trying to send mouse click coordinates back & forth to each other).

    I'll have to try NetworkServer.connections tonight - that does sound like what I'm looking for. Thanks for your help so far :)
     
  8. robochase

    robochase

    Joined:
    Mar 1, 2014
    Posts:
    242
    Yes! it works! Thank you so much!
     
  9. robochase

    robochase

    Joined:
    Mar 1, 2014
    Posts:
    242
    Out of curiosity, is there any way to clearly monitor the network traffic? I'm just curious to know how big these messages actually are, down to the byte (including any extra stuff unity might be sending to ensure the message gets where it needs to go)

    just wondering the weird bits, like is it more optimal to use short variable names in your custom MessageBase? or does it just always pack/unpack the variables in the same order, so the name doesn't matter?
     
  10. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    836
    I don't know if Unity has anything built in, but I'd be interested to know.

    You can always just use Wireshark or whatever though as an external program.