From 938364870d400dd7e9fd5ece7608aec65c1e1383 Mon Sep 17 00:00:00 2001 From: shosatojp Date: Tue, 6 Apr 2021 15:46:41 +0900 Subject: [PATCH 01/13] =?UTF-8?q?*=20Task=E7=94=9F=E6=88=90=E6=95=B0?= =?UTF-8?q?=E3=82=92=E6=B8=9B=E3=82=89=E3=81=97=E3=81=A6CPU=E5=8A=B9?= =?UTF-8?q?=E7=8E=87=E3=81=AE=E6=94=B9=E5=96=84=20*=20=E3=83=91=E3=82=B1?= =?UTF-8?q?=E3=83=83=E3=83=88=E5=87=A6=E7=90=86=E3=82=92CPU=E6=95=B0?= =?UTF-8?q?=E3=81=AB=E5=88=86=E5=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Source/StreamServer/OutputLoop.cs | 16 ++++-- .../Source/StreamServer/PacketSender.cs | 50 +++++++------------ .../ExtensionMethod/SplitIn.cs | 19 +++++++ 3 files changed, 50 insertions(+), 35 deletions(-) create mode 100644 StreamServerCommonLibrary/ExtensionMethod/SplitIn.cs diff --git a/StreamServer/Source/StreamServer/OutputLoop.cs b/StreamServer/Source/StreamServer/OutputLoop.cs index 18449c9..06b7492 100644 --- a/StreamServer/Source/StreamServer/OutputLoop.cs +++ b/StreamServer/Source/StreamServer/OutputLoop.cs @@ -4,6 +4,7 @@ using System.Net.Sockets; using System.Threading.Tasks; using CommonLibrary; +using CommonLibrary.ExtensionMethod; using DebugPrintLibrary; using EventServerCore; using LoopLibrary; @@ -20,7 +21,7 @@ public OutputLoop(UdpClient udpClient, int interval, ulong id) { udp = udpClient; } - + protected override void Start() { var localEndPoint = udp.Client.LocalEndPoint as IPEndPoint; @@ -35,7 +36,7 @@ protected override async Task Update(int count) List users = new List(); foreach (var kvp in ModelManager.Instance.Users) { - if(kvp.Value == null) continue; + if (kvp.Value == null) continue; var user = kvp.Value; MinimumAvatarPacket? packet = user.CurrentPacket; { @@ -53,10 +54,17 @@ protected override async Task Update(int count) if (user.IsConnected) users.Add(user); if (packet != null) packets.Add(packet); } + List tasks = new List(); - foreach (var user in users) + foreach (var userList in users.SplitInto(Environment.ProcessorCount)) { - tasks.Add(PacketSender.Send(user, packets, udp)); + tasks.Add(Task.Run(() => + { + foreach (var user in userList) + { + PacketSender.Send(user, packets, udp); + } + })); } await Task.WhenAll(tasks); } diff --git a/StreamServer/Source/StreamServer/PacketSender.cs b/StreamServer/Source/StreamServer/PacketSender.cs index 939cefc..03ef4a6 100644 --- a/StreamServer/Source/StreamServer/PacketSender.cs +++ b/StreamServer/Source/StreamServer/PacketSender.cs @@ -12,42 +12,30 @@ namespace StreamServer { public static class PacketSender { - public static async Task Send(User user, List packets, UdpClient udp) + public static void Send(User user, List packets, UdpClient udp) { - await Task.Run(async () => + var packetCopy = packets.ToList(); + if (user.CurrentPacket != null) { - var packetCopy = packets.ToList(); - if (user.CurrentPacket != null) - { - var selfPosition = user.CurrentPacket.Position; - - packetCopy.HeapSort((a, b) => - { - var aSquare = Vector3.Square(a.Position, selfPosition); - var bSquare = Vector3.Square(b.Position, selfPosition); - var comp = aSquare < bSquare ? -1 : 1; - return comp; - }); - } + var selfPosition = user.CurrentPacket.Position; - if (packetCopy.Count > 100) - packetCopy = packetCopy.GetRange(0, 100); - var buffs = Utility.PacketsToBuffers(packetCopy); - var tasks = new List(); - foreach (var buf in buffs) + packetCopy.HeapSort((a, b) => { - tasks.Add(udp.SendAsync(buf, buf.Length, user.RemoteEndPoint)); - } + var aSquare = Vector3.Square(a.Position, selfPosition); + var bSquare = Vector3.Square(b.Position, selfPosition); + var comp = aSquare < bSquare ? -1 : 1; + return comp; + }); + } - try - { - await Task.WhenAll(tasks); - } - catch (Exception e) - { - Printer.PrintDbg(e); - } - }); + if (packetCopy.Count > 100) + packetCopy = packetCopy.GetRange(0, 100); + var buffs = Utility.PacketsToBuffers(packetCopy); + var tasks = new List(); + foreach (var buf in buffs) + { + udp.Send(buf, buf.Length, user.RemoteEndPoint); + } } } } diff --git a/StreamServerCommonLibrary/ExtensionMethod/SplitIn.cs b/StreamServerCommonLibrary/ExtensionMethod/SplitIn.cs new file mode 100644 index 0000000..f881901 --- /dev/null +++ b/StreamServerCommonLibrary/ExtensionMethod/SplitIn.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace CommonLibrary.ExtensionMethod +{ + public static class SplitInExtension + { + public static IEnumerable> SplitInto(this List list, int num) + { + var count = list.Count; + var per = count / num; + var amari = count - (count / num) * num; + for (int i = 0; i < num; i++) + { + yield return list.GetRange(i * per + Math.Min(i, amari), per + (i < amari ? 1 : 0)); + } + } + } +} \ No newline at end of file From 04ed40ed67f6f3f5ca14ec1ec34bc65fce104490 Mon Sep 17 00:00:00 2001 From: shosatojp Date: Tue, 6 Apr 2021 16:54:53 +0900 Subject: [PATCH 02/13] =?UTF-8?q?FPS=E6=B8=AC=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LoopLibrary/BaseLoop.cs | 39 ++++++++++++++++--- StreamServer/Source/StreamServer/Entry.cs | 4 +- .../Source/StreamServer/StatusCheckLoop.cs | 8 +++- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/LoopLibrary/BaseLoop.cs b/LoopLibrary/BaseLoop.cs index f3c9285..8e4b8e4 100644 --- a/LoopLibrary/BaseLoop.cs +++ b/LoopLibrary/BaseLoop.cs @@ -3,6 +3,8 @@ using System.Threading.Tasks; using DebugPrintLibrary; using EventServerCore; +using System.Linq; +using System.Collections.Generic; namespace LoopLibrary { @@ -13,6 +15,8 @@ public abstract class BaseLoop private readonly CancellationTokenSource _cts = new CancellationTokenSource(); private int _count; public CancellationTokenSource Cts => _cts; + private readonly int _maxTimespans = 100; + private Queue _timespans = new Queue(); protected BaseLoop(int interval, ulong id = 1) { @@ -34,9 +38,19 @@ private async Task> Loop(CancellationToken token) { var delay = Task.Delay(_interval, token); - await Update(_count); - _count++; - + var start = DateTime.Now; + await Update(_count++); + var timespan = DateTime.Now - start; + + lock (_timespans) + { + _timespans.Enqueue(timespan.TotalMilliseconds); + if (_timespans.Count > _maxTimespans) + { + _timespans.Dequeue(); + } + } + await delay; } } @@ -57,7 +71,7 @@ private async Task> Loop(CancellationToken token) } } - protected virtual void Start(){} + protected virtual void Start() { } protected abstract Task Update(int count); @@ -68,12 +82,27 @@ protected virtual void OnCancel() public void Done(T result) { - throw new OperationCompletedException>(new Result(true ,result)); + throw new OperationCompletedException>(new Result(true, result)); } public void Cancel() { throw new OperationCanceledException(); } + + public double GetFps() + { + lock (_timespans) + { + if (_timespans.Count > 0) + { + return 1000 / _timespans.Average(); + } + else + { + return 0; + } + } + } } } diff --git a/StreamServer/Source/StreamServer/Entry.cs b/StreamServer/Source/StreamServer/Entry.cs index bde68c5..c6f8e76 100644 --- a/StreamServer/Source/StreamServer/Entry.cs +++ b/StreamServer/Source/StreamServer/Entry.cs @@ -11,8 +11,8 @@ static void Main(string[] args) { UdpClient udpClient = new UdpClient(5577); var input = new InputLoop(udpClient, 2, 1); - var output = new OutputLoop(udpClient, 1000, 2); - var statusCheck = new StatusCheckLoop(1000, 3); + var output = new OutputLoop(udpClient, 33, 2); + var statusCheck = new StatusCheckLoop(1000, 3, input, output); input.Run(); output.Run(); statusCheck.Run(); diff --git a/StreamServer/Source/StreamServer/StatusCheckLoop.cs b/StreamServer/Source/StreamServer/StatusCheckLoop.cs index 472d047..fe0df07 100644 --- a/StreamServer/Source/StreamServer/StatusCheckLoop.cs +++ b/StreamServer/Source/StreamServer/StatusCheckLoop.cs @@ -7,14 +7,20 @@ namespace StreamServer { public class StatusCheckLoop : BaseLoop { - public StatusCheckLoop(int interval, ulong id) + private InputLoop inputLoop; + private OutputLoop outputLoop; + public StatusCheckLoop(int interval, ulong id, InputLoop inputLoop, OutputLoop outputLoop) : base(interval, id) { + this.inputLoop = inputLoop; + this.outputLoop = outputLoop; } protected override async Task Update(int count) { Printer.PrintDbg($"Num clients: {ModelManager.Instance.Users.Count.ToString()}"); + Printer.PrintDbg($"input : {inputLoop.GetFps(),5:f0} fps"); + Printer.PrintDbg($"output: {outputLoop.GetFps(),5:f0} fps"); } } } \ No newline at end of file From a74711ba9ce23743241ac072c770664a3753ed8c Mon Sep 17 00:00:00 2001 From: shosatojp Date: Wed, 7 Apr 2021 03:46:46 +0900 Subject: [PATCH 03/13] =?UTF-8?q?unsafe=E3=81=A7=E9=AB=98=E9=80=9F?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreamClient/StreamClient.csproj | 1 + StreamServer/StreamServer.csproj | 2 +- .../StreamServerCommonLibrary.csproj | 1 + StreamServerCommonLibrary/Utility.cs | 93 ++++++++++--------- 4 files changed, 51 insertions(+), 46 deletions(-) diff --git a/StreamClient/StreamClient.csproj b/StreamClient/StreamClient.csproj index 1647094..409cdbd 100644 --- a/StreamClient/StreamClient.csproj +++ b/StreamClient/StreamClient.csproj @@ -4,6 +4,7 @@ Exe netcoreapp3.1 enable + true diff --git a/StreamServer/StreamServer.csproj b/StreamServer/StreamServer.csproj index 2a189a9..8d7095b 100644 --- a/StreamServer/StreamServer.csproj +++ b/StreamServer/StreamServer.csproj @@ -6,7 +6,7 @@ enable - + true diff --git a/StreamServerCommonLibrary/StreamServerCommonLibrary.csproj b/StreamServerCommonLibrary/StreamServerCommonLibrary.csproj index 296ef36..73b4b6e 100644 --- a/StreamServerCommonLibrary/StreamServerCommonLibrary.csproj +++ b/StreamServerCommonLibrary/StreamServerCommonLibrary.csproj @@ -5,6 +5,7 @@ CommonLibrary disable latest + true diff --git a/StreamServerCommonLibrary/Utility.cs b/StreamServerCommonLibrary/Utility.cs index e21470d..78c6f13 100644 --- a/StreamServerCommonLibrary/Utility.cs +++ b/StreamServerCommonLibrary/Utility.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using System.Runtime.InteropServices; namespace CommonLibrary { @@ -71,7 +72,7 @@ public static List BufferToPackets(byte[] buf) MinimumAvatarPacket packet = new MinimumAvatarPacket(userId, new Vector3(x, y, z), radY, new Vector4(qx, qy, qz, qw), time); - if(packet.CheckRange()) packets.Add(packet); + if (packet.CheckRange()) packets.Add(packet); } return packets; @@ -84,56 +85,58 @@ public static List BufferToPackets(byte[] buf) public static byte[] PacketToBuffer(MinimumAvatarPacket packet) { - byte[] buff = new byte[31]; - var numPackets = BitConverter.GetBytes(1); - Buffer.BlockCopy(numPackets, 0, buff, 0, sizeof(int)); - var id = BitConverter.GetBytes(packet.PaketId); - var bx = BitConverter.GetBytes(packet.Position.x); - var by = BitConverter.GetBytes(packet.Position.y); - var bz = BitConverter.GetBytes(packet.Position.z); - var bRadY = PacketUtil.ConvertByte(packet.RadY); - var bQx = PacketUtil.ConvertByte(packet.NeckRotation.x); - var bQy = PacketUtil.ConvertByte(packet.NeckRotation.y); - var bQz = PacketUtil.ConvertByte(packet.NeckRotation.z); - var bQw = PacketUtil.ConvertByte(packet.NeckRotation.w); - var time = BitConverter.GetBytes(packet.time); - byte[] body = {bRadY, bQx, bQy, bQz, bQw}; - Buffer.BlockCopy(id, 0, buff, 4, id.Length); - Buffer.BlockCopy(bx, 0, buff, 12, bx.Length); - Buffer.BlockCopy(by, 0, buff, 14, by.Length); - Buffer.BlockCopy(bz, 0, buff, 16, bz.Length); - Buffer.BlockCopy(body, 0, buff, 18, body.Length); - Buffer.BlockCopy(time, 0, buff, 23, time.Length); + int size = 31; + byte[] buff = new byte[size]; + + unsafe + { + fixed (byte* _buff = new byte[size]) + { + *(int*)&_buff[0] = 1; + *(ulong*)&_buff[4] = packet.PaketId; + *(short*)&_buff[12] = packet.Position.x; + *(short*)&_buff[14] = packet.Position.y; + *(short*)&_buff[16] = packet.Position.z; + *(byte*)&_buff[18] = (byte)packet.RadY; + *(byte*)&_buff[19] = (byte)packet.NeckRotation.x; + *(byte*)&_buff[20] = (byte)packet.NeckRotation.y; + *(byte*)&_buff[21] = (byte)packet.NeckRotation.z; + *(byte*)&_buff[22] = (byte)packet.NeckRotation.w; + *(double*)&_buff[23] = packet.time; + Marshal.Copy((IntPtr)_buff, buff, 0, buff.Length); + } + } return buff; } public static byte[] PacketsToBuffer(List packets) { - int offset = 4; - byte[] buff = new byte[27 * packets.Count + offset]; - var numPackets = BitConverter.GetBytes(packets.Count); - Buffer.BlockCopy(numPackets, 0, buff, 0, sizeof(int)); - for (int i = 0; i < packets.Count; ++i) + int size = 27 * packets.Count + 4; + byte[] buff = new byte[27 * packets.Count + size]; + + unsafe { - var packet = packets[i]; - offset = 4 + i * 27; - var id = BitConverter.GetBytes(packet.PaketId); - var bx = BitConverter.GetBytes(packet.Position.x); - var by = BitConverter.GetBytes(packet.Position.y); - var bz = BitConverter.GetBytes(packet.Position.z); - var bRadY = PacketUtil.ConvertByte(packet.RadY); - var bQx = PacketUtil.ConvertByte(packet.NeckRotation.x); - var bQy = PacketUtil.ConvertByte(packet.NeckRotation.y); - var bQz = PacketUtil.ConvertByte(packet.NeckRotation.z); - var bQw = PacketUtil.ConvertByte(packet.NeckRotation.w); - var time = BitConverter.GetBytes(packet.time); - byte[] body = {bRadY, bQx, bQy, bQz, bQw}; - Buffer.BlockCopy(id, 0, buff, offset, id.Length); - Buffer.BlockCopy(bx, 0, buff, offset += id.Length, bx.Length); - Buffer.BlockCopy(by, 0, buff, offset += bx.Length, by.Length); - Buffer.BlockCopy(bz, 0, buff, offset += by.Length, bz.Length); - Buffer.BlockCopy(body, 0, buff, offset += bz.Length, body.Length); - Buffer.BlockCopy(time, 0, buff, offset += body.Length, time.Length); + fixed (byte* _buff = new byte[27 * packets.Count + size]) + { + *(int*)&_buff[0] = packets.Count; + + for (int i = 0; i < packets.Count; ++i) + { + var packet = packets[i]; + byte* first = &_buff[4 + i * 27]; + *(ulong*)&first[0] = packet.PaketId; + *(short*)&first[8] = packet.Position.x; + *(short*)&first[10] = packet.Position.y; + *(short*)&first[12] = packet.Position.z; + *(byte*)&first[14] = (byte)packet.RadY; + *(byte*)&first[15] = (byte)packet.NeckRotation.x; + *(byte*)&first[16] = (byte)packet.NeckRotation.y; + *(byte*)&first[17] = (byte)packet.NeckRotation.z; + *(byte*)&first[18] = (byte)packet.NeckRotation.w; + *(double*)&first[19] = packet.time; + } + Marshal.Copy((IntPtr)_buff, buff, 0, buff.Length); + } } return buff; From a2035343b1142cdbd0e66b79272007befe32fdd0 Mon Sep 17 00:00:00 2001 From: shosatojp Date: Wed, 7 Apr 2021 04:00:15 +0900 Subject: [PATCH 04/13] =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF?= =?UTF-8?q?=E3=82=BF=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreamServer/Source/StreamServer/OutputLoop.cs | 18 +++++++----------- .../Source/StreamServer/PacketSender.cs | 7 +++---- StreamServerCommonLibrary/Utility.cs | 6 ++++-- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/StreamServer/Source/StreamServer/OutputLoop.cs b/StreamServer/Source/StreamServer/OutputLoop.cs index 06b7492..578cef5 100644 --- a/StreamServer/Source/StreamServer/OutputLoop.cs +++ b/StreamServer/Source/StreamServer/OutputLoop.cs @@ -3,6 +3,7 @@ using System.Net; using System.Net.Sockets; using System.Threading.Tasks; +using System.Linq; using CommonLibrary; using CommonLibrary.ExtensionMethod; using DebugPrintLibrary; @@ -55,18 +56,13 @@ protected override async Task Update(int count) if (packet != null) packets.Add(packet); } - List tasks = new List(); - foreach (var userList in users.SplitInto(Environment.ProcessorCount)) + await Task.WhenAll(users.SplitInto(Environment.ProcessorCount).Select(userList => Task.Run(async () => { - tasks.Add(Task.Run(() => - { - foreach (var user in userList) - { - PacketSender.Send(user, packets, udp); - } - })); - } - await Task.WhenAll(tasks); + foreach (var user in userList) + { + await PacketSender.Send(user, packets, udp); + } + }))); } } } diff --git a/StreamServer/Source/StreamServer/PacketSender.cs b/StreamServer/Source/StreamServer/PacketSender.cs index 03ef4a6..dd1be63 100644 --- a/StreamServer/Source/StreamServer/PacketSender.cs +++ b/StreamServer/Source/StreamServer/PacketSender.cs @@ -12,9 +12,9 @@ namespace StreamServer { public static class PacketSender { - public static void Send(User user, List packets, UdpClient udp) + public static async Task Send(User user, List packets, UdpClient udp) { - var packetCopy = packets.ToList(); + var packetCopy = packets; if (user.CurrentPacket != null) { var selfPosition = user.CurrentPacket.Position; @@ -31,10 +31,9 @@ public static void Send(User user, List packets, UdpClient if (packetCopy.Count > 100) packetCopy = packetCopy.GetRange(0, 100); var buffs = Utility.PacketsToBuffers(packetCopy); - var tasks = new List(); foreach (var buf in buffs) { - udp.Send(buf, buf.Length, user.RemoteEndPoint); + await udp.SendAsync(buf, buf.Length, user.RemoteEndPoint); } } } diff --git a/StreamServerCommonLibrary/Utility.cs b/StreamServerCommonLibrary/Utility.cs index 78c6f13..767728d 100644 --- a/StreamServerCommonLibrary/Utility.cs +++ b/StreamServerCommonLibrary/Utility.cs @@ -41,8 +41,10 @@ public static MinimumAvatarPacket BufferToPacket(byte[] buf) MinimumAvatarPacket packet = new MinimumAvatarPacket(userId, new Vector3(x, y, z), radY, new Vector4(qx, qy, qz, qw), time); - if (packet.CheckRange()) return packet; - else return null; + if (packet.CheckRange()) + return packet; + else + return null; } public static List BufferToPackets(byte[] buf) From 7d1d3500855ef5604ef15c6d1116d44a5fa7487e Mon Sep 17 00:00:00 2001 From: shosatojp Date: Wed, 7 Apr 2021 04:09:47 +0900 Subject: [PATCH 05/13] =?UTF-8?q?interval=E3=82=92=E5=8F=AF=E5=A4=89?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LoopLibrary/BaseLoop.cs | 7 ++++++- StreamServer/Source/StreamServer/Entry.cs | 15 ++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/LoopLibrary/BaseLoop.cs b/LoopLibrary/BaseLoop.cs index 8e4b8e4..f4f5e87 100644 --- a/LoopLibrary/BaseLoop.cs +++ b/LoopLibrary/BaseLoop.cs @@ -11,7 +11,7 @@ namespace LoopLibrary public abstract class BaseLoop { public readonly ulong id; - private readonly int _interval; + private int _interval; private readonly CancellationTokenSource _cts = new CancellationTokenSource(); private int _count; public CancellationTokenSource Cts => _cts; @@ -104,5 +104,10 @@ public double GetFps() } } } + + public void SetInterval(int ms) + { + _interval = ms; + } } } diff --git a/StreamServer/Source/StreamServer/Entry.cs b/StreamServer/Source/StreamServer/Entry.cs index c6f8e76..ef9f07e 100644 --- a/StreamServer/Source/StreamServer/Entry.cs +++ b/StreamServer/Source/StreamServer/Entry.cs @@ -11,7 +11,7 @@ static void Main(string[] args) { UdpClient udpClient = new UdpClient(5577); var input = new InputLoop(udpClient, 2, 1); - var output = new OutputLoop(udpClient, 33, 2); + var output = new OutputLoop(udpClient, 10, 2); var statusCheck = new StatusCheckLoop(1000, 3, input, output); input.Run(); output.Run(); @@ -28,6 +28,19 @@ static void Main(string[] args) Thread.Sleep(100); break; } + else + { + try + { + var interval = Int32.Parse(line); + output.SetInterval(interval); + Printer.PrintDbg($"Set output interval to {interval}"); + } + catch (System.Exception) + { + continue; + } + } } } } From 324bd661fcde8a1cdfcefca14d27c68e63ca8d77 Mon Sep 17 00:00:00 2001 From: shosatojp Date: Wed, 7 Apr 2021 04:36:44 +0900 Subject: [PATCH 06/13] =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreamServer/Source/StreamServer/PacketSender.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/StreamServer/Source/StreamServer/PacketSender.cs b/StreamServer/Source/StreamServer/PacketSender.cs index dd1be63..325088f 100644 --- a/StreamServer/Source/StreamServer/PacketSender.cs +++ b/StreamServer/Source/StreamServer/PacketSender.cs @@ -14,7 +14,7 @@ public static class PacketSender { public static async Task Send(User user, List packets, UdpClient udp) { - var packetCopy = packets; + var packetCopy = packets.ToList(); if (user.CurrentPacket != null) { var selfPosition = user.CurrentPacket.Position; From ac7ffe0955ef2f540c316d046af7d3aa97b4769b Mon Sep 17 00:00:00 2001 From: shosatojp Date: Wed, 7 Apr 2021 04:37:08 +0900 Subject: [PATCH 07/13] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreamServer/Source/StreamServer/OutputLoop.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/StreamServer/Source/StreamServer/OutputLoop.cs b/StreamServer/Source/StreamServer/OutputLoop.cs index 578cef5..172a5de 100644 --- a/StreamServer/Source/StreamServer/OutputLoop.cs +++ b/StreamServer/Source/StreamServer/OutputLoop.cs @@ -37,11 +37,15 @@ protected override async Task Update(int count) List users = new List(); foreach (var kvp in ModelManager.Instance.Users) { - if (kvp.Value == null) continue; + if (kvp.Value == null) + continue; var user = kvp.Value; + MinimumAvatarPacket? packet = user.CurrentPacket; { - if (user.IsConnected && packet != null && DateTime.Now - user.DateTimeBox!.LastUpdated > new TimeSpan(0, 0, 1)) + // 最終パケットが1秒以上前だったら切断したものとする + if (user.IsConnected && packet != null + && DateTime.Now - user.DateTimeBox!.LastUpdated > new TimeSpan(0, 0, 1)) { #if DEBUG Printer.PrintDbg($"Disconnected: [{user.UserId.ToString()}] " + @@ -52,10 +56,15 @@ protected override async Task Update(int count) ModelManager.Instance.Users.TryRemove(kvp.Key, out var dummy); } } - if (user.IsConnected) users.Add(user); - if (packet != null) packets.Add(packet); + + // 有効なユーザとその最新のパケットをまとめる + if (user.IsConnected) + users.Add(user); + if (packet != null) + packets.Add(packet); } + // 論理プロセッサ分に分割して並列処理 await Task.WhenAll(users.SplitInto(Environment.ProcessorCount).Select(userList => Task.Run(async () => { foreach (var user in userList) From e9875f164a1b57650597bf0fe58802701c4498f7 Mon Sep 17 00:00:00 2001 From: shosatojp Date: Wed, 7 Apr 2021 06:25:47 +0900 Subject: [PATCH 08/13] =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF?= =?UTF-8?q?=E3=82=BF=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreamServer/Source/StreamServer/InputLoop.cs | 13 +++--- .../Source/StreamServer/ModelManager.cs | 3 +- .../Source/StreamServer/PacketProcessor.cs | 42 +++++++------------ 3 files changed, 23 insertions(+), 35 deletions(-) diff --git a/StreamServer/Source/StreamServer/InputLoop.cs b/StreamServer/Source/StreamServer/InputLoop.cs index ac9918f..06bc2a0 100644 --- a/StreamServer/Source/StreamServer/InputLoop.cs +++ b/StreamServer/Source/StreamServer/InputLoop.cs @@ -18,7 +18,7 @@ public InputLoop(UdpClient udpClient, int interval, ulong id) { udp = udpClient; } - + protected override void Start() { IPEndPoint localEndPoint = (IPEndPoint)udp.Client.LocalEndPoint; @@ -32,13 +32,12 @@ protected override async Task Update(int count) { try { - UdpReceiveResult res; - res = await udp.ReceiveAsync(); - var process = PacketProcessor.Process(res); - tasks.Add(process); - } catch (SocketException e) + UdpReceiveResult res = await udp.ReceiveAsync(); + tasks.Add(Task.Run(() => PacketProcessor.Process(res))); + } + catch (SocketException e) { - if (e.ErrorCode != 10054) //Client Disconnected. + if (e.ErrorCode != 10054) // Client Disconnected. Printer.PrintDbg(e, id); } } diff --git a/StreamServer/Source/StreamServer/ModelManager.cs b/StreamServer/Source/StreamServer/ModelManager.cs index 501fdb8..b5434f5 100644 --- a/StreamServer/Source/StreamServer/ModelManager.cs +++ b/StreamServer/Source/StreamServer/ModelManager.cs @@ -5,10 +5,9 @@ namespace StreamServer { public class ModelManager { - private ModelManager(){} + private ModelManager() { } private static ModelManager? _instance; public static ModelManager Instance => _instance ??= new ModelManager(); - public readonly ConcurrentDictionary Users = new ConcurrentDictionary(); } } diff --git a/StreamServer/Source/StreamServer/PacketProcessor.cs b/StreamServer/Source/StreamServer/PacketProcessor.cs index 4216c1a..633f414 100644 --- a/StreamServer/Source/StreamServer/PacketProcessor.cs +++ b/StreamServer/Source/StreamServer/PacketProcessor.cs @@ -11,36 +11,26 @@ public static class PacketProcessor { public static async Task Process(UdpReceiveResult res) { - try + var packet = Utility.BufferToPacket(res.Buffer); + if (!ValidatePacket(packet)) { - await Task.Run(() => - { - var packet = Utility.BufferToPacket(res.Buffer); - if (!ValidatePacket(packet)) - { - return; - } - var users = ModelManager.Instance.Users; - - User? user; - if (!users.TryGetValue(packet.PaketId, out user)) - { - // RemoteEndPointから来た最初のパケットの場合 - user = users[packet.PaketId] = new User(packet.PaketId); - user.RemoteEndPoint = res.RemoteEndPoint; - Printer.PrintDbg($"Connected: [{user.UserId.ToString()}] " + - $"({res.RemoteEndPoint.Address}: {res.RemoteEndPoint.Port.ToString()})"); - } - - user.CurrentPacket = packet; - user.DateTimeBox = new DateTimeBox(DateTime.Now); - user.IsConnected = true; - }); + return; } - catch (Exception e) + var users = ModelManager.Instance.Users; + + User? user; + if (!users.TryGetValue(packet.PaketId, out user)) { - Printer.PrintDbg(e); + // RemoteEndPointから来た最初のパケットの場合 + user = users[packet.PaketId] = new User(packet.PaketId); + user.RemoteEndPoint = res.RemoteEndPoint; + Printer.PrintDbg($"Connected: [{user.UserId.ToString()}] " + + $"({res.RemoteEndPoint.Address}: {res.RemoteEndPoint.Port.ToString()})"); } + + user.CurrentPacket = packet; + user.DateTimeBox = new DateTimeBox(DateTime.Now); + user.IsConnected = true; } private static bool ValidatePacket(in MinimumAvatarPacket? packet) From 1d995db50ee045a653ef54c95adc4703982578c0 Mon Sep 17 00:00:00 2001 From: shosatojp Date: Wed, 7 Apr 2021 06:40:17 +0900 Subject: [PATCH 09/13] =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF?= =?UTF-8?q?=E3=82=BF=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreamServer/Source/StreamServer/PacketProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/StreamServer/Source/StreamServer/PacketProcessor.cs b/StreamServer/Source/StreamServer/PacketProcessor.cs index 633f414..19e4635 100644 --- a/StreamServer/Source/StreamServer/PacketProcessor.cs +++ b/StreamServer/Source/StreamServer/PacketProcessor.cs @@ -9,7 +9,7 @@ namespace StreamServer { public static class PacketProcessor { - public static async Task Process(UdpReceiveResult res) + public static void Process(UdpReceiveResult res) { var packet = Utility.BufferToPacket(res.Buffer); if (!ValidatePacket(packet)) From 2bba42874ffcaac3c4de8a2026dbb57b0217481a Mon Sep 17 00:00:00 2001 From: shosatojp Date: Wed, 7 Apr 2021 17:12:55 +0900 Subject: [PATCH 10/13] =?UTF-8?q?=E3=83=90=E3=82=B0=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreamServerCommonLibrary/Utility.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/StreamServerCommonLibrary/Utility.cs b/StreamServerCommonLibrary/Utility.cs index 767728d..8b65f95 100644 --- a/StreamServerCommonLibrary/Utility.cs +++ b/StreamServerCommonLibrary/Utility.cs @@ -114,11 +114,11 @@ public static byte[] PacketToBuffer(MinimumAvatarPacket packet) public static byte[] PacketsToBuffer(List packets) { int size = 27 * packets.Count + 4; - byte[] buff = new byte[27 * packets.Count + size]; + byte[] buff = new byte[size]; unsafe { - fixed (byte* _buff = new byte[27 * packets.Count + size]) + fixed (byte* _buff = new byte[size]) { *(int*)&_buff[0] = packets.Count; From 7a21e29fe0bcf0ef96b9071cfb8fe96f2302dc54 Mon Sep 17 00:00:00 2001 From: shosatojp Date: Wed, 7 Apr 2021 17:20:46 +0900 Subject: [PATCH 11/13] =?UTF-8?q?=E5=8F=82=E7=85=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreamServer.Test/PacketTest.cs | 12 ++++++++---- StreamServer/Source/StreamServer/PacketSender.cs | 4 ++-- StreamServerCommonLibrary/Utility.cs | 16 +++++----------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/StreamServer.Test/PacketTest.cs b/StreamServer.Test/PacketTest.cs index b70cdce..b199802 100644 --- a/StreamServer.Test/PacketTest.cs +++ b/StreamServer.Test/PacketTest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using CommonLibrary; using Xunit; using Xunit.Abstractions; @@ -20,7 +21,8 @@ public void PacketTest1() var packet = new MinimumAvatarPacket(1, new Vector3(2, 5, 6), 10, new Vector4(2, 4, 3, 120), 0); Assert.True(packet.CheckRange(), "packet.CheckRange()"); - var buff = Utility.PacketsToBuffer(new List {packet}); + var packets = new List {packet}; + var buff = Utility.PacketsToBuffer(ref packets); var decodedPacket = Utility.BufferToPackets(buff); Assert.Equal(packet.PaketId, decodedPacket![0].PaketId); Assert.Equal(packet.Position, decodedPacket![0].Position); @@ -36,7 +38,8 @@ public void PacketTest2() var packet2 = new MinimumAvatarPacket(2, new Vector3((short) 7.5f, (short) 2.6f, (short) 9.2f), 99, new Vector4(1, 9, 6, -1), 0); Assert.True(packet1.CheckRange() && packet2.CheckRange(), "packet1.CheckRange() && packet2.CheckRange()"); - var buff = Utility.PacketsToBuffer(new List {packet1, packet2}); + var packets = new List {packet1, packet2}; + var buff = Utility.PacketsToBuffer(ref packets); var decodedPacket = Utility.BufferToPackets(buff); Assert.Equal(packet1.PaketId, decodedPacket![0].PaketId); @@ -56,7 +59,8 @@ public void PacketTest3() var packet = new MinimumAvatarPacket(3, new Vector3(), 0, new Vector4(), 0); Assert.True(packet.CheckRange(), "packet.CheckRange()"); - var buff = Utility.PacketsToBuffer(new List {packet}); + var packets = new List {packet}; + var buff = Utility.PacketsToBuffer(ref packets); var decodedPacket = Utility.BufferToPackets(buff); Assert.Equal(packet.PaketId, decodedPacket![0].PaketId); Assert.Equal(packet.Position, decodedPacket![0].Position); @@ -77,7 +81,7 @@ public static void PacketTest4() Assert.True(packet.CheckRange(), $"packet.CheckRange({i})"); } - var buffs = Utility.PacketsToBuffers(packets); + var buffs = Utility.PacketsToBuffers(packets).ToList(); const int nSize = 29; for (int i = 0; i < buffs.Count; ++i) diff --git a/StreamServer/Source/StreamServer/PacketSender.cs b/StreamServer/Source/StreamServer/PacketSender.cs index 325088f..b60b235 100644 --- a/StreamServer/Source/StreamServer/PacketSender.cs +++ b/StreamServer/Source/StreamServer/PacketSender.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; @@ -30,7 +30,7 @@ public static async Task Send(User user, List packets, UdpC if (packetCopy.Count > 100) packetCopy = packetCopy.GetRange(0, 100); - var buffs = Utility.PacketsToBuffers(packetCopy); + var buffs = Utility.PacketsToBuffers(ref packetCopy); foreach (var buf in buffs) { await udp.SendAsync(buf, buf.Length, user.RemoteEndPoint); diff --git a/StreamServerCommonLibrary/Utility.cs b/StreamServerCommonLibrary/Utility.cs index 8b65f95..e94dad3 100644 --- a/StreamServerCommonLibrary/Utility.cs +++ b/StreamServerCommonLibrary/Utility.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; +using System.Linq; namespace CommonLibrary { @@ -85,7 +86,7 @@ public static List BufferToPackets(byte[] buf) return null; } - public static byte[] PacketToBuffer(MinimumAvatarPacket packet) + public static byte[] PacketToBuffer(in MinimumAvatarPacket packet) { int size = 31; byte[] buff = new byte[size]; @@ -111,7 +112,7 @@ public static byte[] PacketToBuffer(MinimumAvatarPacket packet) return buff; } - public static byte[] PacketsToBuffer(List packets) + public static byte[] PacketsToBuffer(ref List packets) { int size = 27 * packets.Count + 4; byte[] buff = new byte[size]; @@ -144,7 +145,7 @@ public static byte[] PacketsToBuffer(List packets) return buff; } - public static List PacketsToBuffers(List packets) + public static IEnumerable PacketsToBuffers(ref List packets) { var packetsList = new List>(); const int nSize = 29; @@ -152,14 +153,7 @@ public static List PacketsToBuffers(List packets) { packetsList.Add(packets.GetRange(i, Math.Min(nSize, packets.Count - i))); } - - var buffersList = new List(); - foreach (var pcs in packetsList) - { - buffersList.Add(PacketsToBuffer(pcs)); - } - - return buffersList; + return packetsList.Select(pcs => PacketsToBuffer(ref pcs)); } } } \ No newline at end of file From d7e8b40b48271fcbdc67ced98dd8495be57ff725 Mon Sep 17 00:00:00 2001 From: shosatojp Date: Wed, 7 Apr 2021 17:23:46 +0900 Subject: [PATCH 12/13] =?UTF-8?q?=E3=83=92=E3=83=BC=E3=83=97=E3=82=BD?= =?UTF-8?q?=E3=83=BC=E3=83=88=E5=8A=B9=E7=8E=87=E6=94=B9=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreamServer/Source/StreamServer/PacketSender.cs | 7 ++++--- StreamServerCommonLibrary/ExtensionMethod/HeapSort.cs | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/StreamServer/Source/StreamServer/PacketSender.cs b/StreamServer/Source/StreamServer/PacketSender.cs index b60b235..30004a8 100644 --- a/StreamServer/Source/StreamServer/PacketSender.cs +++ b/StreamServer/Source/StreamServer/PacketSender.cs @@ -15,6 +15,7 @@ public static class PacketSender public static async Task Send(User user, List packets, UdpClient udp) { var packetCopy = packets.ToList(); + const int maxCount = 100; if (user.CurrentPacket != null) { var selfPosition = user.CurrentPacket.Position; @@ -25,11 +26,11 @@ public static async Task Send(User user, List packets, UdpC var bSquare = Vector3.Square(b.Position, selfPosition); var comp = aSquare < bSquare ? -1 : 1; return comp; - }); + }, maxCount); } - if (packetCopy.Count > 100) - packetCopy = packetCopy.GetRange(0, 100); + if (packetCopy.Count > maxCount) + packetCopy = packetCopy.GetRange(0, maxCount); var buffs = Utility.PacketsToBuffers(ref packetCopy); foreach (var buf in buffs) { diff --git a/StreamServerCommonLibrary/ExtensionMethod/HeapSort.cs b/StreamServerCommonLibrary/ExtensionMethod/HeapSort.cs index 8c4a793..0ef6501 100644 --- a/StreamServerCommonLibrary/ExtensionMethod/HeapSort.cs +++ b/StreamServerCommonLibrary/ExtensionMethod/HeapSort.cs @@ -15,7 +15,7 @@ public static class ListExtension /// /// /// - public static void HeapSort(this List array, Comparison comparison) + public static void HeapSort(this List array, Comparison comparison, int? count = null) { // 必要なヒープ用配列を確保します var heap = new T[array.Count]; @@ -26,7 +26,7 @@ public static void HeapSort(this List array, Comparison comparison) Insert(ref num, ref heap, array[target], comparison); // ヒープから取り出しながら配列に格納します。 - for (var target = 0; num > 0; target++) + for (var target = 0; num > 0 && (count != null && target < count); target++) array[target] = DeleteGetValue(ref num, ref heap, comparison); } From a460ac9b4c92a88572b488b4c90fe1fc475bb790 Mon Sep 17 00:00:00 2001 From: shosatojp Date: Wed, 7 Apr 2021 17:33:48 +0900 Subject: [PATCH 13/13] =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreamServer.Test/PacketTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/StreamServer.Test/PacketTest.cs b/StreamServer.Test/PacketTest.cs index b199802..42f6626 100644 --- a/StreamServer.Test/PacketTest.cs +++ b/StreamServer.Test/PacketTest.cs @@ -81,7 +81,7 @@ public static void PacketTest4() Assert.True(packet.CheckRange(), $"packet.CheckRange({i})"); } - var buffs = Utility.PacketsToBuffers(packets).ToList(); + var buffs = Utility.PacketsToBuffers(ref packets).ToList(); const int nSize = 29; for (int i = 0; i < buffs.Count; ++i)