I’ve remake may whole netcode with the new Unet API.
But now there is a problem, The game disappers form the matchmaking list and connected clients will also disconnected because of a Timeout, but the server is still running:
I’ve tested like this:
Server and host on the same machine (Unity Editor + Build).
should there additonal options or is this a bug in Unity?
what is needed to tell unity to not use a relay server?
edit:
is there a way to use the matchmaking system more like the old masterserver system?
I have tested the situation:
2players (1 host and 1 client) can idle around and doing nothing then standing around, but if the players do something (spawning objects, moving around) the timeout comes.
But i need to transfer the data to have the multiplayer experience.
Wireshark output has an avg packet size 60 between 180 bit with some rare peaks with 600 between 800.
I use to have this problem with my networking package Cross.Net, The fix for it is simple you have to ready the connection for the player connecting to the game. Everyone that joins should ask ClientScene.Ready this will fix your issue…
from here you can register more handlers and have .Ready when the client becomes ready notify that method. you can have .AddPlayer that way when the client request to add the player for connection it will notify that method also… Hope this helps
Thats not the case, If you looked above at post #11 he is making too many connections,
sebieisdrache, You need to do it in this order /Ready the connection only once, I highly recommend making the connection after the scene change / Then you need to Add the player for the connection after you have done this you should request the server to instantiate your player. If all was done right then you should be good to go.
Also try to do a simple connection before trying to integrate the whole project over. I found it easier to understand by doing this.
I’m using the unity Networkmanger wich do the ready states by it self when spawning a player.
Maybe i reach the Bandwidth limit (I cant figure it out, because i don’t have the Pro version), but I need these bandwidth like syncing multipe inventorys (lists of items) on different events (wich is working).
Then sending the active player equipment to each client who joins later.
Also I need to sync (syncVar) multiple variables like stamina, health, hydration and much more.
All functions had worked well with the old networking system (no bandwith limit?) and they working well now with the new system but there are timeouts.
Is there a way to increase the bandwith limit or acting like the old master server system(when the relay sever causes the limits)
edit:
why is there a hidden bandwith limit? I dont want to make a “Mobile Game”
It can join match, and connect between server and client.
However, I got a timeout error after few seconds.
I don’t think it’s caused by bandwidth limit, but I have no idea…
Here is an example that i am using in Cross.Net, There was more involved i stripped as much as I could…
To create a match with localHost / Server combination you would run
CreateMatch();
this will setup the server / local host
to connect a client to the localhost / server
ConnectToMatch();
public void ConnectToMatch()
{
client.Connect (someIP, somePort));
ClientCallBacks ();
}
//LocalHost / Server combination
public void CreateMatch()
{
//Start the server
NetworkServer.Listen(SomePort);
//Register ServerCallBacks
ServerCallBacks ();
//Register the game prefabs
foreach(GameObject i in gameBehaviour.registerPrefabs)
ClientScene.RegisterPrefab(i);
//Create a local client on the created server
client = ClientScene.ConnectLocalServer();
//RegisterCallBacks
ClientCallBacks ();
}
//When a client connects the server will fire SConnect <-- as the player has connected''
void ServerCallBacks ()
{
NetworkServer.RegisterHandler(MsgType.Connect, SConnect) ;
NetworkServer.RegisterHandler (MsgType.Disconnect, SDisconnect);
NetworkServer.RegisterHandler (MsgType.Ready, SReady);
NetworkServer.RegisterHandler(MsgType.AddPlayer, SAddPlayer);
NetworkServer.RegisterHandler((short)1000, new NetworkMessageDelegate(SetupPrefab));
NetworkServer.RegisterHandler((short)1001, new NetworkMessageDelegate(AffirmConnection));
}
//The Client will also fire a CConnect <-- as the client has connected to the server
//after this is done we want to run ClientScene.Ready within the CConnect..
//from here the server will receive a message from the client SReady
//Inside SReady we send a message to the client AffirmConnection as I have found
//that if you AddPlayerForConnection Right after ready the server misses this and doesnt
//actually add teh player.
void ClientCallBacks ()
{
client.RegisterHandler(MsgType.Connect, CConnect);
client.RegisterHandler(MsgType.Disconnect, CDisconnect);
client.RegisterHandler (MsgType.Ready,CReady);
client.RegisterHandler((short)1001, new NetworkMessageDelegate(AffirmConnection));
}
void SConnect(NetworkMessage msg)
{
try
{
gameBehaviour.connectionCallback.SendMessage ("CrossNetMsg","Server: PlayerConnected");
}catch{
DebugMessages (" Please make a reference to CrossNetMsg: public void CrossNetMsg(string msg){ do stuff..}");
}
}
void SDisconnect(NetworkMessage msg)
{
network_connections--;
NetworkServer.DestroyPlayersForConnection (msg.conn);
try
{
gameBehaviour.connectionCallback.SendMessage ("CrossNetMsg","Server: PlayerDisconnected");
}catch{
DebugMessages (" Please make a reference to CrossNetMsg: public void CrossNetMsg(string msg){ do stuff..}");
}
}
void SAddPlayer(NetworkMessage msg)
{
try
{
gameBehaviour.connectionCallback.SendMessage ("CrossNetMsg","Server: AddedPlayer");
}catch{
DebugMessages (" Please make a reference to CrossNetMsg: public void CrossNetMsg(string msg){ do stuff..}");
}
}
void SReady(NetworkMessage msg)
{
NetworkServer.SendToClient(msg.conn.connectionId,(short)1001,(MessageBase)new StringMessage ("Connected"));
try
{
gameBehaviour.connectionCallback.SendMessage ("CrossNetMsg","Server: PlayerReady");
}catch{
DebugMessages (" Please make a reference to CrossNetMsg: public void CrossNetMsg(string msg){ do stuff..}");
}
}
void CAddPlayer(NetworkMessage msg)
{
try
{
gameBehaviour.connectionCallback.SendMessage ("CrossNetMsg","Client: Requested Add Player");
}catch{
DebugMessages (" Please make a reference to CrossNetMsg: public void CrossNetMsg(string msg){ do stuff..}");
}
}
void CReady(NetworkMessage msg)
{
try
{
gameBehaviour.connectionCallback.SendMessage ("CrossNetMsg","Client: PlayerReady");
}catch{
DebugMessages (" Please make a reference to CrossNetMsg: public void CrossNetMsg(string msg){ do stuff..}");
}
void CConnect(NetworkMessage msg)
{
ClientScene.Ready(client.connection);
}
void CDisconnect(NetworkMessage msg)
{
try
{
gameBehaviour.connectionCallback.SendMessage ("CrossNetMsg","Client: Disconnected");
}catch{
DebugMessages (" Please make a reference to CrossNetMsg: public void CrossNetMsg(string msg){ do stuff..}");
}
//This is where the client recieves a message from the server SReady
//I noticed without this if you try to Add A Player for connection sometimes it fails
//as the client wasnt properly ready inside this Handler you would run the
//Add player for connection..
void AffirmConnection(NetworkMessage msg)
{
try
{
gameBehaviour.connectionCallback.SendMessage("CrossNetMsg", "Client: PlayerConnected");
}
catch
{
DebugMessages(" Please make a reference to CrossNetMsg: public void CrossNetMsg(string msg){ do stuff..}");
}
}
}
The above code became out of format due to trying to copy and paste around most of the Cross.Net code stuff. Hopefully this will make sense.
I found that sending messages Server and Client each other, it can prevents ‘UNet Client Disconnect Error: Timeout’.
Do I have to send keep alive messages when using Unity’s match maker?
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.Types;
using UnityEngine.Networking.Match;
using System.Collections.Generic;
public class HostGame : MonoBehaviour
{
List<MatchDesc> matchList = new List<MatchDesc>();
bool matchCreated;
NetworkMatch networkMatch;
NetworkClient myClient = null;
string label = "";
int cnt = 0;
class Message : MessageBase
{
public uint s;
// This method would be generated
public override void Deserialize(NetworkReader reader)
{
s = reader.ReadPackedUInt32();
}
// This method would be generated
public override void Serialize(NetworkWriter writer)
{
writer.WritePackedUInt32(s);
}
}
void Awake()
{
networkMatch = gameObject.AddComponent<NetworkMatch>();
}
void OnGUI()
{
GUI.Label (new Rect (100, 100, 100, 100), label + cnt);
// You would normally not join a match you created yourself but this is possible here for demonstration purposes.
if(GUILayout.Button("Create Room"))
{
CreateMatchRequest create = new CreateMatchRequest();
create.name = "NewRoom";
create.size = 4;
create.advertise = true;
create.password = "";
networkMatch.CreateMatch(create, OnMatchCreate);
}
if (GUILayout.Button("List rooms"))
{
networkMatch.ListMatches(0, 20, "", OnMatchList);
}
if (matchList.Count > 0)
{
GUILayout.Label("Current rooms");
}
foreach (var match in matchList)
{
if (GUILayout.Button(match.name))
{
networkMatch.JoinMatch(match.networkId, "", OnMatchJoined);
}
}
}
public void OnMatchCreate(CreateMatchResponse matchResponse)
{
if (matchResponse.success)
{
Debug.Log("Create match succeeded");
matchCreated = true;
Utility.SetAccessTokenForNetwork(matchResponse.networkId, new NetworkAccessToken(matchResponse.accessTokenString));
NetworkServer.RegisterHandler(MsgType.Connect, SOnConnected);
NetworkServer.RegisterHandler(1002, SOn1002);
NetworkServer.Listen(new MatchInfo(matchResponse), 9000);
}
else
{
Debug.LogError ("Create match failed");
}
}
public void OnMatchList(ListMatchResponse matchListResponse)
{
if (matchListResponse.success && matchListResponse.matches != null)
{
networkMatch.JoinMatch(matchListResponse.matches[0].networkId, "", OnMatchJoined);
}
}
public void OnMatchJoined(JoinMatchResponse matchJoin)
{
if (matchJoin.success)
{
Debug.Log("Join match succeeded");
if (matchCreated)
{
Debug.LogWarning("Match already set up, aborting...");
return;
}
Utility.SetAccessTokenForNetwork(matchJoin.networkId, new NetworkAccessToken(matchJoin.accessTokenString));
myClient = new NetworkClient();
myClient.RegisterHandler(MsgType.Connect, COnConnected);
myClient.RegisterHandler(1001, COn1001);
myClient.Connect(new MatchInfo(matchJoin));
}
else
{
Debug.LogError("Join match failed");
}
}
public void SOnConnected(NetworkMessage msg)
{
Debug.Log("S:Connected!");
NetworkServer.SetClientReady (msg.conn);
var m = new Message ();
m.s = 1001;
NetworkServer.SendToClient (msg.conn.connectionId, 1001, m);
label = "server";
}
public void SOn1002(NetworkMessage msg)
{
Debug.Log("S:1002!");
var m = new Message ();
m.s = 1001;
NetworkServer.SendToClient (msg.conn.connectionId, 1001, m);
++cnt;
}
public void COnConnected(NetworkMessage msg)
{
Debug.Log("C:Connected!");
label = "client";
}
public void COn1001(NetworkMessage msg)
{
++cnt;
Debug.Log("C:1001!");
var m = new Message ();
m.s = 1002;
myClient.Send(1002, m);
}
}
sebeisdrache, sorry to interrupt your thread.
LevonRavel, thank you for your response.
I have not used Unity’s MatchMaker, I would assume it would work in a same manner as the Crossnet example, Looking at your code seems like you might have already looked at a portion of the Crossnet manager. MatchMaker in that case might be different. Hopefully someone can get back to your posting as I am unable to help with this subject…