Search Unity

'Broadcast discovery already running', 'StartBroadcast failed err: 8' & 'StartServer listen failed'

Discussion in 'Multiplayer' started by _Adriaan, Sep 28, 2015.

  1. _Adriaan

    _Adriaan

    Joined:
    Nov 12, 2009
    Posts:
    481
    Excuse me for the gigantic title! ;)

    I'm continuously hitting the same wall with the NetworkManager in combination with NetworkDiscovery and I can't figure out how to get around this. I hypothesise that this is a bug in UNET, unless someone here knows what I'm doing wrong. Other posts on the forum talking about the 'StartServer listen failed' error suggest that this issue has been fixed, but, well, I'm still experiencing it in 5.2.1f1.

    Example project attached
    I've attached an example test project which has a nice interface to quickly create / connect and disconnect with a LAN game. But mind you that I've found that the speed at which you connect / disconnect seems to be irrelevant.

    The problem
    After two or three connects / disconnects creating a local networked game, the game will stop working completely due to these three errors:

    Broadcast discovery has been already running. Stop discovery first before repeat this call
    UnityEngine.Networking.NetworkDiscovery:StartAsServer()

    and
    NetworkDiscovery StartBroadcast failed err: 8
    UnityEngine.Networking.NetworkDiscovery:StartAsServer()

    and
    StartServer listen failed.
    UnityEngine.Networking.NetworkManager:StartHost()


    Even using the 'HARD RESET' button in my example (which destroys the NetworkManager and NetworkDiscovery) doesn't fix the problem that I'm stuck in this state. As a matter of fact - nothing in-game that I've tried gets me out of this state. All I can do is quit the game and start over.

    Considering connections sometimes fail on mobile networks, being able to restart / rejoin a game even when the connection failed previously is a MUST. Any help on this is greatly appreciated!!
     

    Attached Files:

  2. Bash-Mills

    Bash-Mills

    Joined:
    Sep 15, 2013
    Posts:
    3
    I had pretty much an identical problem. I found that the following made it work if called just before the StartAsServer and StartAsClient calls. Just make sure any existing network sessions and broadcasts have been stopped before doing it.
    Code (CSharp):
    1. NetworkTransport.Shutdown();
    2. NetworkTransport.Init();
    3.  
    I'm not sure how expensive it is to shutdown and init the whole network transport but until a better fix is put in place this could be a workaround for now :)
     
    CharlieH likes this.
  3. Muckel

    Muckel

    Joined:
    Mar 26, 2009
    Posts:
    471
    Hello,
    had the same issue.... maybe a Unity bug?
    well i fixed it on the client side with these:
    hope it helps someone...
    M.
     
  4. helgewt

    helgewt

    Joined:
    Jul 21, 2015
    Posts:
    12
    This bug still appears in Unity 5.5.1f1.

    The client shutdown workaround seems to work in Unity editor, but not when running as build (Windows x64),
    The only way I could fix it was by shutting down the whole NetworkTransport.

    Code (CSharp):
    1.  
    2. namespace BIMeVR
    3. {
    4.     public class NetDiscovery : NetworkDiscovery
    5.     {
    6.         public static NetDiscovery singleton;
    7.  
    8.         void Awake()
    9.         {
    10.             if (singleton != null && singleton != this) {
    11.                 Debug.Log("Multiple instances of " + typeof(NetDiscovery).Name + " detected. Disabling this one.", gameObject);
    12.                 this.enabled = false;
    13.             } else {
    14.                 singleton = this;
    15.             }
    16.         }
    17.  
    18.         public new void StopBroadcast()
    19.         {
    20.             if (running)
    21.                 base.StopBroadcast();
    22.             try {
    23.                 if (NetworkTransport.IsBroadcastDiscoveryRunning()) {
    24.                     Debug.LogWarning("Broadcast discovery still running despite NetDiscovery having stopped - stopping again.", gameObject);
    25.                     NetworkTransport.StopBroadcastDiscovery();
    26.                 }
    27.             } catch (NullReferenceException) {
    28.                 // Ignore when NetworkTransport is not initialized
    29.             }
    30.         }
    31.     }
    32. }
    33.  
    Code (CSharp):
    1.  
    2. namespace BIMeVR
    3. {
    4.     [RequireComponent(typeof(NetDiscovery))]
    5.     public class NetManager : NetworkManager
    6.     {
    7.         public override void OnStopClient()
    8.         {
    9.             ClientShutdownAndReset();
    10.         }
    11.  
    12.         // Workaround for broadcast not working after host has been started/stopped multiple times
    13.         // https://issuetracker.unity3d.com/issues/broadcast-discovery-not-stopping-after-multiple-calls
    14.         // https://forum.unity3d.com/threads/broadcast-discovery-already-running-startbroadcast-failed-err-8-startserver-listen-failed.357852/
    15.         private void ClientShutdownAndReset()
    16.         {
    17.             NetDiscovery.singleton.StopBroadcast();
    18.             if (client != null) {
    19.                 client.Disconnect();
    20.                 client.Shutdown();
    21.                 client = null;
    22.             }
    23.             if (isNetworkActive) {
    24.                 Debug.LogError("Network is still active even though the client has reportedly stopped.", gameObject);
    25.                 return;
    26.             }
    27.             Debug.Log("Resetting network transport layer");
    28.             NetworkTransport.Shutdown();
    29.             NetworkTransport.Init();
    30.         }
    31.     }
    32. }
    33.  
     
  5. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    574
    StopBroadcast() is not synchronous function. It will send command to stop broadcast only, and it will require time for system to execute this command.
    Move NetworkTransport.IsBroadcastDiscoveryRunning() to Update() function and wait before it will return false

    hope it helps
     
    moco2k likes this.
  6. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    Such kind of information should be provided within the docs.

    This would save people from running into issues and finding themselves in the need to study the network discovery source code to find out what's going on. So far, there already has been a lot of confusion about proper usage of Network Discovery, for example also see this thread.
     
    Last edited: Apr 7, 2017
    Muckel likes this.
  7. helgewt

    helgewt

    Joined:
    Jul 21, 2015
    Posts:
    12
    Thanks for your reply and the added clarification.
    It does indeed work if I wait for broadcasting to shutdown cleanly.

    I have done some more testing - here is some additional information.

    After NetworkManager.StartClient(), it works as expected:
    StopBroadcast() works immediately - NetworkTransport.IsBroadcastDiscoveryRunning() returns false. I don't need to wait, reset NetworkTransport or do anything besides calling StopClient() right after.

    After NetworkManager.StartHost(), things start to break in builds (but not always in the editor)
    After I have used StartHost(), the StopBroadcast() command is asynchronous, like you said.
    If I call StopHost() before broadcasting has stopped completely, eventually NetworkDiscovery will stop working and StartHost() will fail to bind on the port - this happens consistently in Windows x64 builds on the third Start/Stop cycle, but only occasionally in the Unity Editor.
    As I said, the third StartHost() command will fail to bind on the same port, indicating that it is still in use by the transport API despite having called NetworkManager.singleton.StopHost().

    The clean fix:
    I have deleted the previous workaround and instead implemented new static Stop-methods in NetManager that defer the actual command until broadcasting has completely stopped.
    Simplified example code below.

    Code (CSharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. namespace BIMeVR
    7. {
    8.     public class NetDiscovery : NetworkDiscovery
    9.     {
    10.         public static NetDiscovery singleton;
    11.  
    12.         public static bool stopConfirmed = false;
    13.  
    14.         void Awake()
    15.         {
    16.             if (singleton != null && singleton != this)
    17.                 this.enabled = false;
    18.             else
    19.                 singleton = this;
    20.         }
    21.  
    22.         public new void StopBroadcast()
    23.         {
    24.             if (running)
    25.                 base.StopBroadcast();
    26.             ConfirmStopped();
    27.         }
    28.  
    29.         void LateUpdate()
    30.         {
    31.             if (!running && !stopConfirmed)
    32.                 ConfirmStopped();
    33.         }
    34.  
    35.         void ConfirmStopped()
    36.         {
    37.             try {
    38.                 stopConfirmed = !NetworkTransport.IsBroadcastDiscoveryRunning();
    39.             } catch (Exception) {
    40.                 stopConfirmed = true;
    41.             }
    42.         }
    43.     }
    44. }
    45.  
    Code (CSharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. namespace BIMeVR
    7. {
    8.     [RequireComponent(typeof(NetDiscovery))]
    9.     public class NetManager : NetworkManager
    10.     {
    11.         public static void StopClientAndBroadcast()
    12.         {
    13.             NetDiscovery.singleton.StopBroadcast();
    14.             onBroadcastStopped += singleton.StopClient;
    15.         }
    16.  
    17.         public static void StopServerAndBroadcast()
    18.         {
    19.             NetDiscovery.singleton.StopBroadcast();
    20.             onBroadcastStopped += singleton.StopServer;
    21.         }
    22.  
    23.         public static void StopHostAndBroadcast()
    24.         {
    25.             NetDiscovery.singleton.StopBroadcast();
    26.             onBroadcastStopped += singleton.StopHost;
    27.         }
    28.  
    29.         private static event Action onBroadcastStopped;
    30.  
    31.         void Update()
    32.         {
    33.             if (onBroadcastStopped != null) {
    34.                 if (!NetDiscovery.singleton.running && NetDiscovery.singleton.stopConfirmed) {
    35.                     onBroadcastStopped.Invoke();
    36.                     onBroadcastStopped = null;
    37.                 } else {
    38.                     if (LogFilter.logDebug)
    39.                         Debug.Log("Waiting for broadcasting to stop completely", gameObject);
    40.                     NetDiscovery.singleton.StopBroadcast();
    41.                 }
    42.             }
    43.         }
    44.     }
    45. }
    46.  
     
    Muckel likes this.
  8. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    574
    @helgewl thanks a lot for your feedback. Actually it looks like a small bug, could you think a bit should it be fixed, and if yes could you open the bug about this. I understood, that you fix is perfect, but the library possible should send some notification about this? Or documentation should be added? Please, make decision :)
     
  9. Jodon

    Jodon

    Joined:
    Sep 12, 2010
    Posts:
    434
    Muckel likes this.