1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2026-04-07 02:01:12 +00:00
This commit is contained in:
JKorf 2026-04-06 12:10:13 +02:00
parent 406ae08c17
commit 08d361b259
5 changed files with 70 additions and 21 deletions

View File

@ -24,7 +24,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
if (string.IsNullOrEmpty(value))
return default;
return (T?)JsonDocument.Parse(value!).Deserialize(typeof(T), options);
return JsonDocument.Parse(value!).Deserialize<T>(options);
}
/// <inheritdoc />

View File

@ -522,19 +522,13 @@ namespace CryptoExchange.Net.Sockets.Default
}
Type? deserializationType = null;
foreach (var subscription in _listeners)
foreach (var listener in _listeners)
{
foreach (var route in subscription.MessageRouter.Routes)
{
if (!route.TypeIdentifier.Equals(typeIdentifier, StringComparison.Ordinal))
continue;
deserializationType = route.DeserializationType;
var routes = listener.MessageRouter[typeIdentifier];
if (routes.Count > 0) {
deserializationType = routes[0].DeserializationType;
break;
}
if (deserializationType != null)
break;
}
if (deserializationType == null)
@ -581,11 +575,13 @@ namespace CryptoExchange.Net.Sockets.Default
var topicFilter = messageConverter.GetTopicFilter(result);
bool processed = false;
foreach (var processor in _listeners)
foreach (var listener in _listeners)
{
var routes = listener.MessageRouter[typeIdentifier];
bool isQuery = false;
Query? query = null;
if (processor is Query cquery)
if (listener is Query cquery)
{
isQuery = true;
query = cquery;
@ -593,11 +589,8 @@ namespace CryptoExchange.Net.Sockets.Default
var complete = false;
foreach (var route in processor.MessageRouter.Routes)
foreach (var route in routes)
{
if (route.TypeIdentifier != typeIdentifier)
continue;
// Forward message rules:
// | Message Topic | Route Topic Filter | Topics Match | Forward | Description
// | N | N | - | Y | No topic filter applied
@ -623,7 +616,7 @@ namespace CryptoExchange.Net.Sockets.Default
if (isQuery && query!.Completed)
continue;
processor.Handle(this, receiveTime, originalData, result, route);
listener.Handle(this, receiveTime, originalData, result, route);
if (isQuery && !route.MultipleReaders)
{
complete = true;

View File

@ -70,10 +70,20 @@ namespace CryptoExchange.Net.Sockets.Default
/// </summary>
public bool Authenticated { get; }
private MessageRouter _router;
/// <summary>
/// Router for this subscription
/// </summary>
public MessageRouter MessageRouter { get; set; }
public MessageRouter MessageRouter
{
get => _router;
set
{
_router = value;
_router.BuildRouteMap();
}
}
/// <summary>
/// Cancellation token registration

View File

@ -1,6 +1,9 @@
using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Sockets.Default;
using System;
#if NET8_0_OR_GREATER
using System.Collections.Frozen;
#endif
using System.Collections.Generic;
using System.Linq;
@ -16,6 +19,12 @@ namespace CryptoExchange.Net.Sockets
/// </summary>
public MessageRoute[] Routes { get; }
#if NET8_0_OR_GREATER
private FrozenDictionary<string, List<MessageRoute>>? _routeMap;
#else
private Dictionary<string, List<MessageRoute>>? _routeMap;
#endif
/// <summary>
/// ctor
/// </summary>
@ -24,6 +33,34 @@ namespace CryptoExchange.Net.Sockets
Routes = routes;
}
/// <summary>
/// Build the route mapping
/// </summary>
public void BuildRouteMap()
{
var newMap = new Dictionary<string, List<MessageRoute>>();
foreach (var route in Routes)
{
if (!newMap.ContainsKey(route.TypeIdentifier))
newMap.Add(route.TypeIdentifier, new List<MessageRoute>());
newMap[route.TypeIdentifier].Add(route);
}
#if NET8_0_OR_GREATER
_routeMap = newMap.ToFrozenDictionary();
#else
_routeMap = newMap;
#endif
}
/// <summary>
/// Get routes matching the type identifier
/// </summary>
public List<MessageRoute> this[string identifier]
{
get => (_routeMap ?? throw new InvalidOperationException("Route map not initialized before use")).TryGetValue(identifier, out var routes) ? routes: [];
}
/// <summary>
/// Create message router without specific message handler
/// </summary>

View File

@ -59,10 +59,19 @@ namespace CryptoExchange.Net.Sockets
/// </summary>
public object? Response { get; set; }
private MessageRouter _router;
/// <summary>
/// Router for this query
/// Router for this subscription
/// </summary>
public MessageRouter MessageRouter { get; set; }
public MessageRouter MessageRouter
{
get => _router;
set
{
_router = value;
_router.BuildRouteMap();
}
}
/// <summary>
/// The query request object