I am trying to program a custom network manager with UNet, since the standard one does not support LAN broadcast matchmaking. At least not that I know of it.
I have successfully set up the broadcasting on the server side and the reading of the broadcasts on the client side, so I am getting a nice List of all servers in the LAN. But when I try to connect, it first seems to work, but then the client receives a “WrongConnection” error when receiving the “NetworkEventType.ConnectEvent”.
I am starting the connect in line 300 with the “ConnectToHost” function, and I am checking for network events in the Update function. The “NetworkEventType.ConnectEvent” gets checked in line 249, then I am trying to get the connection info in line 256, which then results in the error.
Please see my code below. Any ideas what is going wrong?
using UnityEngine;
using UnityEngine.Networking;
using System.Collections.Generic;
//using System;
public class CustomNetworkManager : MonoBehaviour {
const int kMaxBroadcastMsgSize = 10240;
// config data
[SerializeField]
public int broadcastPort = 47654;
[SerializeField]
public int broadcastKey = 47654;
[SerializeField]
public int broadcastVersion = 1;
[SerializeField]
public int broadcastSubVersion = 1;
[SerializeField]
public string broadcastData = "HELLO";
[SerializeField]
public float hostListEntryTimeout = 4f;
// runtime data
private int hostId = -1;
private int connectionId = -1;
private bool broadcastRunning = false;
private bool isServer = false;
private bool isClient = false;
byte[] msgOutBuffer = null;
byte[] msgInBuffer = null;
private List<HostListData> hostList;
private bool hostListChanged = false;
private static CustomNetworkManager _instance;
private const string networkManagerPrefabPath = "NetworkManager";
public void Awake() {
Initialize ();
}
public bool Initialize()
{
if (broadcastData.Length >= kMaxBroadcastMsgSize)
{
Debug.LogError("NetworkDiscovery Initialize - data too large. max is " + kMaxBroadcastMsgSize);
return false;
}
if (!NetworkTransport.IsStarted)
{
NetworkTransport.Init();
}
DontDestroyOnLoad(gameObject);
msgOutBuffer = Utils.GetBytesFromString(broadcastData);
msgInBuffer = new byte[kMaxBroadcastMsgSize];
return true;
}
// listen for broadcasts
public bool StartAsClient()
{
if (hostId != -1 || broadcastRunning)
{
Debug.LogWarning("NetworkDiscovery StartAsClient already started");
return false;
}
ConnectionConfig cc = new ConnectionConfig();
cc.AddChannel(QosType.Reliable);
HostTopology defaultTopology = new HostTopology(cc, 1);
hostId = NetworkTransport.AddHost(defaultTopology, broadcastPort);
if (hostId == -1)
{
Debug.LogError("NetworkDiscovery StartAsClient - addHost failed");
return false;
}
byte error;
NetworkTransport.SetBroadcastCredentials(hostId, broadcastKey, broadcastVersion, broadcastSubVersion, out error);
broadcastRunning = true;
isClient = true;
isServer = false;
hostList = new List<HostListData> ();
hostListChanged = true;
Debug.Log("StartAsClient Discovery listening");
return true;
}
// perform actual broadcasts
public bool StartAsServer()
{
if (hostId != -1 || broadcastRunning)
{
Debug.LogWarning("NetworkDiscovery StartAsServer already started");
return false;
}
ConnectionConfig cc = new ConnectionConfig();
cc.AddChannel(QosType.Reliable);
HostTopology defaultTopology = new HostTopology(cc, 1);
hostId = NetworkTransport.AddHost(defaultTopology, broadcastPort);
if (hostId == -1)
{
Debug.LogError("NetworkDiscovery StartAsServer - addHost failed");
return false;
}
string serverName = GameManager.Instance ().GetFirstLocalPlayerName ();
msgOutBuffer = Utils.GetBytesFromString(serverName + "\'s Game");
if (msgOutBuffer.Length >= kMaxBroadcastMsgSize)
{
Debug.LogError("NetworkDiscovery Initialize - data too large. max is: " + kMaxBroadcastMsgSize + ", current is: " + msgOutBuffer.Length);
return false;
}
byte err;
if (!NetworkTransport.StartBroadcastDiscovery(hostId, broadcastPort, broadcastKey, broadcastVersion, broadcastSubVersion, msgOutBuffer, msgOutBuffer.Length, 1000, out err))
{
Debug.LogError("NetworkDiscovery StartBroadcast failed err: " + err);
return false;
}
broadcastRunning = true;
isServer = true;
isClient = false;
Debug.Log("StartAsServer Discovery broadcasting");
return true;
}
public void StopBroadcast()
{
if (hostId == -1)
{
Debug.LogError("NetworkDiscovery StopBroadcast not initialized");
return;
}
if (!broadcastRunning)
{
Debug.LogWarning("NetworkDiscovery StopBroadcast not started");
return;
}
if (isServer) {
NetworkTransport.StopBroadcastDiscovery();
}
broadcastRunning = false;
hostList = new List<HostListData> ();
Debug.Log("Stopped Discovery broadcasting");
}
public void Disconnect() {
if (hostId < 0) {
Debug.LogError(GetType() + ".Disconnect: was not connected.");
return;
}
byte error;
if (connectionId >= 0) {
NetworkTransport.Disconnect (hostId, connectionId, out error);
if (error != 0) {
Debug.LogError (GetType () + ".Disconnect: error while disconnecting: " + error.ToString ());
}
}
NetworkTransport.RemoveHost(hostId);
hostId = -1;
connectionId = -1;
isServer = false;
isClient = false;
}
void Update()
{
if (hostId == -1)
return;
int histBroadcastConnectionId;
int channelId;
int receivedSize;
int receivedHostId = -1;
int receivedConnectionId = -1;
byte error;
NetworkEventType networkEvent = NetworkEventType.DataEvent;
if (isClient) {
List<HostListData> removeList = new List<HostListData> ();
foreach (HostListData host in hostList) {
host.timeOut -= Time.deltaTime;
if (host.timeOut <= 0f) {
removeList.Add(host);
}
}
foreach (HostListData removeHost in removeList) {
hostList.Remove(removeHost);
hostListChanged = true;
}
}
do
{
if (isServer) {
networkEvent = NetworkTransport.Receive(out receivedHostId, out receivedConnectionId, out channelId, msgInBuffer, kMaxBroadcastMsgSize, out receivedSize, out error);
}
else {
networkEvent = NetworkTransport.ReceiveFromHost(hostId, out histBroadcastConnectionId, out channelId, msgInBuffer, kMaxBroadcastMsgSize, out receivedSize, out error);
}
if (error != 0) {
Debug.LogError(GetType() + ".Update: error while receiving from host: " + error.ToString());
}
int port;
ulong network;
ushort dstNode;
string info;
switch (networkEvent) {
case NetworkEventType.BroadcastEvent:
if (!isServer) {
NetworkTransport.GetBroadcastConnectionMessage(hostId, msgInBuffer, kMaxBroadcastMsgSize, out receivedSize, out error);
if (error != 0) {
Debug.LogError(GetType() + ".Update: error while getting broadcast connection message: " + error.ToString());
}
string senderAddr;
int senderPort;
NetworkTransport.GetBroadcastConnectionInfo(hostId, out senderAddr, out senderPort, out error);
if (error != 0) {
Debug.LogError(GetType() + ".Update: error while getting broadcast connection info: " + error.ToString());
}
OnReceivedBroadcast(senderAddr, senderPort, Utils.GetStringFromBytes(msgInBuffer));
}
break;
case NetworkEventType.ConnectEvent:
if (isServer) {
Debug.Log (GetType() + ".Update: Connected event on server.");
}
if (isClient) {
Debug.Log (GetType() + ".Update: Connected event on client.");
}
info = NetworkTransport.GetConnectionInfo(hostId, receivedConnectionId, out port, out network, out dstNode, out error);
if (error != 0) {
Debug.LogError(GetType() + ".Update: error while getting connection event info: " + ((NetworkError)error).ToString());
}
Debug.Log (GetType() + ".Update: connected: " + info + ", receivedHostId = " + receivedHostId + ", receivedConnectionId = " + receivedConnectionId + ", port = " + port + ", network = " + network + ", dstNode = " + dstNode);
break;
case NetworkEventType.DisconnectEvent:
if (isServer) {
Debug.Log (GetType() + ".Update: Disconnected event on server.");
}
if (isClient) {
Debug.Log (GetType() + ".Update: Disconnected event on client.");
}
info = NetworkTransport.GetConnectionInfo(hostId, receivedConnectionId, out port, out network, out dstNode, out error);
if (error != 0) {
Debug.LogError(GetType() + ".Update: error while getting disconnected event info: " + error.ToString());
}
Debug.Log (GetType() + ".Update: disconnected: " + info + ", receivedHostId = " + receivedHostId + ", receivedConnectionId = " + receivedConnectionId + ", port = " + port + ", network = " + network + ", dstNode = " + dstNode);
break;
}
} while (networkEvent != NetworkEventType.Nothing);
}
public virtual void OnReceivedBroadcast(string fromAddress, int port, string hostName)
{
Debug.Log(string.Format("Got broadcast from {0}: {1}:{2}", hostName, fromAddress, port.ToString()));
Debug.Log ("fromAddress = " + fromAddress + ", port = " + port);
bool serverListContainsNewServer = false;
foreach (HostListData host in hostList) {
if (host.ip == fromAddress) {
serverListContainsNewServer = true;
host.timeOut = hostListEntryTimeout;
Debug.Log("Refreshing existing server.");
}
}
if (!serverListContainsNewServer) {
Debug.Log("Adding new server to list.");
hostList.Add(new HostListData(fromAddress, port, hostName, hostListEntryTimeout));
hostListChanged = true;
}
}
public bool ConnectToHost(HostListData hostToConnect) {
if (!isClient) {
Debug.LogError(GetType() + ".ConnectToHost: only clients can connect.");
return false;
}
if (hostId < 0) {
Debug.LogError(GetType() + ".ConnectToHost: client has no host established.");
return false;
}
byte error;
Debug.Log (GetType () + ".ConnectToHost: trying to connect: " + hostToConnect.ip + ":" + hostToConnect.port);
connectionId = NetworkTransport.Connect (hostId, hostToConnect.ip, hostToConnect.port, 0, out error);
if (error != 0) {
Debug.LogError(GetType() + ".ConnectToHost: client could not connect: " + ((NetworkError)error).ToString());
return false;
}
if (connectionId < 0) {
Debug.LogError(GetType() + ".ConnectToHost: connectionId was wrong.");
return false;
}
Debug.Log (GetType () + ".ConnectToHost: successfully connected with id: " + connectionId);
return true;
}
public bool HostListChanged {
get {
return hostListChanged;
}
}
public List<HostListData> HostList {
get {
hostListChanged = false;
return hostList;
}
}
public static CustomNetworkManager Instance() {
if (!_instance) {
_instance = FindObjectOfType<CustomNetworkManager>();
}
if (!_instance) {
GameObject networkManagerPrefab = Resources.Load<GameObject>(networkManagerPrefabPath);
if (networkManagerPrefab) {
GameObject networkManagerObj = Instantiate(networkManagerPrefab);
_instance = networkManagerObj.GetComponent<CustomNetworkManager>();
if (!_instance) {
Debug.LogError(typeof(CustomNetworkManager).ToString() + ".Instance: prefab " + networkManagerPrefabPath + " had no " + typeof(CustomNetworkManager).ToString() + " component.");
}
}
else {
Debug.LogError(typeof(CustomNetworkManager).ToString() + ".Instance: did not find prefab in path: " + networkManagerPrefabPath);
}
}
return _instance;
}
}