feat: init all packetHandler once & reuse
All checks were successful
Test if Server can be built / build-server (push) Successful in 24s
All checks were successful
Test if Server can be built / build-server (push) Successful in 24s
This commit is contained in:
parent
63c29f21df
commit
010f05c565
1 changed files with 30 additions and 17 deletions
|
@ -1,13 +1,14 @@
|
||||||
namespace Server.Services;
|
namespace Server.Services;
|
||||||
|
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using DotNext.Collections.Generic;
|
||||||
using MassTransit.Internals;
|
using MassTransit.Internals;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.VisualBasic.CompilerServices;
|
using Microsoft.VisualBasic.CompilerServices;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using PacketHandlers;
|
using PacketHandlers;
|
||||||
using Packets;
|
using Packets;
|
||||||
using static DotNext.Metaprogramming.CodeGenerator;
|
using static DotNext.Metaprogramming.CodeGenerator;
|
||||||
|
@ -17,8 +18,12 @@ public class PacketDistributorService : IHostedService
|
||||||
{
|
{
|
||||||
private readonly ConcurrentQueue<RawPacket> concurrentQueue;
|
private readonly ConcurrentQueue<RawPacket> concurrentQueue;
|
||||||
private readonly ILogger<PacketDistributorService> logger;
|
private readonly ILogger<PacketDistributorService> logger;
|
||||||
private readonly Dictionary<OperationCode, Type> packetHandlers;
|
private readonly ConcurrentDictionary<OperationCode, object> packetHandlersInstantiation;
|
||||||
private readonly Dictionary<OperationCode, Func<byte[], IPacket>> deserializationMap;
|
|
||||||
|
private readonly
|
||||||
|
ImmutableDictionary<OperationCode,
|
||||||
|
Func<byte[], IPacket>> deserializationMap;
|
||||||
|
|
||||||
private readonly IServiceProvider serviceProvider;
|
private readonly IServiceProvider serviceProvider;
|
||||||
|
|
||||||
public PacketDistributorService(ILogger<PacketDistributorService> logger, IServiceProvider serviceProvider)
|
public PacketDistributorService(ILogger<PacketDistributorService> logger, IServiceProvider serviceProvider)
|
||||||
|
@ -26,29 +31,38 @@ public class PacketDistributorService : IHostedService
|
||||||
this.concurrentQueue = new ConcurrentQueue<RawPacket>();
|
this.concurrentQueue = new ConcurrentQueue<RawPacket>();
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.serviceProvider = serviceProvider;
|
this.serviceProvider = serviceProvider;
|
||||||
this.packetHandlers = new Dictionary<OperationCode, Type>();
|
var tempDeserializationMap =
|
||||||
this.deserializationMap = new Dictionary<OperationCode, Func<byte[], IPacket>>();
|
new Dictionary<OperationCode, Func<byte[], IPacket>>();
|
||||||
|
|
||||||
var executingAssembly = Assembly.GetExecutingAssembly();
|
var executingAssembly = Assembly.GetExecutingAssembly();
|
||||||
var packetsTypes = this.GetPacketsWithId(executingAssembly);
|
var packetsTypes = this.GetPacketsWithId(executingAssembly);
|
||||||
this.packetHandlers = this.GetAllPacketHandlersWithId(executingAssembly);
|
var packetHandlers = this.GetAllPacketHandlersWithId(executingAssembly);
|
||||||
|
this.packetHandlersInstantiation = new ConcurrentDictionary<OperationCode, object>();
|
||||||
|
packetHandlers.ForEach(x =>
|
||||||
|
{
|
||||||
|
var packetHandler =
|
||||||
|
ActivatorUtilities.GetServiceOrCreateInstance(this.serviceProvider,
|
||||||
|
x.Value);
|
||||||
|
this.packetHandlersInstantiation.TryAdd(x.Key, packetHandler);
|
||||||
|
});
|
||||||
foreach (var packetsType in packetsTypes)
|
foreach (var packetsType in packetsTypes)
|
||||||
{
|
{
|
||||||
var lambda = Lambda<Func<byte[], IPacket>>(fun =>
|
var lambda = Lambda<Func<byte[], IPacket>>(fun =>
|
||||||
{
|
{
|
||||||
var arg = fun[0];
|
var argPacketData = fun[0];
|
||||||
var newPacket = packetsType.Value.New();
|
var newPacket = packetsType.Value.New();
|
||||||
|
|
||||||
var packetVariable = DeclareVariable(packetsType.Value, "packet");
|
var packetVariable = DeclareVariable(packetsType.Value, "packet");
|
||||||
Assign(packetVariable, newPacket);
|
Assign(packetVariable, newPacket);
|
||||||
Call(packetVariable, nameof(IPacket.Deserialize), arg);
|
Call(packetVariable, nameof(IPacket.Deserialize), argPacketData);
|
||||||
|
|
||||||
Return(packetVariable);
|
Return(packetVariable);
|
||||||
}).Compile();
|
}).Compile();
|
||||||
logger.LogInformation("Packet creation function created for {Opcode}", packetsType.Key);
|
logger.LogInformation("Packet creation function created for {Opcode}", packetsType.Key);
|
||||||
this.deserializationMap.Add(packetsType.Key, lambda);
|
tempDeserializationMap.Add(packetsType.Key, lambda);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.deserializationMap = tempDeserializationMap.ToImmutableDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||||
|
@ -81,7 +95,8 @@ public class PacketDistributorService : IHostedService
|
||||||
t is { IsClass: true, IsAbstract: false } && t
|
t is { IsClass: true, IsAbstract: false } && t
|
||||||
.GetInterfaces().Any(i =>
|
.GetInterfaces().Any(i =>
|
||||||
i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IPacketHandler<>))).ToDictionary(type =>
|
i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IPacketHandler<>))).ToDictionary(type =>
|
||||||
type.GetInterfaces().First(t =>t is { IsGenericType: true} && t.GetGenericTypeDefinition() == typeof(IPacketHandler<>))
|
type.GetInterfaces().First(t =>
|
||||||
|
t is { IsGenericType: true } && t.GetGenericTypeDefinition() == typeof(IPacketHandler<>))
|
||||||
.GetGenericArguments().First().GetCustomAttribute<PacketIdAttribute>()!.Code);
|
.GetGenericArguments().First().GetCustomAttribute<PacketIdAttribute>()!.Code);
|
||||||
|
|
||||||
if (packetHandlersWithId is not { Count: 0 })
|
if (packetHandlersWithId is not { Count: 0 })
|
||||||
|
@ -126,12 +141,10 @@ public class PacketDistributorService : IHostedService
|
||||||
}
|
}
|
||||||
|
|
||||||
var packet = this.deserializationMap[item.OperationCode](item.MessageBody);
|
var packet = this.deserializationMap[item.OperationCode](item.MessageBody);
|
||||||
var packetHandler =
|
this.packetHandlersInstantiation[item.OperationCode].GetType().GetMethod("HandleAsync")
|
||||||
ActivatorUtilities.GetServiceOrCreateInstance(this.serviceProvider,
|
?.Invoke(this.packetHandlersInstantiation[item.OperationCode], new object[] { packet, item.Session });
|
||||||
this.packetHandlers[item.OperationCode]);
|
|
||||||
packetHandler.GetType().GetMethod("HandleAsync")
|
//this.logger.LogDebug("Packet data {PacketData}", JsonConvert.SerializeObject(packet));
|
||||||
?.Invoke(packetHandler, new object[] { packet, item.Session });
|
|
||||||
this.logger.LogDebug("Packet data {PacketData}", JsonConvert.SerializeObject(packet));
|
|
||||||
this.logger.LogTrace("[{TempId}] Packet with ID: {MessageOperationCode} has finished",
|
this.logger.LogTrace("[{TempId}] Packet with ID: {MessageOperationCode} has finished",
|
||||||
item.Session.Id,
|
item.Session.Id,
|
||||||
item.OperationCode);
|
item.OperationCode);
|
||||||
|
|
Loading…
Reference in a new issue