1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-06-22 15:26:17 +00:00
This commit is contained in:
JKorf 2024-01-20 19:36:08 +01:00
parent e3207033c3
commit fc6503035a
29 changed files with 14 additions and 400 deletions

View File

@ -1,5 +1,4 @@
using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Authentication;
using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Objects.Options; using CryptoExchange.Net.Objects.Options;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;

View File

@ -1,4 +1,3 @@
using CryptoExchange.Net.Converters;
using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Interfaces;
using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Objects.Options; using CryptoExchange.Net.Objects.Options;
@ -41,11 +40,6 @@ namespace CryptoExchange.Net
/// </summary> /// </summary>
protected TimeSpan KeepAliveInterval { get; set; } = TimeSpan.FromSeconds(10); protected TimeSpan KeepAliveInterval { get; set; } = TimeSpan.FromSeconds(10);
/// <summary>
/// Delegate used for manipulating data received from socket connections before it is processed by listeners
/// </summary>
protected Func<Stream, Stream>? interceptor;
/// <summary> /// <summary>
/// Handlers for data from the socket which doesn't need to be forwarded to the caller. Ping or welcome messages for example. /// Handlers for data from the socket which doesn't need to be forwarded to the caller. Ping or welcome messages for example.
/// </summary> /// </summary>
@ -498,7 +492,6 @@ namespace CryptoExchange.Net
protected virtual WebSocketParameters GetWebSocketParameters(string address) protected virtual WebSocketParameters GetWebSocketParameters(string address)
=> new(new Uri(address), ClientOptions.AutoReconnect) => new(new Uri(address), ClientOptions.AutoReconnect)
{ {
Interceptor = interceptor,
KeepAliveInterval = KeepAliveInterval, KeepAliveInterval = KeepAliveInterval,
ReconnectInterval = ClientOptions.ReconnectInterval, ReconnectInterval = ClientOptions.ReconnectInterval,
RateLimiters = RateLimiters, RateLimiters = RateLimiters,

View File

@ -1,8 +1,4 @@
using System; namespace CryptoExchange.Net.CommonObjects
using System.Collections.Generic;
using System.Text;
namespace CryptoExchange.Net.CommonObjects
{ {
/// <summary> /// <summary>
/// Order type /// Order type

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
namespace CryptoExchange.Net.CommonObjects namespace CryptoExchange.Net.CommonObjects
{ {

View File

@ -1,8 +1,4 @@
using System; namespace CryptoExchange.Net.CommonObjects
using System.Collections.Generic;
using System.Text;
namespace CryptoExchange.Net.CommonObjects
{ {
/// <summary> /// <summary>
/// Id of an order /// Id of an order

View File

@ -1,6 +1,4 @@
using System; namespace CryptoExchange.Net.CommonObjects
namespace CryptoExchange.Net.CommonObjects
{ {
/// <summary> /// <summary>
/// Ticker data /// Ticker data

View File

@ -1,158 +0,0 @@
//using CryptoExchange.Net.Interfaces;
//using CryptoExchange.Net.Objects.Sockets;
//using Newtonsoft.Json;
//using Newtonsoft.Json.Linq;
//using System;
//using System.Collections.Generic;
//using System.IO;
//using System.Linq;
//using System.Runtime.InteropServices.ComTypes;
//using System.Text;
//namespace CryptoExchange.Net.Converters
//{
// internal class JTokenAccessor : IMessageAccessor
// {
// private readonly JToken _token;
// private readonly Stream _stream;
// private readonly StreamReader _reader;
// private Dictionary<string, JToken?> _cache = new Dictionary<string, JToken?>();
// private static JsonSerializer _serializer = JsonSerializer.Create(SerializerOptions.WithConverters);
// public JTokenAccessor(Stream stream)
// {
// _stream = stream;
// _reader = new StreamReader(stream, Encoding.UTF8, false, (int)stream.Length, true);
// using var jsonTextReader = new JsonTextReader(_reader);
// JToken token;
// try
// {
// _token = JToken.Load(jsonTextReader);
// }
// catch (Exception ex)
// {
// // Not a json message
// throw;
// }
// }
// public BaseParsedMessage Instantiate(Type type)
// {
// var resultMessageType = typeof(ParsedMessage<>).MakeGenericType(type);
// var instance = (BaseParsedMessage)Activator.CreateInstance(resultMessageType, type == null ? null : _token.ToObject(type, _serializer));
// return instance;
// }
// public string GetOriginalString()
// {
// _stream.Position = 0;
// return _reader.ReadToEnd();
// }
// public int? GetArrayIntValue(string? key, int index)
// {
// var accessToken = key == null ? _token : GetToken(key);
// if (accessToken == null || accessToken is not JArray arr)
// return null;
// return arr[index].Value<int>();
// }
// public string? GetArrayStringValue(string? key, int index)
// {
// var accessToken = key == null ? _token : GetToken(key);
// if (accessToken == null || accessToken is not JArray arr)
// return null;
// if (arr.Count <= index)
// return null;
// if (arr[index].Type != JTokenType.String)
// return null;
// return arr[index].Value<string>();
// }
// public int? GetCount(string key)
// {
// var accessToken = GetToken(key);
// return accessToken.Count();
// }
// public int? GetIntValue(string key)
// {
// var accessToken = GetToken(key);
// return accessToken?.Value<int>();
// }
// public string? GetStringValue(string key)
// {
// var accessToken = GetToken(key);
// if (accessToken?.Type == JTokenType.Object)
// return ((JObject)accessToken).Properties().First().Name;
// return accessToken?.ToString();
// }
// public bool IsObject(string? key) => _token.Type == JTokenType.Object;
// public bool IsArray(IEnumerable<int> indexes)
// {
// var item = _token;
// foreach(var index in indexes)
// {
// if (item.Type != JTokenType.Array)
// return false;
// var arr = ((JArray)item);
// if (arr.Count <= index)
// return false;
// item = arr[index];
// }
// return item.Type == JTokenType.Array;
// }
// public bool IsEmptyArray(IEnumerable<int> indexes)
// {
// var item = _token;
// foreach (var index in indexes)
// {
// if (item.Type != JTokenType.Array)
// return false;
// var arr = ((JArray)item);
// if (arr.Count <= index)
// return false;
// item = arr[index];
// }
// return item.Type == JTokenType.Array && !item.HasValues;
// }
// private JToken? GetToken(string key)
// {
// if (key == null)
// return _token;
// if (_cache.TryGetValue(key, out var token))
// return token;
// var splitTokens = key.Split(new char[] { ':' });
// var accessToken = _token;
// foreach (var splitToken in splitTokens)
// {
// if (accessToken.Type == JTokenType.Array)
// return null;
// accessToken = accessToken[splitToken];
// if (accessToken == null)
// break;
// }
// _cache.Add(key, accessToken);
// return accessToken;
// }
// }
//}

View File

@ -1,58 +0,0 @@
//using CryptoExchange.Net.Interfaces;
//using CryptoExchange.Net.Objects;
//using CryptoExchange.Net.Objects.Sockets;
//using CryptoExchange.Net.Sockets;
//using Newtonsoft.Json;
//using Newtonsoft.Json.Linq;
//using System;
//using System.Collections.Generic;
//using System.IO;
//using System.Linq;
//using System.Net.WebSockets;
//using System.Text;
//namespace CryptoExchange.Net.Converters
//{
// /// <summary>
// /// Socket message converter
// /// </summary>
// public abstract class SocketConverter
// {
// public abstract MessageInterpreterPipeline InterpreterPipeline { get; }
// /// <inheritdoc />
// public BaseParsedMessage? ReadJson(WebSocketMessageType websocketMessageType, Stream stream, SocketListenerManager listenerManager, bool outputOriginalData)
// {
// // Start reading the data
// // Once we reach the properties that identify the message we save those in a dict
// // Once all id properties have been read callback to see what the deserialization type should be
// // Deserialize to the correct type
// if (InterpreterPipeline.PreProcessCallback != null)
// stream = InterpreterPipeline.PreProcessCallback(websocketMessageType, stream);
// var accessor = new JTokenAccessor(stream);
// if (accessor == null)
// return null;
// var streamIdentity = InterpreterPipeline.GetStreamIdentifier(accessor);
// if (streamIdentity == null)
// return null;
// var typeIdentity = InterpreterPipeline.GetTypeIdentifier(accessor);
// var typeResult = listenerManager.IdToType(streamIdentity, typeIdentity);
// if (typeResult == null)
// return null;
// var idInstance = accessor.Instantiate(typeResult);
// if (outputOriginalData)
// idInstance.OriginalData = idInstance.OriginalData;
// idInstance.StreamIdentifier = streamIdentity;
// idInstance.TypeIdentifier = typeIdentity;
// idInstance.Parsed = true;
// return idInstance;
// }
// }
//}

View File

@ -2,7 +2,6 @@
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using CryptoExchange.Net.CommonObjects; using CryptoExchange.Net.CommonObjects;
using CryptoExchange.Net.Interfaces.CommonClients;
using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.Interfaces.CommonClients namespace CryptoExchange.Net.Interfaces.CommonClients

View File

@ -1,5 +1,4 @@
using CryptoExchange.Net.CommonObjects; using CryptoExchange.Net.CommonObjects;
using CryptoExchange.Net.Interfaces.CommonClients;
using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;

View File

@ -3,7 +3,6 @@ using CryptoExchange.Net.Objects.Sockets;
using CryptoExchange.Net.Sockets; using CryptoExchange.Net.Sockets;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace CryptoExchange.Net.Interfaces namespace CryptoExchange.Net.Interfaces

View File

@ -1,5 +1,4 @@
using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Objects.Options;
using System; using System;
using System.Net.Http; using System.Net.Http;

View File

@ -1,7 +1,4 @@
using CryptoExchange.Net.Objects; namespace CryptoExchange.Net.Interfaces
using System;
namespace CryptoExchange.Net.Interfaces
{ {
/// <summary> /// <summary>
/// Base rest API client /// Base rest API client

View File

@ -1,6 +1,4 @@
using System; using System;
using CryptoExchange.Net.Authentication;
using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Objects.Options; using CryptoExchange.Net.Objects.Options;
namespace CryptoExchange.Net.Interfaces namespace CryptoExchange.Net.Interfaces

View File

@ -1,7 +1,5 @@
using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects.Options;
using CryptoExchange.Net.Objects.Options;
using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Objects.Sockets;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace CryptoExchange.Net.Interfaces namespace CryptoExchange.Net.Interfaces

View File

@ -1,7 +1,5 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using CryptoExchange.Net.Authentication;
using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Objects.Options; using CryptoExchange.Net.Objects.Options;
using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Objects.Sockets;

View File

@ -1,10 +1,6 @@
using CryptoExchange.Net.Objects; using System;
using CryptoExchange.Net.Sockets;
using System;
using System.IO; using System.IO;
using System.Net.WebSockets; using System.Net.WebSockets;
using System.Security.Authentication;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace CryptoExchange.Net.Interfaces namespace CryptoExchange.Net.Interfaces

View File

@ -1,54 +0,0 @@
//namespace CryptoExchange.Net.Objects.Sockets
//{
// /// <summary>
// /// Parsed message object
// /// </summary>
// public abstract class BaseParsedMessage
// {
// /// <summary>
// /// Stream identifier string
// /// </summary>
// public string StreamIdentifier { get; set; } = null!;
// /// <summary>
// /// Type identifier string
// /// </summary>
// public string TypeIdentifier { get; set; } = null!;
// /// <summary>
// /// Original data if the option is enabled
// /// </summary>
// public string? OriginalData { get; set; }
// /// <summary>
// /// If parsed
// /// </summary>
// public bool Parsed { get; set; }
// /// <summary>
// /// Get the data object
// /// </summary>
// /// <returns></returns>
// public abstract object Data { get; }
// }
// /// <summary>
// /// Parsed message object
// /// </summary>
// /// <typeparam name="T">Data type</typeparam>
// public class ParsedMessage<T> : BaseParsedMessage
// {
// /// <summary>
// /// Parsed data object
// /// </summary>
// public override object? Data { get; }
// public T? TypedData => (T)Data;
// /// <summary>
// /// ctor
// /// </summary>
// /// <param name="data"></param>
// public ParsedMessage(T? data)
// {
// Data = data;
// }
// }
//}

View File

@ -1,19 +0,0 @@
//using CryptoExchange.Net.Converters;
//using CryptoExchange.Net.Interfaces;
//using CryptoExchange.Net.Sockets;
//using Newtonsoft.Json.Linq;
//using System;
//using System.Collections.Generic;
//using System.IO;
//using System.Net.WebSockets;
//using System.Text;
//namespace CryptoExchange.Net.Objects.Sockets
//{
// public class MessageInterpreterPipeline
// {
// public Func<WebSocketMessageType, Stream, Stream>? PreProcessCallback { get; set; }
// public Func<IMessageAccessor, string?> GetStreamIdentifier { get; set; }
// public Func<IMessageAccessor, string, string?> GetTypeIdentifier { get; set; } = (accessor, streamId) => streamId;
// }
//}

View File

@ -1,5 +1,4 @@
using CryptoExchange.Net.Objects; using CryptoExchange.Net.Sockets;
using CryptoExchange.Net.Sockets;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;

View File

@ -1,10 +1,7 @@
using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Interfaces;
using CryptoExchange.Net.Objects;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace CryptoExchange.Net.Objects.Sockets namespace CryptoExchange.Net.Objects.Sockets
{ {
@ -58,21 +55,6 @@ namespace CryptoExchange.Net.Objects.Sockets
/// </summary> /// </summary>
public IEnumerable<IRateLimiter>? RateLimiters { get; set; } public IEnumerable<IRateLimiter>? RateLimiters { get; set; }
/// <summary>
/// Origin header value to send in the connection handshake
/// </summary>
public string? Origin { get; set; }
/// <summary>
/// Delegate used for manipulating data received from socket connections before it is processed by listeners
/// </summary>
public Func<Stream, Stream>? Interceptor { get; set; }
/// <summary>
/// Delegate used for processing string data received from socket connections before it is processed by handlers
/// </summary>
public Func<string, string>? DataInterpreterString { get; set; }
/// <summary> /// <summary>
/// Encoding for sending/receiving data /// Encoding for sending/receiving data
/// </summary> /// </summary>

View File

@ -1,6 +1,4 @@
using System.Collections.Generic; namespace CryptoExchange.Net.Objects
namespace CryptoExchange.Net.Objects
{ {
/// <summary> /// <summary>
/// Trade environment names /// Trade environment names

View File

@ -1,36 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Text;
namespace CryptoExchange.Net
{
/// <summary>
/// Parsing utility methods
/// </summary>
public static class ParsingUtils
{
/// <summary>
/// Read the stream as string
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public static string GetString(Stream stream)
{
using var reader = new StreamReader(stream, Encoding.UTF8, false, (int)stream.Length, true);
return reader.ReadToEnd();
}
/// <summary>
/// Read the stream and parse to JToken
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public static JToken GetJToken(Stream x)
{
using var sr = new StreamReader(x, Encoding.UTF8, false, (int)x.Length, true);
using var jsonTextReader = new JsonTextReader(sr);
return JToken.Load(jsonTextReader);
}
}
}

View File

@ -1,10 +1,8 @@
using System; using System;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Runtime.InteropServices;
using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Interfaces;
using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Objects.Options;
namespace CryptoExchange.Net.Requests namespace CryptoExchange.Net.Requests
{ {

View File

@ -591,9 +591,6 @@ namespace CryptoExchange.Net.Sockets
LastActionTime = DateTime.UtcNow; LastActionTime = DateTime.UtcNow;
stream.Position = 0; stream.Position = 0;
if (Parameters.Interceptor != null)
stream = Parameters.Interceptor.Invoke(stream);
if (OnStreamMessage != null) if (OnStreamMessage != null)
await OnStreamMessage.Invoke(type, stream).ConfigureAwait(false); await OnStreamMessage.Invoke(type, stream).ConfigureAwait(false);
} }

View File

@ -3,7 +3,6 @@ using CryptoExchange.Net.Sockets.MessageParsing.Interfaces;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;

View File

@ -10,8 +10,6 @@ using System.Net.WebSockets;
using System.IO; using System.IO;
using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Objects.Sockets;
using System.Text; using System.Text;
using System.Diagnostics.CodeAnalysis;
using CryptoExchange.Net.Converters;
using System.Diagnostics; using System.Diagnostics;
using CryptoExchange.Net.Sockets.MessageParsing; using CryptoExchange.Net.Sockets.MessageParsing;
@ -351,6 +349,8 @@ namespace CryptoExchange.Net.Sockets
/// <returns></returns> /// <returns></returns>
protected virtual async Task HandleStreamMessage(WebSocketMessageType type, Stream stream) protected virtual async Task HandleStreamMessage(WebSocketMessageType type, Stream stream)
{ {
var sw = Stopwatch.StartNew();
// 1. Decrypt/Preprocess if necessary // 1. Decrypt/Preprocess if necessary
stream = ApiClient.PreprocessStreamMessage(type, stream); stream = ApiClient.PreprocessStreamMessage(type, stream);
@ -381,6 +381,7 @@ namespace CryptoExchange.Net.Sockets
} }
_logger.LogTrace("Socket {SocketId} {Count} processors matched to message with listener identifier {ListenerId}", SocketId, processors.Count, listenId); _logger.LogTrace("Socket {SocketId} {Count} processors matched to message with listener identifier {ListenerId}", SocketId, processors.Count, listenId);
var totalUserTime = 0;
foreach (var processor in processors) foreach (var processor in processors)
{ {
// 4. Determine the type to deserialize to // 4. Determine the type to deserialize to
@ -406,7 +407,9 @@ namespace CryptoExchange.Net.Sockets
// 6. Hand of the message to the subscription // 6. Hand of the message to the subscription
try try
{ {
var innerSw = Stopwatch.StartNew();
await processor.HandleAsync(this, new DataEvent<object>(deserialized, null, message.RawData, message.ReceiveTime, null)).ConfigureAwait(false); await processor.HandleAsync(this, new DataEvent<object>(deserialized, null, message.RawData, message.ReceiveTime, null)).ConfigureAwait(false);
totalUserTime += (int)innerSw.ElapsedMilliseconds;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -417,6 +420,7 @@ namespace CryptoExchange.Net.Sockets
} }
stream.Dispose(); stream.Dispose();
_logger.LogTrace($"Socket {SocketId} message processed in {(int)sw.ElapsedMilliseconds}ms ({totalUserTime - sw.ElapsedMilliseconds}ms parsing)");
} }
/// <summary> /// <summary>

View File

@ -2,7 +2,6 @@
using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Objects.Sockets;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace CryptoExchange.Net.Sockets namespace CryptoExchange.Net.Sockets

View File

@ -1,7 +1,6 @@
using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Interfaces;
using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Objects.Sockets;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System;
namespace CryptoExchange.Net.Sockets namespace CryptoExchange.Net.Sockets
{ {