I wanted to learn more about making multiplayer games so I started making a multiplayer game in Unity with UNet LLAPI but I have a problem with the API now. When I have one server where is one client connected to the server and then I try to connect to the same server with a second client the client will get connection ID 1 from the Connect() method. The server and the second client will receive Connect Event and the server will receive messages from the second client (as from a client with connection ID 2) but the second client won’t receive messages from the server.
I found this topic: LLAPI - ConnectionID of clients are the same where user ‘Two Ten’ posted this: ‘You gotta sync that yourself. From my experiance. The ConnectionId’s are not synced. So just add it to your connection flow.’ but I didn’t find anything about some connection ID syncing in the documentation about the API.
hmm let me explain logic here. Each peer (client or server doesn’t mater) has a table of connections:
Client A: Connections[3] = {-1,-1,-1}; //each slot in connections array keep internal data related to connections
Client B: Connections[3] = {-1, -1, -1};
Server" Connections[10] = {-1-1-1-1-1-1-1…);
So for now no connection established, then allow client a connect to server:
(Client A) int connectionId = Connect(server.ip); // connectionId == 1, A: Connections {1 -1 -1}, B: Connection {-1-1-1} Server: {-1-1-1-1-1…}
Server: ConnectionEvent = Receive( out connectionId )…; // ConnectionId == 1 A: Connections {1 -1 -1} B: Connection {-1-1-1} Server: {1-1-1-1-1…}
now client B will connect to server
(Client B) int connectionId = Connect(server.ip); // connectionId == 1, A: Connections {1 -1 -1}, B: Connection {1-1-1} Server: {1-1-1-1-1…}
Server: ConnectionEvent = Receive( out connectionId )…; // ConnectionId == 2 A: Connections {1 -1 -1} B: Connection {1-1-1} Server: {1,1-1-1-1…}
Other words for each client server will be represented by ConnectionId == 1, On server side Connection A will be represented by Connection = 1 and B by connectionId =2.
From each client you can send messages only to the peer which has been already connected and You know its connection id.
So from client A, B you can send by Send(servrConnectionId (==1 for A and B)…),
from server to client A Send (connectionA (==1) …)
from server to client B Send(connection(==2)…)
and there is no way to send message from Client A to Client B directly, as there is no direct connection between them.
Note: that you can send messages if connection has been already connected, so for client A for ex:
conn = Connect();;
evn = Receive(recvConnection, error)
switch evn
case ConnectEvent:
if(conn == recvConnection); //connection established you can send after that
case DisconnecEvnt:
if(conn == recvConnection); //connection NOT established check error to understand possible reason
Thank you a lot! This is very helpful. But in your list on the second #2 point you’re saying:
I thought that server’s Connections[10] array should be {1,2,-1,-1,-1,…} or did I miss any of your points?
Also when I am sending a message from a server to second connected client I’ll get Network.Error 2 or by the UNET documentation: “The specified connectionId doesn’t exist.” (https://docs.unity3d.com/ScriptReference/Networking.NetworkError.WrongConnection.html). Any ideas what could go wrong?
You don’t miss the point, I just mean Connection[1], Connection[2] and values inside {} show that this slot has been already occupied. Actually, it will looks like
On Server:
Connection[1] =
{
ip = 127.0.0.1
port = 5256
dstConnId = 1
}
Connection[2] =
{
ip = 192.46.50.64
port = 4567
dstConnId = 1
}
Take a look while indexes in the array are different in our particular case dstConnectionId will be 1 for both connections, and message from server to client will have header
srcId = 2
dstId = 1
When client will receive this message it will know that this message come from connection Id == 1, and on sender this connection has id = 2, so if server has address 192.157.196.35:5000 message from client will be
to 192.157.196.35:5000
srcId = 1
dstId = 2
Ok question #2.
You should know that both connection are connected, so before send any message you MUST receive connection event for each peer which you are want to sending messages. Typical errors here are
Users do not wait for connection event and started send messages immediately like:
id = Connect();
Send(id…) //WRONG! you should receive connection event first to be confirmed that connection has been already established, or disconnect event which will tell you that this connection cannot be established…
Users are trying to start more than one client and provide port for them. Usually in client/server model, only server should have predefined port.
Thank your for explaining. I spotted a mistake that I made with my method of sending messages from a server to clients. When I am sending a message from a server to client I am doing it through method that I called ‘SendClient’. In the method there is method from the UNET library called NetworkTransport.Send(int hostID, int connectionID, int channelID, byte[ ] buffer, int size, out byte error). In my game server and client have differed variables for hostID and channelID but I was using client’s variables for hostID and channelID when I was sending messages from server to clients. The problem is solved. Now I’ll fix some bugs that remained.