1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-10-04 02:11:11 +00:00
Files
CryptoExchange.Net/CryptoExchange.Net/Sockets/Default/Routing/MessageRouter.cs
T

206 lines
8.3 KiB
C#

using CryptoExchange.Net.Objects;
using System;
using System.Collections.Generic;
using System.Linq;
namespace CryptoExchange.Net.Sockets.Default.Routing
{
/// <summary>
/// Message router
/// </summary>
public class MessageRouter
{
private ProcessorRouter? _routingTable;
/// <summary>
/// The routes registered for this router
/// </summary>
public MessageRoute[] Routes { get; }
/// <summary>
/// ctor
/// </summary>
private MessageRouter(params MessageRoute[] routes)
{
Routes = routes;
}
private RouteCollection? GetRoutes(string typeIdentifier)
=> (_routingTable ?? throw new NullReferenceException("Routing table not build before handling")).GetRoutes(typeIdentifier);
/// <summary>
/// Build the route mapping
/// </summary>
public void BuildQueryRouter()
{
_routingTable = new QueryRouter(Routes);
}
/// <summary>
/// Build the route mapping
/// </summary>
public void BuildSubscriptionRouter()
{
_routingTable = new SubscriptionRouter(Routes);
}
/// <summary>
/// Handle message
/// </summary>
public bool Handle(string typeIdentifier, string? topicFilter, SocketConnection connection, DateTime receiveTime, string? originalData, object data, out CallResult? result)
{
var routeCollection = GetRoutes(typeIdentifier);
if (routeCollection == null)
throw new InvalidOperationException($"No routes for {typeIdentifier} message type");
return routeCollection.Handle(topicFilter, connection, receiveTime, originalData, data, out result);
}
/// <summary>
/// Whether the router has a matching route for the specified message type and topic
/// </summary>
public bool CanHandle(string typeIdentifier, string? topicFilter)
{
return GetRoutes(typeIdentifier)?.CanHandle(topicFilter) == true;
}
/// <summary>
/// Create a void handler
/// </summary>
public static MessageRouter CreateVoid<TMessage>(string typeIdentifier)
{
return new MessageRouter(new EventRoute<TMessage>(typeIdentifier, null, (con, time, originalData, msg) => CallResult<TMessage>.Ok(default!)));
}
/// <summary>
/// Create a router for handling event messages
/// </summary>
public static MessageRouter CreateForEvent<TMessage>(string typeIdentifier, Func<SocketConnection, DateTime, string?, TMessage, CallResult?> handler, bool multipleReaders = false)
{
return new MessageRouter(new EventRoute<TMessage>(typeIdentifier, null, handler)
{
MultipleReaders = multipleReaders
});
}
/// <summary>
/// Create a router for handling event messages
/// </summary>
public static MessageRouter CreateForEvent<TMessage>(IEnumerable<string> typeIdentifier, Func<SocketConnection, DateTime, string?, TMessage, CallResult?> handler, bool multipleReaders = false)
{
return new MessageRouter(typeIdentifier.Select(x => new EventRoute<TMessage>(x, null, handler)
{
MultipleReaders = multipleReaders
}).ToArray());
}
/// <summary>
/// Create a router for handling event messages
/// </summary>
public static MessageRouter CreateForEvent<TMessage>(IEnumerable<string> typeIdentifier, IEnumerable<string> topicFilters, Func<SocketConnection, DateTime, string?, TMessage, CallResult?> handler, bool multipleReaders = false)
{
return new MessageRouter(typeIdentifier.SelectMany(x => {
var routes = new List<MessageRoute>();
foreach (var topicFilter in topicFilters)
{
routes.Add(new EventRoute<TMessage>(x, topicFilter, handler)
{
MultipleReaders = multipleReaders
});
}
return routes;
}).ToArray());
}
/// <summary>
/// Create a router for handling event messages
/// </summary>
public static MessageRouter CreateForEvent<TMessage>(string typeIdentifier, string? topicFilter, Func<SocketConnection, DateTime, string?, TMessage, CallResult?> handler, bool multipleReaders = false)
{
return new MessageRouter(new EventRoute<TMessage>(typeIdentifier, topicFilter, handler)
{
MultipleReaders = multipleReaders
});
}
/// <summary>
/// Create a router for handling event messages
/// </summary>
public static MessageRouter CreateForEvent<TMessage>(string typeIdentifier, IEnumerable<string> topicFilters, Func<SocketConnection, DateTime, string?, TMessage, CallResult?> handler, bool multipleReaders = false)
{
return new MessageRouter(topicFilters.Select(x => new EventRoute<TMessage>(typeIdentifier, x, handler)
{
MultipleReaders = multipleReaders
}).ToArray());
}
/// <summary>
/// Create a router for handling query responses
/// </summary>
public static MessageRouter CreateForQuery<TMessage>(IEnumerable<string> typeIdentifier, Func<SocketConnection, DateTime, string?, TMessage, CallResult<TMessage>?> handler, bool multipleReaders = false)
{
return new MessageRouter(typeIdentifier.Select(x => new QueryRoute<TMessage>(x, null, handler)
{
MultipleReaders = multipleReaders
}).ToArray());
}
/// <summary>
/// Create a router for handling query responses
/// </summary>
public static MessageRouter CreateForQuery<TMessage>(string typeIdentifier, Func<SocketConnection, DateTime, string?, TMessage, CallResult<TMessage>?> handler, bool multipleReaders = false)
{
return new MessageRouter(new QueryRoute<TMessage>(typeIdentifier, null, handler)
{
MultipleReaders = multipleReaders
});
}
/// <summary>
/// Create a router for handling query responses
/// </summary>
public static MessageRouter CreateForQuery<TMessage>(string typeIdentifier, string? topicFilter, Func<SocketConnection, DateTime, string?, TMessage, CallResult<TMessage>?> handler, bool multipleReaders = false)
{
return new MessageRouter(new QueryRoute<TMessage>(typeIdentifier, topicFilter, handler)
{
MultipleReaders = multipleReaders
});
}
/// <summary>
/// Create a router for handling query responses
/// </summary>
public static MessageRouter CreateForQuery<TMessage, TResult>(string typeIdentifier, Func<SocketConnection, DateTime, string?, TMessage, CallResult<TResult>?> handler, bool multipleReaders = false)
{
return new MessageRouter(new QueryRoute<TMessage, TResult>(typeIdentifier, null, handler)
{
MultipleReaders = multipleReaders
});
}
/// <summary>
/// Create a router for handling query responses
/// </summary>
public static MessageRouter CreateForQuery<TMessage, TResult>(string typeIdentifier, string? topicFilter, Func<SocketConnection, DateTime, string?, TMessage, CallResult<TResult>?> handler, bool multipleReaders = false)
{
return new MessageRouter(new QueryRoute<TMessage, TResult>(typeIdentifier, topicFilter, handler)
{
MultipleReaders = multipleReaders
});
}
/// <summary>
/// Create message matcher with specific routes
/// </summary>
public static MessageRouter Create(params MessageRoute[] routes)
{
return new MessageRouter(routes);
}
/// <summary>
/// Whether this matcher contains a specific link
/// </summary>
public bool ContainsCheck(MessageRoute route) => Routes.Any(x => x.TypeIdentifier == route.TypeIdentifier && x.TopicFilter == route.TopicFilter);
}
}