您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
705 行
28 KiB
705 行
28 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using NUnit.Framework;
|
|
using Unity.Collections;
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
using Unity.Networking.Transport.Error;
|
|
using UnityEngine;
|
|
using Unity.Networking.Transport.Protocols;
|
|
using Unity.Networking.Transport.Utilities;
|
|
using Random = UnityEngine.Random;
|
|
|
|
namespace Unity.Networking.Transport.Tests.Utilities
|
|
{
|
|
using System.Linq;
|
|
public static class Random
|
|
{
|
|
private static System.Random random = new System.Random();
|
|
|
|
public static string String(int length)
|
|
{
|
|
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
return new string(Enumerable.Repeat(chars, length)
|
|
.Select(s => s[random.Next(s.Length)]).ToArray());
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace Unity.Networking.Transport.Tests
|
|
{
|
|
public struct LocalDriverHelper : IDisposable
|
|
{
|
|
public NetworkEndPoint EndPoint { get; }
|
|
public NetworkDriver m_LocalDriver;
|
|
private NativeArray<byte> m_LocalData;
|
|
public NetworkConnection Connection { get; internal set; }
|
|
public List<NetworkConnection> ClientConnections;
|
|
|
|
public LocalDriverHelper(NetworkEndPoint endpoint, params INetworkParameter[] networkParams)
|
|
{
|
|
if (networkParams.Length == 0)
|
|
m_LocalDriver = new NetworkDriver(new IPCNetworkInterface(), new NetworkDataStreamParameter
|
|
{size = NetworkParameterConstants.MTU});
|
|
else
|
|
m_LocalDriver = new NetworkDriver(new IPCNetworkInterface(), networkParams);
|
|
m_LocalData = new NativeArray<byte>(NetworkParameterConstants.MTU, Allocator.Persistent);
|
|
|
|
if (endpoint.IsValid)
|
|
{
|
|
EndPoint = endpoint;
|
|
}
|
|
else
|
|
{
|
|
EndPoint = NetworkEndPoint.LoopbackIpv4.WithPort(1);
|
|
}
|
|
|
|
Connection = default(NetworkConnection);
|
|
ClientConnections = new List<NetworkConnection>();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
m_LocalDriver.Dispose();
|
|
m_LocalData.Dispose();
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
m_LocalDriver.ScheduleUpdate().Complete();
|
|
}
|
|
|
|
public NetworkConnection Accept()
|
|
{
|
|
return m_LocalDriver.Accept();
|
|
}
|
|
|
|
public void Host()
|
|
{
|
|
m_LocalDriver.Bind(EndPoint);
|
|
m_LocalDriver.Listen();
|
|
}
|
|
|
|
public void Connect(NetworkEndPoint endpoint)
|
|
{
|
|
Assert.True(endpoint.IsValid);
|
|
Connection = m_LocalDriver.Connect(endpoint);
|
|
m_LocalDriver.ScheduleUpdate().Complete();
|
|
}
|
|
|
|
public unsafe void Assert_GotConnectionRequest(NetworkEndPoint from, bool accept = false)
|
|
{
|
|
int length;
|
|
NetworkInterfaceEndPoint remote;
|
|
Assert.True(EndPoint.IsLoopback || EndPoint.IsAny);
|
|
Assert.True(from.IsLoopback || from.IsAny);
|
|
var localEndPoint = IPCManager.Instance.CreateEndPoint(EndPoint.Port);
|
|
var fromEndPoint = IPCManager.Instance.CreateEndPoint(from.Port);
|
|
Assert.True(
|
|
IPCManager.Instance.PeekNext(localEndPoint, m_LocalData.GetUnsafePtr(), out length, out remote) >=
|
|
sizeof(UdpCHeader));
|
|
|
|
UdpCHeader header = new UdpCHeader();
|
|
var reader = new DataStreamReader(m_LocalData.GetSubArray(0, sizeof(UdpCHeader)));
|
|
Assert.True(reader.IsCreated);
|
|
reader.ReadBytes(header.Data, sizeof(UdpCHeader));
|
|
Assert.AreEqual((int) UdpCProtocol.ConnectionRequest, header.Type);
|
|
|
|
Assert.True(remote == fromEndPoint);
|
|
|
|
if (accept)
|
|
{
|
|
m_LocalDriver.ScheduleUpdate().Complete();
|
|
var con = m_LocalDriver.Accept();
|
|
ClientConnections.Add(con);
|
|
Assert.True(con != default(NetworkConnection));
|
|
}
|
|
}
|
|
|
|
public unsafe void Assert_GotDisconnectionRequest(NetworkEndPoint from)
|
|
{
|
|
int length;
|
|
NetworkInterfaceEndPoint remote;
|
|
Assert.True(EndPoint.IsLoopback || EndPoint.IsAny);
|
|
Assert.True(from.IsLoopback || from.IsAny);
|
|
var localEndPoint = IPCManager.Instance.CreateEndPoint(EndPoint.Port);
|
|
var fromEndPoint = IPCManager.Instance.CreateEndPoint(from.Port);
|
|
Assert.True(
|
|
IPCManager.Instance.PeekNext(localEndPoint, m_LocalData.GetUnsafePtr(), out length, out remote) >=
|
|
sizeof(UdpCHeader));
|
|
|
|
UdpCHeader header = new UdpCHeader();
|
|
var reader = new DataStreamReader(m_LocalData.GetSubArray(0, sizeof(UdpCHeader)));
|
|
Assert.True(reader.IsCreated);
|
|
reader.ReadBytes(header.Data, sizeof(UdpCHeader));
|
|
Assert.True(header.Type == (int) UdpCProtocol.Disconnect);
|
|
|
|
Assert.True(remote == fromEndPoint);
|
|
}
|
|
|
|
public unsafe void Assert_GotDataRequest(NetworkEndPoint from, byte[] dataToCompare)
|
|
{
|
|
NetworkInterfaceEndPoint remote = default;
|
|
int headerLen = sizeof(UdpCHeader);
|
|
void* packetData = (byte*)m_LocalData.GetUnsafePtr();
|
|
int payloadLen = NetworkParameterConstants.MTU;
|
|
int dataLen = 0;
|
|
Assert.True(EndPoint.IsLoopback || EndPoint.IsAny);
|
|
Assert.True(from.IsLoopback || from.IsAny);
|
|
var localEndPoint = IPCManager.Instance.CreateEndPoint(EndPoint.Port);
|
|
var fromEndPoint = IPCManager.Instance.CreateEndPoint(from.Port);
|
|
dataLen = IPCManager.Instance.ReceiveMessageEx(localEndPoint, packetData, payloadLen, ref remote);
|
|
|
|
payloadLen = dataLen - headerLen;
|
|
if (payloadLen <= 0)
|
|
{
|
|
payloadLen = 0;
|
|
}
|
|
|
|
UdpCHeader header = new UdpCHeader();
|
|
var reader = new DataStreamReader(m_LocalData.GetSubArray(0, headerLen));
|
|
Assert.True(reader.IsCreated);
|
|
reader.ReadBytes(header.Data, headerLen);
|
|
Assert.True(header.Type == (int) UdpCProtocol.Data);
|
|
|
|
Assert.True(remote == fromEndPoint);
|
|
|
|
Assert.True(payloadLen == dataToCompare.Length);
|
|
|
|
reader = new DataStreamReader(m_LocalData.GetSubArray(headerLen, dataToCompare.Length));
|
|
var received = new NativeArray<byte>(dataToCompare.Length, Allocator.Temp);
|
|
reader.ReadBytes(received);
|
|
|
|
for (int i = 0, n = dataToCompare.Length; i < n; ++i)
|
|
Assert.True(received[i] == dataToCompare[i]);
|
|
}
|
|
|
|
public unsafe void Assert_PopEventForConnection(NetworkConnection connection, NetworkEvent.Type evnt)
|
|
{
|
|
DataStreamReader reader;
|
|
var retval = m_LocalDriver.PopEventForConnection(connection, out reader);
|
|
Assert.True(retval == evnt);
|
|
}
|
|
|
|
public unsafe void Assert_PopEvent(out NetworkConnection connection, NetworkEvent.Type evnt)
|
|
{
|
|
DataStreamReader reader;
|
|
|
|
var retval = m_LocalDriver.PopEvent(out connection, out reader);
|
|
Assert.True(retval == evnt);
|
|
}
|
|
}
|
|
|
|
public class NetworkDriverUnitTests
|
|
{
|
|
private const string backend = "baselib";
|
|
[Test]
|
|
public void InitializeAndDestroyDriver()
|
|
{
|
|
var driver = TestNetworkDriver.Create(new NetworkDataStreamParameter {size = 64});
|
|
driver.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public void BindDriverToAEndPoint()
|
|
{
|
|
var driver = TestNetworkDriver.Create(new NetworkDataStreamParameter {size = 64});
|
|
|
|
driver.Bind(NetworkEndPoint.LoopbackIpv4);
|
|
driver.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public void ListenOnDriver()
|
|
{
|
|
var driver = TestNetworkDriver.Create(new NetworkDataStreamParameter {size = 64});
|
|
|
|
// Make sure we Bind before we Listen.
|
|
driver.Bind(NetworkEndPoint.LoopbackIpv4);
|
|
driver.Listen();
|
|
|
|
Assert.True(driver.Listening);
|
|
driver.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public void AcceptNewConnectionsOnDriver()
|
|
{
|
|
var driver = TestNetworkDriver.Create(new NetworkDataStreamParameter {size = 64});
|
|
|
|
// Make sure we Bind before we Listen.
|
|
driver.Bind(NetworkEndPoint.LoopbackIpv4);
|
|
driver.Listen();
|
|
|
|
Assert.True(driver.Listening);
|
|
|
|
//NetworkConnection connection;
|
|
while ((/*connection =*/ driver.Accept()) != default(NetworkConnection))
|
|
{
|
|
//Assert.True(connectionId != NetworkParameterConstants.InvalidConnectionId);
|
|
}
|
|
|
|
driver.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public void ConnectToARemoteEndPoint()
|
|
{
|
|
using (var host = new LocalDriverHelper(default(NetworkEndPoint)))
|
|
using (var driver = new NetworkDriver(new IPCNetworkInterface(), new NetworkDataStreamParameter {size = 64}))
|
|
{
|
|
host.Host();
|
|
|
|
NetworkConnection connectionId = driver.Connect(host.EndPoint);
|
|
Assert.True(connectionId != default(NetworkConnection));
|
|
driver.ScheduleUpdate().Complete();
|
|
|
|
var local = driver.LocalEndPoint();
|
|
host.Assert_GotConnectionRequest(local);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetNotValidConnectionState()
|
|
{
|
|
using (var driver = TestNetworkDriver.Create(new NetworkDataStreamParameter {size = 64}))
|
|
{
|
|
Assert.AreEqual(NetworkConnection.State.Disconnected, driver.GetConnectionState(new NetworkConnection() {m_NetworkId = Int16.MaxValue}));
|
|
Assert.AreEqual(NetworkConnection.State.Disconnected, driver.GetConnectionState(new NetworkConnection() {m_NetworkId = -1}));
|
|
}
|
|
}
|
|
|
|
// TODO: Add tests where connection attempts are exceeded (connect fails)
|
|
// TODO: Test dropped connection accept messages (accept retries happen)
|
|
// TODO: Needs a way to explicitly assert on connect attempt stats
|
|
// In this test multiple connect requests are received on the server, from client, might be this is expected
|
|
// because of how the IPC driver works, but this situation is handled properly at least by basic driver logic.
|
|
[Test]
|
|
public void ConnectAttemptWithRetriesToARemoteEndPoint()
|
|
{
|
|
NetworkConnection connection;
|
|
NetworkEvent.Type eventType = 0;
|
|
DataStreamReader reader;
|
|
|
|
// Tiny connect timeout for this test to be quicker
|
|
using (var client = new NetworkDriver(new IPCNetworkInterface(), new NetworkDataStreamParameter {size = 64},
|
|
new NetworkConfigParameter {connectTimeoutMS = 15, maxConnectAttempts = 10, fixedFrameTimeMS = 10}))
|
|
{
|
|
var hostAddress = NetworkEndPoint.LoopbackIpv4.WithPort(1);
|
|
client.Connect(hostAddress);
|
|
|
|
// Wait past the connect timeout so there will be unanswered connect requests
|
|
client.ScheduleUpdate().Complete();
|
|
client.ScheduleUpdate().Complete();
|
|
|
|
using (var host = new LocalDriverHelper(hostAddress))
|
|
{
|
|
host.Host();
|
|
|
|
// Now give the next connect attempt time to happen
|
|
// TODO: Would be better to be able to see internal state here and explicitly wait until next connect attempt happens
|
|
//client.ScheduleUpdate().Complete();
|
|
|
|
host.Assert_GotConnectionRequest(client.LocalEndPoint(), true);
|
|
|
|
// Wait for the client to get the connect event back
|
|
for (int i = 0; i < 2; ++i)
|
|
{
|
|
client.ScheduleUpdate().Complete();
|
|
eventType = client.PopEvent(out connection, out reader);
|
|
if (eventType != NetworkEvent.Type.Empty)
|
|
break;
|
|
}
|
|
|
|
Assert.AreEqual(NetworkEvent.Type.Connect, eventType);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void DisconnectFromARemoteEndPoint()
|
|
{
|
|
using (var host = new LocalDriverHelper(default(NetworkEndPoint)))
|
|
using (var driver = new NetworkDriver(new IPCNetworkInterface(), new NetworkDataStreamParameter {size = 64}))
|
|
{
|
|
host.Host();
|
|
|
|
// Need to be connected in order to be able to send a disconnect packet.
|
|
NetworkConnection connectionId = driver.Connect(host.EndPoint);
|
|
Assert.True(connectionId != default(NetworkConnection));
|
|
driver.ScheduleUpdate().Complete();
|
|
|
|
var local = driver.LocalEndPoint();
|
|
host.Assert_GotConnectionRequest(local, true);
|
|
|
|
NetworkConnection con;
|
|
DataStreamReader slice;
|
|
// Pump so we get the accept message back.
|
|
driver.ScheduleUpdate().Complete();
|
|
Assert.AreEqual(NetworkEvent.Type.Connect, driver.PopEvent(out con, out slice));
|
|
driver.Disconnect(connectionId);
|
|
driver.ScheduleUpdate().Complete();
|
|
|
|
host.Assert_GotDisconnectionRequest(local);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void DisconnectTimeoutOnServer()
|
|
{
|
|
using (var host = new LocalDriverHelper(default(NetworkEndPoint),
|
|
new NetworkConfigParameter {disconnectTimeoutMS = 40, fixedFrameTimeMS = 10}))
|
|
using (var client = new NetworkDriver(new IPCNetworkInterface(), new NetworkConfigParameter {disconnectTimeoutMS = 40, fixedFrameTimeMS = 10}))
|
|
{
|
|
NetworkConnection id;
|
|
NetworkEvent.Type popEvent = NetworkEvent.Type.Empty;
|
|
DataStreamReader reader;
|
|
byte reason = 0;
|
|
|
|
host.Host();
|
|
|
|
client.Connect(host.EndPoint);
|
|
client.ScheduleUpdate().Complete();
|
|
host.Assert_GotConnectionRequest(client.LocalEndPoint(), true);
|
|
|
|
// Host sends stuff but gets nothing back, until disconnect timeout happens
|
|
for (int frm = 0; frm < 10; ++frm)
|
|
{
|
|
if (host.m_LocalDriver.BeginSend(NetworkPipeline.Null, host.ClientConnections[0], out var stream) == 0)
|
|
{
|
|
for (int i = 0; i < 100; i++)
|
|
stream.WriteByte((byte) i);
|
|
|
|
host.m_LocalDriver.EndSend(stream);
|
|
}
|
|
if ((popEvent = host.m_LocalDriver.PopEvent(out id, out reader)) != NetworkEvent.Type.Empty)
|
|
{
|
|
reason = (reader.IsCreated && reader.Length > 0) ? reason = reader.ReadByte() : (byte)0;
|
|
break;
|
|
}
|
|
host.Update();
|
|
}
|
|
Assert.AreEqual(NetworkEvent.Type.Disconnect, popEvent);
|
|
Assert.AreEqual((byte)DisconnectReason.Timeout, reason);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void DisconnectByRemote()
|
|
{
|
|
using (var host = new LocalDriverHelper(default(NetworkEndPoint)))
|
|
using (var client = new NetworkDriver(new IPCNetworkInterface()))
|
|
{
|
|
host.Host();
|
|
var popEvent = NetworkEvent.Type.Empty;
|
|
var c = client.Connect(host.EndPoint);
|
|
|
|
client.ScheduleUpdate().Complete();
|
|
host.Assert_GotConnectionRequest(client.LocalEndPoint(), true);
|
|
|
|
byte reason = 0;
|
|
DataStreamReader reader;
|
|
for (int frm = 0; frm < 10; ++frm)
|
|
{
|
|
if (c.GetState(client) == NetworkConnection.State.Connected) c.Disconnect(client);
|
|
|
|
if ((popEvent = host.m_LocalDriver.PopEvent(out var id, out reader)) != NetworkEvent.Type.Empty)
|
|
{
|
|
reason = (reader.IsCreated && reader.Length > 0) ? reason = reader.ReadByte() : (byte)0;
|
|
break;
|
|
}
|
|
host.Update();
|
|
client.ScheduleUpdate().Complete();
|
|
}
|
|
Assert.AreEqual(NetworkEvent.Type.Disconnect, popEvent);
|
|
Assert.AreEqual((byte)DisconnectReason.ClosedByRemote, reason);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void DisconnectByMaxConnectionAttempts()
|
|
{
|
|
using (var host = new LocalDriverHelper(default(NetworkEndPoint)))
|
|
using (var client = new NetworkDriver(new IPCNetworkInterface(), new NetworkConfigParameter {maxConnectAttempts = 1, fixedFrameTimeMS = 10, connectTimeoutMS = 25}))
|
|
{
|
|
host.Host();
|
|
var popEvent = NetworkEvent.Type.Empty;
|
|
var c = client.Connect(host.EndPoint);
|
|
client.ScheduleUpdate().Complete();
|
|
|
|
byte reason = 0;
|
|
var reader = default(DataStreamReader);
|
|
for (int frm = 0; frm < 10; ++frm)
|
|
{
|
|
if ((popEvent = client.PopEvent(out var id, out reader)) != NetworkEvent.Type.Empty)
|
|
{
|
|
reason = (reader.IsCreated && reader.Length > 0) ? reason = reader.ReadByte() : (byte)0;
|
|
break;
|
|
}
|
|
client.ScheduleUpdate().Complete();
|
|
}
|
|
Assert.AreEqual(NetworkEvent.Type.Disconnect, popEvent);
|
|
Assert.AreEqual((byte)DisconnectReason.MaxConnectionAttempts, reason);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SendDataToRemoteEndPoint()
|
|
{
|
|
using (var host = new LocalDriverHelper(default))
|
|
{
|
|
host.Host();
|
|
var driver = new NetworkDriver(new IPCNetworkInterface(), new NetworkDataStreamParameter {size = 64});
|
|
|
|
// Need to be connected in order to be able to send a disconnect packet.
|
|
NetworkConnection connectionId = driver.Connect(host.EndPoint);
|
|
Assert.True(connectionId != default(NetworkConnection));
|
|
driver.ScheduleUpdate().Complete();
|
|
var local = driver.LocalEndPoint();
|
|
host.Assert_GotConnectionRequest(local, true);
|
|
|
|
NetworkConnection con;
|
|
DataStreamReader slice;
|
|
// Pump so we get the accept message back.
|
|
driver.ScheduleUpdate().Complete();
|
|
Assert.AreEqual(NetworkEvent.Type.Connect, driver.PopEvent(out con, out slice));
|
|
|
|
var data = Encoding.ASCII.GetBytes("data to send");
|
|
if (driver.BeginSend(NetworkPipeline.Null, connectionId, out var stream) == 0)
|
|
{
|
|
stream.WriteBytes(new NativeArray<byte>(data, Allocator.Temp));
|
|
driver.EndSend(stream);
|
|
}
|
|
driver.ScheduleUpdate().Complete();
|
|
|
|
host.Assert_GotDataRequest(local, data);
|
|
|
|
driver.Dispose();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void HandleEventsFromSpecificEndPoint()
|
|
{
|
|
using (var host = new LocalDriverHelper(default))
|
|
using (var client0 = new LocalDriverHelper(default))
|
|
using (var client1 = new LocalDriverHelper(default))
|
|
{
|
|
host.Host();
|
|
client0.Connect(host.EndPoint);
|
|
client1.Connect(host.EndPoint);
|
|
|
|
host.Assert_PopEventForConnection(client0.Connection, NetworkEvent.Type.Empty);
|
|
host.Assert_PopEventForConnection(client1.Connection, NetworkEvent.Type.Empty);
|
|
|
|
host.Update();
|
|
|
|
var clientConnectionId0 = host.Accept();
|
|
Assert.True(clientConnectionId0 != default(NetworkConnection));
|
|
var clientConnectionId1 = host.Accept();
|
|
Assert.True(clientConnectionId1 != default(NetworkConnection));
|
|
|
|
client1.Update();
|
|
client1.Assert_PopEventForConnection(client1.Connection, NetworkEvent.Type.Connect);
|
|
|
|
client0.Update();
|
|
client0.Assert_PopEventForConnection(client0.Connection, NetworkEvent.Type.Connect);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void HandleEventsFromAnyEndPoint()
|
|
{
|
|
using (var host = new LocalDriverHelper(default))
|
|
using (var client0 = new LocalDriverHelper(default))
|
|
using (var client1 = new LocalDriverHelper(default))
|
|
{
|
|
host.Host();
|
|
client0.Connect(host.EndPoint);
|
|
client1.Connect(host.EndPoint);
|
|
|
|
host.Assert_PopEventForConnection(client0.Connection, NetworkEvent.Type.Empty);
|
|
host.Assert_PopEventForConnection(client1.Connection, NetworkEvent.Type.Empty);
|
|
|
|
host.Update();
|
|
|
|
var clientConnectionId0 = host.Accept();
|
|
Assert.True(clientConnectionId0 != default(NetworkConnection));
|
|
var clientConnectionId1 = host.Accept();
|
|
Assert.True(clientConnectionId1 != default(NetworkConnection));
|
|
|
|
NetworkConnection id;
|
|
|
|
client1.Update();
|
|
client1.Assert_PopEvent(out id, NetworkEvent.Type.Connect);
|
|
Assert.True(id == client1.Connection);
|
|
|
|
client0.Update();
|
|
client0.Assert_PopEvent(out id, NetworkEvent.Type.Connect);
|
|
Assert.True(id == client0.Connection);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void FillInternalBitStreamBuffer()
|
|
{
|
|
const int k_InternalBufferSize = 1000;
|
|
const int k_PacketCount = 21; // Exactly enough to fill the receive buffer + 1 too much
|
|
const int k_PacketSize = 50;
|
|
const int k_PacketHeaderSize = 4; // The header also goes to the buffer
|
|
const int k_PayloadSize = k_PacketSize - k_PacketHeaderSize;
|
|
|
|
using (var host = new NetworkDriver(new IPCNetworkInterface(), new NetworkDataStreamParameter {size = k_InternalBufferSize}))
|
|
using (var client = new NetworkDriver(new IPCNetworkInterface(), new NetworkDataStreamParameter {size = 64}))
|
|
{
|
|
host.Bind(NetworkEndPoint.LoopbackIpv4);
|
|
|
|
host.Listen();
|
|
|
|
NetworkConnection connectionId = client.Connect(host.LocalEndPoint());
|
|
|
|
client.ScheduleUpdate().Complete();
|
|
host.ScheduleUpdate().Complete();
|
|
|
|
NetworkConnection poppedId;
|
|
DataStreamReader reader;
|
|
host.Accept();
|
|
|
|
client.ScheduleUpdate().Complete();
|
|
|
|
var retval = client.PopEvent(out poppedId, out reader);
|
|
Assert.AreEqual(retval, NetworkEvent.Type.Connect);
|
|
|
|
var dataBlob = new Dictionary<int, byte[]>();
|
|
for (int i = 0; i < k_PacketCount; ++i)
|
|
{
|
|
// Scramble each packet contents so you can't match reading the same data twice as success
|
|
dataBlob.Add(i, Encoding.ASCII.GetBytes(Utilities.Random.String(k_PayloadSize)));
|
|
}
|
|
|
|
for (int i = 0; i < k_PacketCount; ++i)
|
|
{
|
|
if (client.BeginSend(NetworkPipeline.Null, connectionId, out var stream) == 0)
|
|
{
|
|
stream.WriteBytes(new NativeArray<byte>(dataBlob[i], Allocator.Temp));
|
|
client.EndSend(stream);
|
|
}
|
|
}
|
|
|
|
// Process the pending events
|
|
client.ScheduleUpdate().Complete();
|
|
host.ScheduleUpdate().Complete();
|
|
|
|
for (int i = 0; i < k_PacketCount; ++i)
|
|
{
|
|
retval = host.PopEvent(out poppedId, out reader);
|
|
|
|
if (i == k_PacketCount - 1)
|
|
{
|
|
Assert.AreEqual(retval, NetworkEvent.Type.Empty);
|
|
Assert.IsFalse(reader.IsCreated);
|
|
host.ScheduleUpdate().Complete();
|
|
retval = host.PopEvent(out poppedId, out reader);
|
|
}
|
|
|
|
Assert.AreEqual(NetworkEvent.Type.Data, retval);
|
|
Assert.AreEqual(reader.Length, k_PayloadSize);
|
|
|
|
for (int j = 0; j < k_PayloadSize; ++j)
|
|
{
|
|
Assert.AreEqual(dataBlob[i][j], reader.ReadByte());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void SendAndReceiveMessage(NetworkDriver serverDriver, NetworkDriver clientDriver)
|
|
{
|
|
DataStreamReader stream;
|
|
|
|
var serverEndpoint = NetworkEndPoint.Parse("127.0.0.1", (ushort)Random.Range(2000, 65000));
|
|
serverDriver.Bind(serverEndpoint);
|
|
serverDriver.Listen();
|
|
|
|
var clientToServerId = clientDriver.Connect(serverEndpoint);
|
|
clientDriver.ScheduleFlushSend(default).Complete();
|
|
|
|
NetworkConnection serverToClientId = default(NetworkConnection);
|
|
// Retry a few times since the network might need some time to process
|
|
for (int i = 0; i < 10 && serverToClientId == default(NetworkConnection); ++i)
|
|
{
|
|
clientDriver.ScheduleUpdate().Complete();
|
|
serverDriver.ScheduleUpdate().Complete();
|
|
|
|
serverToClientId = serverDriver.Accept();
|
|
}
|
|
|
|
Assert.That(serverToClientId != default(NetworkConnection));
|
|
|
|
clientDriver.ScheduleUpdate().Complete();
|
|
|
|
var eventId = clientDriver.PopEventForConnection(clientToServerId, out stream);
|
|
Assert.That(eventId == NetworkEvent.Type.Connect, $"Expected Connect but got {eventId} using {backend}");
|
|
|
|
int testInt = 100;
|
|
float testFloat = 555.5f;
|
|
byte[] testByteArray = Encoding.ASCII.GetBytes("Some bytes blablabla 1111111111111111111");
|
|
var sentBytes = 0;
|
|
if (clientDriver.BeginSend(NetworkPipeline.Null, clientToServerId, out var clientSendData) == 0)
|
|
{
|
|
clientSendData.WriteInt(testInt);
|
|
clientSendData.WriteFloat(testFloat);
|
|
clientSendData.WriteInt(testByteArray.Length);
|
|
clientSendData.WriteBytes(new NativeArray<byte>(testByteArray, Allocator.Temp));
|
|
sentBytes = clientDriver.EndSend(clientSendData);
|
|
}
|
|
|
|
Assert.AreEqual(clientSendData.Length, sentBytes);
|
|
|
|
clientDriver.ScheduleUpdate().Complete();
|
|
serverDriver.ScheduleUpdate().Complete();
|
|
|
|
DataStreamReader serverReceiveStream;
|
|
eventId = serverDriver.PopEventForConnection(serverToClientId, out serverReceiveStream);
|
|
|
|
Assert.True(eventId == NetworkEvent.Type.Data);
|
|
var receivedInt = serverReceiveStream.ReadInt();
|
|
var receivedFloat = serverReceiveStream.ReadFloat();
|
|
var byteArrayLength = serverReceiveStream.ReadInt();
|
|
var receivedBytes = new NativeArray<byte>(byteArrayLength, Allocator.Temp);
|
|
serverReceiveStream.ReadBytes(receivedBytes);
|
|
|
|
Assert.True(testInt == receivedInt);
|
|
Assert.That(Mathf.Approximately(testFloat, receivedFloat));
|
|
Assert.AreEqual(testByteArray, receivedBytes);
|
|
}
|
|
[Test]
|
|
public void SendAndReceiveMessage_RealNetwork()
|
|
{
|
|
using (var serverDriver = NetworkDriver.Create(new NetworkDataStreamParameter {size = 64}))
|
|
using (var clientDriver = NetworkDriver.Create(new NetworkDataStreamParameter {size = 64}))
|
|
{
|
|
SendAndReceiveMessage(serverDriver, clientDriver);
|
|
}
|
|
}
|
|
[Test]
|
|
public void SendAndReceiveMessage_WebSocket()
|
|
{
|
|
using (var serverDriver = new NetworkDriver(new WebSocketNetworkInterface(), new NetworkDataStreamParameter {size = 64}))
|
|
using (var clientDriver = new NetworkDriver(new WebSocketNetworkInterface(), new NetworkDataStreamParameter {size = 64}))
|
|
{
|
|
SendAndReceiveMessage(serverDriver, clientDriver);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SendAndReceiveMessage()
|
|
{
|
|
using (var serverDriver = new NetworkDriver(new IPCNetworkInterface(), new NetworkDataStreamParameter {size = 64}))
|
|
using (var clientDriver = new NetworkDriver(new IPCNetworkInterface(), new NetworkDataStreamParameter {size = 64}))
|
|
{
|
|
SendAndReceiveMessage(serverDriver, clientDriver);
|
|
}
|
|
}
|
|
}
|
|
}
|