This commit is contained in:
mischa 2024-07-04 09:59:24 +02:00
parent 49ad787d7c
commit 3cbaa58caf
23 changed files with 119 additions and 78 deletions

View File

@ -12,9 +12,7 @@ public class LocalConnectionToClient : NetworkConnectionToClient
// packet queue
internal readonly Queue<NetworkWriterPooled> queue = new Queue<NetworkWriterPooled>();
public LocalConnectionToClient() : base(LocalConnectionId) {}
public override string address => "localhost";
public LocalConnectionToClient() : base(LocalConnectionId, "localhost") {}
internal override void Send(ArraySegment<byte> segment, int channelId = Channels.Reliable)
{

View File

@ -7,6 +7,8 @@ namespace Mirror
{
public class NetworkConnectionToClient : NetworkConnection
{
// connection address, passed from transport
// rpcs are collected in a buffer, and then flushed out together.
// this way we don't need one NetworkMessage per rpc.
// => prepares for LocalWorldState as well.
@ -14,7 +16,7 @@ public class NetworkConnectionToClient : NetworkConnection
readonly NetworkWriter reliableRpcs = new NetworkWriter();
readonly NetworkWriter unreliableRpcs = new NetworkWriter();
public virtual string address => Transport.active.ServerGetClientAddress(connectionId);
public string address { get; private set; }
/// <summary>NetworkIdentities that this connection can see</summary>
// TODO move to server's NetworkConnectionToClient?
@ -50,9 +52,29 @@ public class NetworkConnectionToClient : NetworkConnection
/// <summary>Round trip time (in seconds) that it takes a message to go server->client->server.</summary>
public double rtt => _rtt.Value;
public NetworkConnectionToClient(int networkConnectionId, string address)
: base(networkConnectionId)
{
this.address = address;
// initialize EMA with 'emaDuration' seconds worth of history.
// 1 second holds 'sendRate' worth of values.
// multiplied by emaDuration gives n-seconds.
driftEma = new ExponentialMovingAverage(NetworkServer.sendRate * NetworkClient.snapshotSettings.driftEmaDuration);
deliveryTimeEma = new ExponentialMovingAverage(NetworkServer.sendRate * NetworkClient.snapshotSettings.deliveryTimeEmaDuration);
// buffer limit should be at least multiplier to have enough in there
snapshotBufferSizeLimit = Mathf.Max((int)NetworkClient.snapshotSettings.bufferTimeMultiplier, snapshotBufferSizeLimit);
}
// keep the old contstructor for a while in order to not break all projects.
// DEPRECATED 2024-05-16
[Obsolete("'new NetworkConnection(connectionId)' constructor was changed to 'new NetworkConnection(connectionId, address)'")]
public NetworkConnectionToClient(int networkConnectionId)
: base(networkConnectionId)
{
this.address = Transport.active.ServerGetClientAddress(connectionId);
// initialize EMA with 'emaDuration' seconds worth of history.
// 1 second holds 'sendRate' worth of values.
// multiplied by emaDuration gives n-seconds.

View File

@ -634,8 +634,9 @@ public static void SendToReadyObservers<T>(NetworkIdentity identity, T message,
}
// transport events ////////////////////////////////////////////////////
// called by transport
static void OnTransportConnected(int connectionId)
// called by transport.
// address is the (IP) address without port. useful for IP bans etc.
static void OnTransportConnected(int connectionId, string address)
{
// Debug.Log($"Server accepted client:{connectionId}");
@ -665,7 +666,7 @@ static void OnTransportConnected(int connectionId)
if (connections.Count < maxConnections)
{
// add connection
NetworkConnectionToClient conn = new NetworkConnectionToClient(connectionId);
NetworkConnectionToClient conn = new NetworkConnectionToClient(connectionId, address);
OnConnected(conn);
}
else

View File

@ -3,6 +3,9 @@
// Connecting:
// * Transports are responsible to call either OnConnected || OnDisconnected
// in a certain time after a Connect was called. It can not end in limbo.
// * OnConnected should always pass the connection address.
// This makes threaded transports easier.
// Otherwise we would need to keep a main thread connections copy.
//
// Disconnecting:
// * Connections might disconnect voluntarily by the other end.
@ -67,7 +70,8 @@ public abstract class Transport : MonoBehaviour
// server //////////////////////////////////////////////////////////////
/// <summary>Called by Transport when a new client connected to the server.</summary>
public Action<int> OnServerConnected;
// parameters: <connectionId, address> to pass address directly instead of having a separate ServerGetClientAddress() function.
public Action<int, string> OnServerConnected;
/// <summary>Called by Transport when the server received a message from a client.</summary>
public Action<int, ArraySegment<byte>, int> OnServerDataReceived;
@ -131,6 +135,8 @@ public virtual void ClientConnect(Uri uri)
/// <summary>Get a client's address on the server.</summary>
// Can be useful for Game Master IP bans etc.
// DEPRECATED 2024-05-16
[Obsolete("Transport.ServerGetClientAddress() was deprecated. Each connection's address is now passed only once in OnServerConnected instead.")]
public abstract string ServerGetClientAddress(int connectionId);
/// <summary>Stop listening and disconnect all connections.</summary>

View File

@ -4,8 +4,7 @@ namespace Mirror.Tests
{
public class FakeNetworkConnectionToClient : NetworkConnectionToClient
{
public FakeNetworkConnectionToClient() : base(1) {}
public override string address => "Test";
public FakeNetworkConnectionToClient() : base(1, "localhost") {}
public override void Disconnect() {}
internal override void Send(ArraySegment<byte> segment, int channelId = 0) {}
}

View File

@ -201,7 +201,7 @@ public override void ServerEarlyUpdate()
case EventType.Connected:
Debug.Log("MemoryTransport Server Message: Connected");
// event might be null in tests if no NetworkClient is used.
OnServerConnected?.Invoke(message.connectionId);
OnServerConnected?.Invoke(message.connectionId, "localhost");
break;
case EventType.Data:
Debug.Log($"MemoryTransport Server Message: Data: {BitConverter.ToString(message.data)}");

View File

@ -21,7 +21,7 @@ public override void SetUp()
// A with connectionId = 0x0A, netId = 0xAA
CreateNetworked(out gameObjectA, out identityA);
connectionA = new NetworkConnectionToClient(0x0A);
connectionA = new NetworkConnectionToClient(0x0A, "");
connectionA.isAuthenticated = true;
connectionA.isReady = true;
connectionA.identity = identityA;
@ -29,7 +29,7 @@ public override void SetUp()
// B
CreateNetworked(out gameObjectB, out identityB);
connectionB = new NetworkConnectionToClient(0x0B);
connectionB = new NetworkConnectionToClient(0x0B, "");
connectionB.isAuthenticated = true;
connectionB.isReady = true;
connectionB.identity = identityB;

View File

@ -34,7 +34,7 @@ public override void TearDown()
public void Send_BatchesUntilUpdate()
{
// create connection and send
NetworkConnectionToClient connection = new NetworkConnectionToClient(42);
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, "");
NetworkTime.PingInterval = float.MaxValue; // disable ping for this test
byte[] message = {0x01, 0x02};
connection.Send(new ArraySegment<byte>(message));
@ -63,7 +63,7 @@ public void SendBatchingResetsPreviousWriter()
const int BatchHeader = 8;
// create connection
NetworkConnectionToClient connection = new NetworkConnectionToClient(42);
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, "");
NetworkTime.PingInterval = float.MaxValue; // disable ping for this test
// send and update big message

View File

@ -123,11 +123,11 @@ public void RemoveObserver()
identity.OnStartServer();
// add an observer connection
NetworkConnectionToClient connection = new NetworkConnectionToClient(42);
NetworkConnectionToClient connection = new NetworkConnectionToClient(42, "");
identity.observers[connection.connectionId] = connection;
// RemoveObserver with invalid connection should do nothing
identity.RemoveObserver(new NetworkConnectionToClient(43));
identity.RemoveObserver(new NetworkConnectionToClient(43, ""));
Assert.That(identity.observers.Count, Is.EqualTo(1));
// RemoveObserver with existing connection should remove it
@ -324,7 +324,7 @@ public void AssignAndRemoveClientAuthority()
// another connection
// error log is expected
LogAssert.ignoreFailingMessages = true;
result = identity.AssignClientAuthority(new NetworkConnectionToClient(43));
result = identity.AssignClientAuthority(new NetworkConnectionToClient(43, ""));
LogAssert.ignoreFailingMessages = false;
Assert.That(result, Is.False);
Assert.That(identity.connectionToClient, Is.EqualTo(owner));
@ -552,8 +552,8 @@ public void AddObserver()
CreateNetworked(out GameObject _, out NetworkIdentity identity);
// create some connections
NetworkConnectionToClient connection1 = new NetworkConnectionToClient(42);
NetworkConnectionToClient connection2 = new NetworkConnectionToClient(43);
NetworkConnectionToClient connection1 = new NetworkConnectionToClient(42, "");
NetworkConnectionToClient connection2 = new NetworkConnectionToClient(43, "");
// call AddObservers
identity.AddObserver(connection1);
@ -565,7 +565,7 @@ public void AddObserver()
Assert.That(identity.observers[connection2.connectionId], Is.EqualTo(connection2));
// adding a duplicate connectionId shouldn't overwrite the original
NetworkConnectionToClient duplicate = new NetworkConnectionToClient(connection1.connectionId);
NetworkConnectionToClient duplicate = new NetworkConnectionToClient(connection1.connectionId, "");
identity.AddObserver(duplicate);
Assert.That(identity.observers.Count, Is.EqualTo(2));
Assert.That(identity.observers.ContainsKey(connection1.connectionId));
@ -583,8 +583,8 @@ public void ClearObservers()
identity.OnStartServer();
// add some observers
identity.observers[42] = new NetworkConnectionToClient(42);
identity.observers[43] = new NetworkConnectionToClient(43);
identity.observers[42] = new NetworkConnectionToClient(42, "");
identity.observers[43] = new NetworkConnectionToClient(43, "");
// call ClearObservers
identity.ClearObservers();
@ -632,9 +632,9 @@ public void ResetState()
identity.isClient = true;
// creates .observers and generates a netId
identity.OnStartServer();
identity.connectionToClient = new NetworkConnectionToClient(1);
identity.connectionToClient = new NetworkConnectionToClient(1, "");
identity.connectionToServer = new NetworkConnectionToServer();
identity.observers[43] = new NetworkConnectionToClient(2);
identity.observers[43] = new NetworkConnectionToClient(2, "");
// mark for reset and reset
identity.ResetState();

View File

@ -67,11 +67,11 @@ public void MaxConnections()
Assert.That(NetworkServer.connections.Count, Is.EqualTo(0));
// connect first: should work
transport.OnServerConnected.Invoke(42);
transport.OnServerConnected.Invoke(42, "");
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
// connect second: should fail
transport.OnServerConnected.Invoke(43);
transport.OnServerConnected.Invoke(43, "");
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
}
@ -84,7 +84,7 @@ public void OnConnectedEventCalled()
// listen & connect
NetworkServer.Listen(1);
transport.OnServerConnected.Invoke(42);
transport.OnServerConnected.Invoke(42, "");
Assert.That(connectCalled, Is.True);
}
@ -97,7 +97,7 @@ public void OnDisconnectedEventCalled()
// listen & connect
NetworkServer.Listen(1);
transport.OnServerConnected.Invoke(42);
transport.OnServerConnected.Invoke(42, "");
// disconnect
transport.OnServerDisconnected.Invoke(42);
@ -112,12 +112,12 @@ public void ConnectionsDict()
Assert.That(NetworkServer.connections.Count, Is.EqualTo(0));
// connect first
transport.OnServerConnected.Invoke(42);
transport.OnServerConnected.Invoke(42, "");
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
Assert.That(NetworkServer.connections.ContainsKey(42), Is.True);
// connect second
transport.OnServerConnected.Invoke(43);
transport.OnServerConnected.Invoke(43, "");
Assert.That(NetworkServer.connections.Count, Is.EqualTo(2));
Assert.That(NetworkServer.connections.ContainsKey(43), Is.True);
@ -144,7 +144,7 @@ public void OnConnectedOnlyAllowsNonZeroConnectionIds()
// connect with connectionId == 0 should fail
// (it will show an error message, which is expected)
LogAssert.ignoreFailingMessages = true;
transport.OnServerConnected.Invoke(0);
transport.OnServerConnected.Invoke(0, "");
Assert.That(NetworkServer.connections.Count, Is.EqualTo(0));
LogAssert.ignoreFailingMessages = false;
}
@ -156,12 +156,12 @@ public void ConnectDuplicateConnectionIds()
NetworkServer.Listen(2);
// connect first
transport.OnServerConnected.Invoke(42);
transport.OnServerConnected.Invoke(42, "");
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
NetworkConnectionToClient original = NetworkServer.connections[42];
// connect duplicate - shouldn't overwrite first one
transport.OnServerConnected.Invoke(42);
transport.OnServerConnected.Invoke(42, "");
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
Assert.That(NetworkServer.connections[42], Is.EqualTo(original));
}
@ -230,13 +230,13 @@ public void AddConnection()
NetworkServer.Listen(1);
// add first connection
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42);
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42, "");
Assert.That(NetworkServer.AddConnection(conn42), Is.True);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
Assert.That(NetworkServer.connections[42], Is.EqualTo(conn42));
// add second connection
NetworkConnectionToClient conn43 = new NetworkConnectionToClient(43);
NetworkConnectionToClient conn43 = new NetworkConnectionToClient(43, "");
Assert.That(NetworkServer.AddConnection(conn43), Is.True);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(2));
Assert.That(NetworkServer.connections[42], Is.EqualTo(conn42));
@ -250,13 +250,13 @@ public void AddConnection_PreventsDuplicates()
NetworkServer.Listen(1);
// add a connection
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42);
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42, "");
Assert.That(NetworkServer.AddConnection(conn42), Is.True);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
Assert.That(NetworkServer.connections[42], Is.EqualTo(conn42));
// add duplicate connectionId
NetworkConnectionToClient connDup = new NetworkConnectionToClient(42);
NetworkConnectionToClient connDup = new NetworkConnectionToClient(42, "");
Assert.That(NetworkServer.AddConnection(connDup), Is.False);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
Assert.That(NetworkServer.connections[42], Is.EqualTo(conn42));
@ -269,7 +269,7 @@ public void RemoveConnection()
NetworkServer.Listen(1);
// add connection
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42);
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42, "");
Assert.That(NetworkServer.AddConnection(conn42), Is.True);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
@ -285,7 +285,7 @@ public void DisconnectAllTest_RemoteConnection()
NetworkServer.Listen(1);
// add connection
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42);
NetworkConnectionToClient conn42 = new NetworkConnectionToClient(42, "");
NetworkServer.AddConnection(conn42);
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));

View File

@ -298,7 +298,7 @@ public void TestClientExceptionCallback()
public void TestServerConnectedCallback(int id)
{
int called = 0;
middleware.OnServerConnected = (i) =>
middleware.OnServerConnected = (i, addr) =>
{
called++;
Assert.That(i, Is.EqualTo(id));
@ -306,10 +306,10 @@ public void TestServerConnectedCallback(int id)
// start to give callback to inner
middleware.ServerStart();
inner.OnServerConnected.Invoke(id);
inner.OnServerConnected.Invoke(id, "");
Assert.That(called, Is.EqualTo(1));
inner.OnServerConnected.Invoke(id);
inner.OnServerConnected.Invoke(id, "");
Assert.That(called, Is.EqualTo(2));
}

View File

@ -238,7 +238,7 @@ public void TestServerConnected()
ArraySegment<byte> segment = new ArraySegment<byte>(data);
// on connect, send a message back
void SendMessage(int connectionId)
void SendMessage(int connectionId, string address)
{
transport.ServerSend(connectionId, segment, 5);
}
@ -247,7 +247,7 @@ void SendMessage(int connectionId)
transport.OnServerConnected = SendMessage;
transport.ServerStart();
transport1.OnServerConnected.Invoke(1);
transport1.OnServerConnected.Invoke(1, "");
transport1.Received().ServerSend(1, segment, 5);
}
@ -260,14 +260,14 @@ public void TestServerSend()
transport.ServerStart();
transport.ClientConnect("some.server.com");
transport.OnServerConnected = _ => {};
transport.OnServerConnected = (connId, address) => {};
transport.OnServerDisconnected = _ => {};
// connect two connectionIds.
// one of them very large to prevent
// https://github.com/vis2k/Mirror/issues/3280
transport1.OnServerConnected(10);
transport2.OnServerConnected(int.MaxValue);
transport1.OnServerConnected(10, "");
transport2.OnServerConnected(int.MaxValue, "");
byte[] data = { 1, 2, 3 };
ArraySegment<byte> segment = new ArraySegment<byte>(data);

View File

@ -95,7 +95,7 @@ public IEnumerator DisconnectTimeoutTest()
NetworkServer.disconnectInactiveTimeout = 1;
GameObject remotePlayer = new GameObject("RemotePlayer", typeof(NetworkIdentity));
NetworkConnectionToClient remoteConnection = new NetworkConnectionToClient(1);
NetworkConnectionToClient remoteConnection = new NetworkConnectionToClient(1, "localhost");
NetworkServer.OnConnected(remoteConnection);
NetworkServer.AddPlayerForConnection(remoteConnection, remotePlayer);

View File

@ -28,7 +28,7 @@ public class EdgegapKcpServer : KcpServer
bool relayActive;
public EdgegapKcpServer(
Action<int> OnConnected,
Action<int, IPEndPoint> OnConnected,
Action<int, ArraySegment<byte>, KcpChannel> OnData,
Action<int> OnDisconnected,
Action<int, ErrorCode, string> OnError,

View File

@ -60,7 +60,7 @@ protected override void Awake()
// server
server = new EdgegapKcpServer(
(connectionId) => OnServerConnected.Invoke(connectionId),
(connectionId, endPoint) => OnServerConnected.Invoke(connectionId, endPoint.PrettyAddress()),
(connectionId, message, channel) => OnServerDataReceived.Invoke(connectionId, message, FromKcpChannel(channel)),
(connectionId) => OnServerDisconnected.Invoke(connectionId),
(connectionId, error, reason) => OnServerError.Invoke(connectionId, ToTransportError(error), reason),

View File

@ -76,7 +76,7 @@ private void HandleInnerServerDataReceived(int connId, ArraySegment<byte> data,
}
}
private void HandleInnerServerConnected(int connId)
private void HandleInnerServerConnected(int connId, string address)
{
Debug.Log($"[EncryptionTransport] New connection #{connId}");
EncryptedConnection ec = null;
@ -89,7 +89,7 @@ private void HandleInnerServerConnected(int connId)
{
Debug.Log($"[EncryptionTransport] Connection #{connId} is ready");
ServerRemoveFromPending(ec);
OnServerConnected?.Invoke(connId);
OnServerConnected?.Invoke(connId, address);
},
(type, msg) =>
{

View File

@ -122,7 +122,7 @@ protected virtual void Awake()
// server
server = new KcpServer(
(connectionId) => OnServerConnected.Invoke(connectionId),
(connectionId, endPoint) => OnServerConnected.Invoke(connectionId, endPoint.PrettyAddress()),
(connectionId, message, channel) => OnServerDataReceived.Invoke(connectionId, message, FromKcpChannel(channel)),
(connectionId) => OnServerDisconnected.Invoke(connectionId),
(connectionId, error, reason) => OnServerError.Invoke(connectionId, ToTransportError(error), reason),

View File

@ -18,7 +18,7 @@ public class KcpServer
// events are readonly, set in constructor.
// this ensures they are always initialized when used.
// fixes https://github.com/MirrorNetworking/Mirror/issues/3337 and more
protected readonly Action<int> OnConnected;
protected readonly Action<int, IPEndPoint> OnConnected; // connectionId, address
protected readonly Action<int, ArraySegment<byte>, KcpChannel> OnData;
protected readonly Action<int> OnDisconnected;
protected readonly Action<int, ErrorCode, string> OnError;
@ -43,7 +43,7 @@ public class KcpServer
public Dictionary<int, KcpServerConnection> connections =
new Dictionary<int, KcpServerConnection>();
public KcpServer(Action<int> OnConnected,
public KcpServer(Action<int, IPEndPoint> OnConnected,
Action<int, ArraySegment<byte>, KcpChannel> OnData,
Action<int> OnDisconnected,
Action<int, ErrorCode, string> OnError,
@ -184,6 +184,7 @@ public void Disconnect(int connectionId)
}
// expose the whole IPEndPoint, not just the IP address. some need it.
[Obsolete("KcpServer.GetClientEndPoint() isn't needed anymore. Connection endpoints are now passed in the KcpServer.OnConnected event in order to make threaded transports easier.")]
public IPEndPoint GetClientEndPoint(int connectionId)
{
if (connections.TryGetValue(connectionId, out KcpServerConnection connection))
@ -285,7 +286,8 @@ void OnConnectedCallback(KcpServerConnection conn)
// finally, call mirror OnConnected event
Log.Info($"[KCP] Server: OnConnected({connectionId})");
OnConnected(connectionId);
IPEndPoint endPoint = conn.remoteEndPoint as IPEndPoint;
OnConnected(connectionId, endPoint);
}
void OnDisconnectedCallback()

View File

@ -261,12 +261,12 @@ void AddServerCallbacks()
int transportIndex = i;
Transport transport = transports[i];
transport.OnServerConnected = (originalConnectionId =>
transport.OnServerConnected = (originalConnectionId, originalAddress) =>
{
// invoke Multiplex event with multiplexed connectionId
int multiplexedId = AddToLookup(originalConnectionId, transportIndex);
OnServerConnected.Invoke(multiplexedId);
});
OnServerConnected.Invoke(multiplexedId, originalAddress);
};
transport.OnServerDataReceived = (originalConnectionId, data, channel) =>
{

View File

@ -6,7 +6,7 @@ namespace Mirror.SimpleWeb
{
public class SimpleWebServer
{
public event Action<int> onConnect;
public event Action<int, string> onConnect; // connectionId, address
public event Action<int> onDisconnect;
public event Action<int, ArraySegment<byte>> onData;
public event Action<int, Exception> onError;
@ -91,7 +91,8 @@ public void ProcessMessageQueue(MonoBehaviour behaviour)
switch (next.type)
{
case EventType.Connected:
onConnect?.Invoke(next.connId);
string address = GetClientAddress(next.connId);
onConnect?.Invoke(next.connId, address);
break;
case EventType.Data:
onData?.Invoke(next.connId, next.data.ToSegment());

View File

@ -11,7 +11,7 @@ public class Server : Common
{
// events to hook into
// => OnData uses ArraySegment for allocation free receives later
public Action<int> OnConnected;
public Action<int, IPEndPoint> OnConnected; // connectionId, IPEndPoint
public Action<int, ArraySegment<byte>> OnData;
public Action<int> OnDisconnected;
@ -316,16 +316,16 @@ public bool Send(int connectionId, ArraySegment<byte> message)
}
// client's ip is sometimes needed by the server, e.g. for bans
public string GetClientAddress(int connectionId)
IPEndPoint GetClientEndPoint(int connectionId)
{
try
{
// find the connection
if (clients.TryGetValue(connectionId, out ConnectionState connection))
{
return ((IPEndPoint)connection.client.Client.RemoteEndPoint).Address.ToString();
return (IPEndPoint)connection.client.Client.RemoteEndPoint;
}
return "";
return null;
}
catch (SocketException)
{
@ -337,10 +337,17 @@ public string GetClientAddress(int connectionId)
// incompatible with the requested protocol was used at
// System.Net.Sockets.Socket.get_LocalEndPoint ()
// so let's at least catch it and recover
return "unknown";
return null;
}
}
[Obsolete("Telepathy.Server.GetClientEndPoint() isn't needed anymore. Connection endpoints are now passed in the Telepathy.Server.OnConnected event in order to make threaded transports easier.")]
public string GetClientAddress(int connectionId)
{
IPEndPoint endPoint = GetClientEndPoint(connectionId);
return endPoint != null ? endPoint.Address.ToString() : "unknown";
}
// disconnect (kick) a client
public bool Disconnect(int connectionId)
{
@ -388,7 +395,9 @@ public int Tick(int processLimit, Func<bool> checkEnabled = null)
switch (eventType)
{
case EventType.Connected:
OnConnected?.Invoke(connectionId);
// pass address in OnConnected for easier ThreadedTransport support
IPEndPoint endPoint = GetClientEndPoint(connectionId);
OnConnected?.Invoke(connectionId, endPoint);
break;
case EventType.Data:
OnData?.Invoke(connectionId, message);

View File

@ -178,7 +178,7 @@ public override void ServerStart()
// system's hook (e.g. statistics OnData) was added is to wrap
// them all in a lambda and always call the latest hook.
// (= lazy call)
server.OnConnected = (connectionId) => OnServerConnected.Invoke(connectionId);
server.OnConnected = (connectionId, endPoint) => OnServerConnected.Invoke(connectionId, endPoint.PrettyAddress());
server.OnData = (connectionId, segment) => OnServerDataReceived.Invoke(connectionId, segment, Channels.Reliable);
server.OnDisconnected = (connectionId) => OnServerDisconnected.Invoke(connectionId);

View File

@ -5,6 +5,7 @@
// note that ThreadLog.cs is required for Debug.Log from threads to work in builds.
using System;
using System.Collections.Concurrent;
using System.Net;
using System.Runtime.CompilerServices;
using System.Threading;
using UnityEngine;
@ -317,9 +318,11 @@ protected void OnThreadedClientDisconnected()
EnqueueClientMain(ClientMainEventType.OnClientDisconnected, null, null, null);
}
protected void OnThreadedServerConnected(int connectionId)
protected void OnThreadedServerConnected(int connectionId, IPEndPoint endPoint)
{
EnqueueServerMain(ServerMainEventType.OnServerConnected, null, connectionId, null, null);
// create string copy of address immediately before sending to another thread
string address = endPoint.PrettyAddress();
EnqueueServerMain(ServerMainEventType.OnServerConnected, address, connectionId, null, null);
}
protected void OnThreadedServerSend(int connectionId, ArraySegment<byte> message, int channelId)
@ -515,9 +518,9 @@ public override void ServerEarlyUpdate()
// SERVER EVENTS ///////////////////////////////////////////
case ServerMainEventType.OnServerConnected:
{
// call original transport event
// TODO pass client address in OnConnect here later
OnServerConnected?.Invoke(elem.connectionId.Value);//, (string)elem.param);
// call original transport event with connectionId, address
string address = (string)elem.param;
OnServerConnected?.Invoke(elem.connectionId.Value, address);
break;
}
case ServerMainEventType.OnServerSent:
@ -612,7 +615,7 @@ public override void ServerDisconnect(int connectionId)
// querying this at runtime won't work for threaded transports.
public override string ServerGetClientAddress(int connectionId)
{
throw new NotImplementedException();
throw new NotImplementedException("ThreadedTransport passes each connection's address in OnServerConnected. Don't use ServerGetClientAddress.");
}
public override void ServerStop()