Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Unity 2020 LTS & Unity 2021.1 have been released.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Unity Multiplayer OnReceivedBroadcast doesn't supply port number

Discussion in 'Multiplayer' started by Munchy2007, Jan 25, 2016.

  1. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,469
    NetworkDiscovery.OnReceivedBroadcast(string fromAddress,string data) supplies the fromAddress string in the format ::ffff:192.168.0.50 for example.

    Initially I thought the ffff part might be the port number as a hex string, however regardless of which port I start my host on before I start broadcast, it is always ffff.

    Therefore the only useful information I can get from then fromAddress string is the IP address.

    Currently I'm passing the port number in the data variable, however this seems a bit of an odd way to have to do it.

    Does anyone know if this is the way it's intended to work, or am I missing something here?
     
    Lofar42 likes this.
  2. abhilash-im

    abhilash-im

    Joined:
    Feb 3, 2016
    Posts:
    14
    Hello Munchy2007,

    How did you intercepted OnReceivedBroadcast() of NetworkDiscovery? I tried the same, but I couldn't get the broadcast message from the server.

    Below is what I had done:

    1. Create a class which implements NetworkDiscovery and override the OnReceivedBroadcast() method.
    2. In Unity Editor, I created an empty GameObject and mapped this class (in #1) as Component.

    Code (CSharp):
    1.  
    2. // Discovery is the instance of the class in step #1.
    3. Discovery.Initialize();   // returns true value.
    4. Discovery.StartAsClient();   // returns true value.
    5.  
    But after invoking the above code, I am not receiving any broadcast message from server.

    One thing I noticed was, in step #2, if I use NetworkDiscovery component directly instead of class created in step #1, then I am receiving the broadcast message from server.

    Any idea, what I am missing here?
    Any help will be appreciated.
    Awaiting your valuable reply.

    Thanks.
     
  3. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,469
    Hi abilash.im, I'm at work at the moment, and the project I used NetworkDiscovery in is on my home PC.

    When I get home I'll take a look at it and post some (hopefully) helpful example code.
     
  4. abhilash-im

    abhilash-im

    Joined:
    Feb 3, 2016
    Posts:
    14
    Thanks Munchy2007. Please feel free to share some pointers when you are back home.
    Thanks again.
     
  5. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,469
    So here are the scripts I came up with. Please bear in mind this was a first attempt, and is probably not the best way to approach it.

    This is my lan NetworkManager. It uses a UI with a 'HostGame' button connected up to the StartGameHost() method, and a GridLayoutGroup that is used to display join buttons for any local games found.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using UnityEngine.Networking;
    5.  
    6. public class MyLanNetManager : NetworkManager
    7. {
    8.     [SerializeField] GameObject UI;
    9.     public NetworkDiscovery discovery;
    10.     [HideInInspector] public bool isHost;
    11.  
    12.     void Start()
    13.     {
    14.        
    15.     }
    16.  
    17.     public void StartGameHost()
    18.     {
    19.         UI.SetActive(false);
    20.         isHost = true;
    21.         StartHost();
    22.     }
    23.  
    24.     public void StartGameClient()
    25.     {
    26.         UI.SetActive(false);
    27.         isHost = false;
    28.         StartClient();
    29.     }
    30.  
    31.     public override void OnStartHost()
    32.     {
    33.         discovery.StopBroadcast();
    34.         Debug.Log("Start Host Broadcast....");
    35.         discovery.broadcastData = networkPort.ToString();
    36.         discovery.StartAsServer();
    37.  
    38.     }
    39.  
    40.     public override void OnServerAddPlayer (NetworkConnection conn, short playerControllerId)
    41.     {
    42.         base.OnServerAddPlayer (conn, playerControllerId);
    43.         if(conn.connectionId > 0)
    44.         {
    45.             Debug.Log("Stop Host Broadcast...");
    46.             discovery.StopBroadcast();
    47.         }
    48.     }
    49.        
    50.     public override void OnStartClient(NetworkClient client)
    51.     {
    52.         base.OnStartClient(client);
    53.     }
    54.  
    55.     public override void OnStopClient()
    56.     {
    57.         UI.SetActive(true);
    58.         discovery.StopBroadcast();
    59.         Destroy(gameObject);
    60.     }
    61. }
    62.  
    This is the script for the GameButton, which needs to be added to a UI button and then be made into a prefab.

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using UnityEngine.EventSystems;
    4. using UnityEngine.UI;
    5. using UnityEngine.Networking;
    6.  
    7. public class LanGameButton : MonoBehaviour, IPointerClickHandler {
    8.     [SerializeField] Text buttonText;
    9.  
    10.     public string m_networkAddress;
    11.     public string networkAddress {
    12.         get{return m_networkAddress;}
    13.         set
    14.         {
    15.             m_networkAddress = value;
    16.             buttonText.text = value;
    17.         }
    18.     }
    19.        
    20.     #region IPointerClickHandler implementation
    21.     public void OnPointerClick (PointerEventData eventData)
    22.     {
    23.         MyLanNetManager.singleton.networkAddress = networkAddress;
    24.         MyLanNetManager.singleton.GetComponent<MyLanNetManager>().StartGameClient();
    25.     }
    26.     #endregion
    27. }
    This is the derived NetworkDiscovery class. The GridLayoutGroup from the NetworkManager UI and the GameButton prefab need to be hooked up to this in the inspector. Note, UseNetworkManager field is set to true.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine.Networking;
    6. using UnityEngine.UI;
    7.  
    8. public class MyNetworkDiscovery : NetworkDiscovery  {
    9.     [SerializeField] LanGameButton gameButtonPrefab;
    10.     [SerializeField] Transform buttonGrid;
    11.     public List<DiscoveredGame> discoveredGames = new List<DiscoveredGame>();
    12.     List<LanGameButton> gameButtons = new List<LanGameButton>();
    13.  
    14.     void Start()
    15.     {
    16.         Initialize();
    17.         StartAsClient();
    18.         StartCoroutine(CheckGamesList());
    19.     }
    20.  
    21.     public override void OnReceivedBroadcast (string fromAddress, string data)
    22.     {
    23.         base.OnReceivedBroadcast (fromAddress, data);
    24.         Debug.Log(fromAddress);
    25.         var parts = fromAddress.Split(new char[]{':'});
    26.  
    27.         bool found = false;
    28.         foreach(var dGame in discoveredGames)
    29.         {
    30.             if(dGame.networkAddress == parts[3])
    31.             {
    32.                 found = true;
    33.                 dGame.lastSeen = Time.time;
    34.                 break;
    35.             }
    36.         }
    37.  
    38.         if(!found)
    39.         {
    40.             var dGame = new DiscoveredGame();
    41.             dGame.networkAddress = parts[3];
    42.             dGame.networkPort = int.Parse(data);
    43.             dGame.lastSeen = Time.time;
    44.             discoveredGames.Add(dGame);
    45.         }
    46.            
    47.     }
    48.  
    49.     IEnumerator CheckGamesList()
    50.     {
    51.         while(true)
    52.         {
    53.             for(int i = discoveredGames.Count -1; i >= 0; i--)
    54.             {
    55.                 if(discoveredGames[i].lastSeen < Time.time-1.5f)
    56.                 {
    57.                     discoveredGames.RemoveAt(i);
    58.                 }
    59.             }
    60.  
    61.             foreach(var gButton in gameButtons)
    62.             {
    63.                 gButton.transform.SetParent(null, false);
    64.                 DestroyImmediate(gButton.gameObject);
    65.             }
    66.             gameButtons.Clear();
    67.  
    68.             foreach(var dGame in discoveredGames)
    69.             {
    70.                 var gButton = Instantiate<LanGameButton>(gameButtonPrefab);
    71.                 gButton.networkAddress = dGame.networkAddress;
    72.                 gButton.transform.SetParent(buttonGrid, false);
    73.                 gameButtons.Add(gButton);
    74.             }
    75.  
    76.             yield return new WaitForSeconds(1.5f);
    77.         }
    78.     }
    79. }
    80.  
    81. [System.Serializable]
    82. public class DiscoveredGame
    83. {
    84.     public string networkAddress;
    85.     public int networkPort;
    86.     public float lastSeen;
    87. }
    As I said I seriously doubt this is the best way to approach this, but it works, and I hope it helps get you pointed in the right direction.
     
  6. abhilash-im

    abhilash-im

    Joined:
    Feb 3, 2016
    Posts:
    14
    Hello Munchy2007. Thank you so much for the code snippets and pointers. Much appreciated.
    Let me give a try and will update you.
    Thanks again.
     
  7. abhilash-im

    abhilash-im

    Joined:
    Feb 3, 2016
    Posts:
    14
    Hello Munch2007,

    Sorry for being late. I was busy experimenting many other network related things.

    Based on your code snippet, I prepared a Unity sample.

    However, I got stuck with hooking up GridLayoutGroup and GameButton prefab in the inspector. I cannot see those variables in the inspector when selecting custom NetworkDiscovery (Screenshot attached).
    unity_insp_netdiscovery.png

    I am also attaching the unity sample prepared as per your instructions. It would be really great, if you could take a look.
    Thanks again and appreciate your feedbacks.
     

    Attached Files:

  8. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,469
    Hi @abhilash.im

    Sorry I forgot to mention that for those fields to show up in the inspector so that you can populate them, you need to put the inspector into debug mode.
    NetworkDiscovery.png
     
    abhilash-im likes this.
  9. abhilash-im

    abhilash-im

    Joined:
    Feb 3, 2016
    Posts:
    14
    Hello @Munchy2007 , Thanks for the comments. It fixed the issue. Now, I am able to intercept the broadcast message. I have a close look at my implementation. My NetwokDiscovery never had any Prefab. That's the only difference I could see.

    Thank you for your valuable comment.
     
  10. JesusChrist17

    JesusChrist17

    Joined:
    Sep 17, 2016
    Posts:
    12
    does anybody know if i can sent also the name of host ( broadcast like ip + port + nameHost )??
     
  11. ZoidbergForPresident

    ZoidbergForPresident

    Joined:
    Dec 15, 2015
    Posts:
    147
    Hi guys.

    Sorry but frrom this thread I still don't know how the server broadcast its port, how can you pass that info to the listening clients?
     
  12. wadybaby7861

    wadybaby7861

    Joined:
    Apr 17, 2020
    Posts:
    4
    Also need to know this here, if anyone can assist. It would be appreciated:)
     
unityunity