diff --git a/CoreRemoting.Tests/RpcTests.cs b/CoreRemoting.Tests/RpcTests.cs index b3dddfc..12af61d 100644 --- a/CoreRemoting.Tests/RpcTests.cs +++ b/CoreRemoting.Tests/RpcTests.cs @@ -608,5 +608,54 @@ public void DataTable_roundtrip_works_issue60() var dt2 = proxy.TestDt(dt, 1); Assert.NotNull(dt2); } + + [Fact] + public void Large_messages_are_sent_and_received() + { + // max payload size, in bytes + var maxSize = 2 * 1024 * 1024 + 1; + + using var client = new RemotingClient(new ClientConfig() + { + ConnectionTimeout = 0, + InvocationTimeout = 0, + SendTimeout = 0, + Channel = ClientChannel, + MessageEncryption = false, + ServerPort = _serverFixture.Server.Config.NetworkPort, + }); + + client.Connect(); + var proxy = client.CreateProxy(); + + // shouldn't throw exceptions + Roundtrip("Payload", maxSize); + Roundtrip(new byte[] { 1, 2, 3, 4, 5 }, maxSize); + Roundtrip(new int[] { 12345, 67890 }, maxSize); + + void Roundtrip(T payload, int maxSize) where T : class + { + var lastSize = 0; + try + { + while (true) + { + // a -> aa -> aaaa ... + var dup = proxy.Duplicate(payload); + if (dup.size >= maxSize) + break; + + // save the size for error reporting + lastSize = dup.size; + payload = dup.duplicate; + } + } + catch (Exception ex) + { + throw new InvalidOperationException($"Failed to handle " + + $"payload larger than {lastSize}: {ex.Message}", ex); + } + } + } } } \ No newline at end of file diff --git a/CoreRemoting.Tests/Tools/ITestService.cs b/CoreRemoting.Tests/Tools/ITestService.cs index 7977a95..7685f04 100644 --- a/CoreRemoting.Tests/Tools/ITestService.cs +++ b/CoreRemoting.Tests/Tools/ITestService.cs @@ -38,5 +38,7 @@ public interface ITestService : IBaseService void NonSerializableError(string text, params object[] data); DataTable TestDt(DataTable dt, long num); + + (T duplicate, int size) Duplicate(T sample) where T : class; } } \ No newline at end of file diff --git a/CoreRemoting.Tests/Tools/TestService.cs b/CoreRemoting.Tests/Tools/TestService.cs index 1cc271d..6bdf221 100644 --- a/CoreRemoting.Tests/Tools/TestService.cs +++ b/CoreRemoting.Tests/Tools/TestService.cs @@ -99,5 +99,24 @@ public DataTable TestDt(DataTable dt, long num) dt.Rows.Clear(); return dt; } + + public (T, int) Duplicate(T sample) where T : class + { + return sample switch + { + byte[] arr => (Dup(arr) as T, arr.Length * 2), + int[] iarr => (Dup(iarr) as T, iarr.Length * 2 * sizeof(int)), + string str => ((str + str) as T, str.Length * 2 * sizeof(char)), + _ => throw new ArgumentOutOfRangeException(), + }; + + TItem[] Dup(TItem[] arr) + { + var length = arr.Length; + Array.Resize(ref arr, length * 2); + Array.Copy(arr, 0, arr, length, length); + return arr; + } + } } } \ No newline at end of file