diff --git a/.github/notification_pr.workflow b/.github/notification_pr.workflow
deleted file mode 100644
index 85ff3ba..0000000
--- a/.github/notification_pr.workflow
+++ /dev/null
@@ -1,10 +0,0 @@
-workflow "Notify about PR" {
- on = "pull_request"
- resolves = ["GitHub Action for Slack"]
-}
-
-action "GitHub Action for Slack" {
- uses = "Ilshidur/action-slack@305f56a15c09f84b6b4a86e83bff1c41c6b69c63"
- secrets = ["SLACK_WEBHOOK"]
- args = "A new PR has been created in Bitfinex websocket repo"
-}
diff --git a/.github/workflows/dotnet-core-branches.yml b/.github/workflows/dotnet-core-branches.yml
new file mode 100644
index 0000000..b6225df
--- /dev/null
+++ b/.github/workflows/dotnet-core-branches.yml
@@ -0,0 +1,23 @@
+name: .NET Core (branch)
+
+on:
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 8.x
+ - name: Install dependencies
+ run: dotnet restore
+ - name: Build
+ run: dotnet build --configuration Release --no-restore
+ - name: Test
+ run: dotnet test --no-restore --verbosity normal
diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml
new file mode 100644
index 0000000..60f60f9
--- /dev/null
+++ b/.github/workflows/dotnet-core.yml
@@ -0,0 +1,37 @@
+name: .NET Core
+
+on:
+ push:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 8.x
+
+ - name: Install dependencies
+ run: dotnet restore
+ - name: Build
+ run: dotnet build --configuration Release --no-restore
+ - name: Test
+ run: dotnet test --no-restore --logger "trx;LogFileName=tests.trx"
+ - name: Test Report
+ uses: dorny/test-reporter@v1
+ if: success() || failure() # run this step even if previous step failed
+ with:
+ name: tests
+ path: '**/*.trx'
+ reporter: dotnet-trx
+ - name: Pack library project
+ run: dotnet pack src/Bitfinex.Client.Websocket/Bitfinex.Client.Websocket.csproj --no-build --configuration Release --include-symbols -p:SymbolPackageFormat=snupkg -o .
+ - name: Publish library (NuGet)
+ run: dotnet nuget push *.nupkg --api-key ${{secrets.NUGET_API_KEY}} --source "https://api.nuget.org/v3/index.json" --skip-duplicate
+ #- name: Publish library (Github)
+ # run: dotnet nuget push *.nupkg --api-key ${{secrets.PUBLISH_TO_GITHUB_TOKEN}} --source "https://nuget.pkg.github.com/marfusios/index.json" --skip-duplicate
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 249f491..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-language: csharp
-dotnet: 6.0
-os: linux
-dist: xenial
-mono: none
-sudo: required
-
-install:
-before_script:
-script:
-- dotnet build -c Release
-- dotnet test test/Bitfinex.Client.Websocket.Tests -c Release
-deploy:
- provider: script
- skip_cleanup: true
- script:
- - cd src/Bitfinex.Client.Websocket && dotnet pack /p:PackageVersion=4.1.$TRAVIS_BUILD_NUMBER -c Release && cd bin/Release && dotnet nuget push **/*.4.1.$TRAVIS_BUILD_NUMBER.nupkg -k $NUGET_API_KEY -s https://api.nuget.org/v3/index.json
- on:
- branch: master
\ No newline at end of file
diff --git a/Bitfinex.Client.Websocket.sln b/Bitfinex.Client.Websocket.sln
index 4a4cece..a3a137a 100644
--- a/Bitfinex.Client.Websocket.sln
+++ b/Bitfinex.Client.Websocket.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29806.167
+# Visual Studio Version 17
+VisualStudioVersion = 17.8.34601.278
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{360B18BD-653A-4824-9261-C88167EEBAD2}"
EndProject
@@ -19,8 +19,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bitfinex.Client.Websocket.S
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6D0FCFA1-4C4C-4BBD-83CC-22C8E464E338}"
ProjectSection(SolutionItems) = preProject
- .travis.yml = .travis.yml
bitfinex_logo.png = bitfinex_logo.png
+ .github\workflows\dotnet-core-branches.yml = .github\workflows\dotnet-core-branches.yml
+ .github\workflows\dotnet-core.yml = .github\workflows\dotnet-core.yml
LICENSE = LICENSE
README.md = README.md
EndProjectSection
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..9185158
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,9 @@
+
+
+
+
+
+ 4.1.0
+
+
+
diff --git a/README.md b/README.md
index 2676edb..9b1bcb6 100644
--- a/README.md
+++ b/README.md
@@ -346,8 +346,3 @@ Due to the large amount of questions about integration of this library into a de
### Available for help
I do consulting, please don't hesitate to contact me if you have a custom solution you would like me to implement ([web](http://mkotas.cz/),
)
-
-Donations gratefully accepted.
-* [![Donate with Bitcoin](https://en.cryptobadges.io/badge/small/1HfxKZhvm68qK3gE8bJAdDBWkcZ2AFs9pw)](https://en.cryptobadges.io/donate/1HfxKZhvm68qK3gE8bJAdDBWkcZ2AFs9pw)
-* [![Donate with Litecoin](https://en.cryptobadges.io/badge/small/LftdENE8DTbLpV6RZLKLdzYzVU82E6dz4W)](https://en.cryptobadges.io/donate/LftdENE8DTbLpV6RZLKLdzYzVU82E6dz4W)
-* [![Donate with Ethereum](https://en.cryptobadges.io/badge/small/0xb9637c56b307f24372cdcebd208c0679d4e48a47)](https://en.cryptobadges.io/donate/0xb9637c56b307f24372cdcebd208c0679d4e48a47)
diff --git a/src/Bitfinex.Client.Websocket/Bitfinex.Client.Websocket.csproj b/src/Bitfinex.Client.Websocket/Bitfinex.Client.Websocket.csproj
index 974106d..bd6b1c3 100644
--- a/src/Bitfinex.Client.Websocket/Bitfinex.Client.Websocket.csproj
+++ b/src/Bitfinex.Client.Websocket/Bitfinex.Client.Websocket.csproj
@@ -1,37 +1,38 @@
-
- netstandard2.0;netstandard2.1;net5;net6
- Bitfinex.Client.Websocket
- 4.0.0
- Mariusz Kotas
- Client for Bitfinex and Ethfinex websocket API version 2.0
- false
-
- Copyright 2021 Mariusz Kotas. All rights reserved.
- Bitfinex Ethfinex websockets websocket client cryptocurrency exchange bitcoin
- https://github.com/Marfusios/bitfinex-client-websocket/blob/master/LICENSE
- https://github.com/Marfusios/bitfinex-client-websocket
- http://blog.bitfinex.com/wp-content/uploads/2016/05/bfx-stacked.png
- https://github.com/Marfusios/bitfinex-client-websocket
- Git
- true
- true
- 4.0.0.0
- 4.0.0.0
+
+ netstandard2.1;net6;net7;net8
+ Bitfinex.Client.Websocket
+ Mariusz Kotas
+ Client for Bitfinex and Ethfinex websocket API version 2.0
+ false
+ Enhancements
+ Copyright 2024 Mariusz Kotas. All rights reserved.
+ Bitfinex Ethfinex websockets websocket client cryptocurrency exchange bitcoin
+ MIT
+ https://github.com/Marfusios/bitfinex-client-websocket
+ http://blog.bitfinex.com/wp-content/uploads/2016/05/bfx-stacked.png
+ icon.png
+ https://github.com/Marfusios/bitfinex-client-websocket
+ README.md
+ Git
+ true
+ true
- true
- snupkg
-
+ true
+ snupkg
+ enable
+
-
-
- all
- runtime; build; native; contentfiles; analyzers
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Bitfinex.Client.Websocket/Client/BitfinexAuthenticatedHandler.cs b/src/Bitfinex.Client.Websocket/Client/BitfinexAuthenticatedHandler.cs
index 802137e..1156963 100644
--- a/src/Bitfinex.Client.Websocket/Client/BitfinexAuthenticatedHandler.cs
+++ b/src/Bitfinex.Client.Websocket/Client/BitfinexAuthenticatedHandler.cs
@@ -1,5 +1,4 @@
using System.Linq;
-using Bitfinex.Client.Websocket.Logging;
using Bitfinex.Client.Websocket.Responses.Balance;
using Bitfinex.Client.Websocket.Responses.Configurations;
using Bitfinex.Client.Websocket.Responses.Notifications;
@@ -9,18 +8,20 @@
using Bitfinex.Client.Websocket.Responses.Trades;
using Bitfinex.Client.Websocket.Responses.TradesPrivate;
using Bitfinex.Client.Websocket.Responses.Wallets;
+using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
namespace Bitfinex.Client.Websocket.Client
{
internal class BitfinexAuthenticatedHandler
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
+ private readonly ILogger _logger;
private readonly BitfinexClientStreams _streams;
- public BitfinexAuthenticatedHandler(BitfinexClientStreams streams, BitfinexChannelList channelIdToHandler)
+ public BitfinexAuthenticatedHandler(BitfinexClientStreams streams, BitfinexChannelList channelIdToHandler, ILogger logger)
{
_streams = streams;
+ _logger = logger;
channelIdToHandler[0] = HandleAccountInfo;
}
@@ -35,17 +36,17 @@ internal void HandleAccountInfo(JToken token, ConfigurationState config)
var itemsCount = token?.Count();
if (token == null || itemsCount < 2)
{
- Log.Warn($"Invalid message format, too low items");
+ _logger.LogWarning(L("Invalid message format, too low items"));
return;
}
var secondItem = token[1];
- if (secondItem.Type != JTokenType.String)
+ if (secondItem?.Type != JTokenType.String)
{
- Log.Warn(L("Invalid message format, second param is not string"));
+ _logger.LogWarning(L("Invalid message format, second param is not string"));
return;
}
- var msgType = (string)secondItem;
+ var msgType = (string?)secondItem;
if (msgType == "hb")
{
// heartbeat, ignore
@@ -54,7 +55,7 @@ internal void HandleAccountInfo(JToken token, ConfigurationState config)
if (itemsCount < 3)
{
- Log.Warn(L("Invalid message format, too low items"));
+ _logger.LogWarning(L("Invalid message format, too low items"));
return;
}
@@ -109,9 +110,9 @@ internal void HandleAccountInfo(JToken token, ConfigurationState config)
case "miu":
MarginInfo.Handle(token, _streams.MarginInfoSubject);
break;
- //default:
- // Log.Warning($"Missing private handler for '{msgType}'. Data: {token}");
- // break;
+ //default:
+ // Log.Warning($"Missing private handler for '{msgType}'. Data: {token}");
+ // break;
}
}
}
diff --git a/src/Bitfinex.Client.Websocket/Client/BitfinexPublicHandler.cs b/src/Bitfinex.Client.Websocket/Client/BitfinexPublicHandler.cs
index 15e7ce1..13b141c 100644
--- a/src/Bitfinex.Client.Websocket/Client/BitfinexPublicHandler.cs
+++ b/src/Bitfinex.Client.Websocket/Client/BitfinexPublicHandler.cs
@@ -1,5 +1,4 @@
using System;
-using Bitfinex.Client.Websocket.Logging;
using Bitfinex.Client.Websocket.Messages;
using Bitfinex.Client.Websocket.Responses;
using Bitfinex.Client.Websocket.Responses.Books;
@@ -14,8 +13,6 @@ namespace Bitfinex.Client.Websocket.Client
{
internal class BitfinexPublicHandler
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
private readonly BitfinexClientStreams _streams;
private readonly BitfinexChannelList _channelIdToHandler;
@@ -52,14 +49,17 @@ public void OnObjectMessage(string msg)
case MessageType.Unsubscribed:
UnsubscribedResponse.Handle(msg, _streams.UnsubscriptionSubject);
break;
- //default:
- // Log.Warning($"Missing handler for public stream, data: '{msg}'");
- // break;
+ //default:
+ // Log.Warning($"Missing handler for public stream, data: '{msg}'");
+ // break;
}
}
- private void OnSubscription(SubscribedResponse response)
+ private void OnSubscription(SubscribedResponse? response)
{
+ if (response == null)
+ return;
+
_streams.SubscriptionSubject.OnNext(response);
var channelId = response.ChanId;
@@ -71,32 +71,32 @@ private void OnSubscription(SubscribedResponse response)
switch (response.Channel)
{
case "ticker":
- _channelIdToHandler[channelId] = (data, config) =>
+ _channelIdToHandler[channelId] = (data, config) =>
Ticker.Handle(data, response, config, _streams.TickerSubject);
break;
case "trades":
//if pair is null means that is funding
if (response.Pair == null)
{
- _channelIdToHandler[channelId] = (data, config) =>
+ _channelIdToHandler[channelId] = (data, config) =>
Funding.Handle(data, response, config, _streams.FundingsSubject);
}
else
{
- _channelIdToHandler[channelId] = (data, config) =>
+ _channelIdToHandler[channelId] = (data, config) =>
Trade.Handle(data, response, config, _streams.TradesSubject, _streams.TradesSnapshotSubject);
}
break;
case "candles":
- _channelIdToHandler[channelId] = (data, config) =>
+ _channelIdToHandler[channelId] = (data, config) =>
Candles.Handle(data, response, _streams.CandlesSubject);
break;
case "book":
- if("R0".Equals(response.Prec, StringComparison.OrdinalIgnoreCase))
- _channelIdToHandler[channelId] = (data, config) =>
+ if ("R0".Equals(response.Prec, StringComparison.OrdinalIgnoreCase))
+ _channelIdToHandler[channelId] = (data, config) =>
RawBook.Handle(data, response, config, _streams.RawBookSubject, _streams.RawBookSnapshotSubject, _streams.BookChecksumSubject);
else
- _channelIdToHandler[channelId] = (data, config) =>
+ _channelIdToHandler[channelId] = (data, config) =>
Book.Handle(data, response, config, _streams.BookSubject, _streams.BookSnapshotSubject, _streams.BookChecksumSubject);
break;
case "status":
@@ -113,9 +113,9 @@ private void OnSubscription(SubscribedResponse response)
}
break;
- //default:
- // Log.Warning($"Missing subscription handler '{response.Channel}'");
- // break;
+ //default:
+ // Log.Warning($"Missing subscription handler '{response.Channel}'");
+ // break;
}
}
diff --git a/src/Bitfinex.Client.Websocket/Client/BitfinexSerialization.cs b/src/Bitfinex.Client.Websocket/Client/BitfinexSerialization.cs
index e56cd67..2c6b0e0 100644
--- a/src/Bitfinex.Client.Websocket/Client/BitfinexSerialization.cs
+++ b/src/Bitfinex.Client.Websocket/Client/BitfinexSerialization.cs
@@ -5,7 +5,7 @@ namespace Bitfinex.Client.Websocket.Client
{
internal static class BitfinexSerialization
{
- public static T Deserialize(string msg)
+ public static T? Deserialize(string msg) where T : class
{
return JsonConvert.DeserializeObject(msg, BitfinexJsonSerializer.Settings);
}
diff --git a/src/Bitfinex.Client.Websocket/Client/BitfinexWebsocketClient.cs b/src/Bitfinex.Client.Websocket/Client/BitfinexWebsocketClient.cs
index e1a10b4..c9e43ef 100644
--- a/src/Bitfinex.Client.Websocket/Client/BitfinexWebsocketClient.cs
+++ b/src/Bitfinex.Client.Websocket/Client/BitfinexWebsocketClient.cs
@@ -1,13 +1,13 @@
using System;
using System.Linq;
-using System.Threading.Tasks;
using Bitfinex.Client.Websocket.Communicator;
using Bitfinex.Client.Websocket.Json;
-using Bitfinex.Client.Websocket.Logging;
using Bitfinex.Client.Websocket.Requests;
using Bitfinex.Client.Websocket.Requests.Configurations;
using Bitfinex.Client.Websocket.Responses.Configurations;
using Bitfinex.Client.Websocket.Validations;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Websocket.Client;
@@ -21,8 +21,7 @@ namespace Bitfinex.Client.Websocket.Client
///
public class BitfinexWebsocketClient : IDisposable
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
+ private readonly ILogger _logger;
private readonly IBitfinexCommunicator _communicator;
private readonly IDisposable _messageReceivedSubscription;
private readonly IDisposable _configurationSubscription;
@@ -33,15 +32,16 @@ public class BitfinexWebsocketClient : IDisposable
private readonly BitfinexPublicHandler _publicHandler;
///
- public BitfinexWebsocketClient(IBitfinexCommunicator communicator)
+ public BitfinexWebsocketClient(IBitfinexCommunicator communicator, ILogger? logger = null)
{
BfxValidations.ValidateInput(communicator, nameof(communicator));
_communicator = communicator;
+ _logger = logger ?? NullLogger.Instance;
_messageReceivedSubscription = _communicator.MessageReceived.Subscribe(HandleMessage);
_configurationSubscription = Streams.ConfigurationSubject.Subscribe(HandleConfiguration);
- _authenticatedHandler = new BitfinexAuthenticatedHandler(Streams, _channelIdToHandler);
+ _authenticatedHandler = new BitfinexAuthenticatedHandler(Streams, _channelIdToHandler, _logger);
_publicHandler = new BitfinexPublicHandler(Streams, _channelIdToHandler);
}
@@ -80,7 +80,7 @@ public void Send(T request)
}
catch (Exception e)
{
- Log.Error(e, L($"Exception while sending message '{request}'. Error: {e.Message}"));
+ _logger.LogError(e, L("Exception while sending message '{request}'. Error: {error}"), request, e.Message);
throw;
}
}
@@ -117,7 +117,7 @@ private void HandleConfiguration(ConfigurationResponse response)
}
catch (Exception e)
{
- Log.Error(e, L("Exception while received configuration"));
+ _logger.LogError(e, L("Exception while received configuration, error: {error}"), e.Message);
}
}
@@ -141,7 +141,7 @@ private void HandleMessage(ResponseMessage message)
}
catch (Exception e)
{
- Log.Error(e, L("Exception while receiving message"));
+ _logger.LogError(e, L("Exception while receiving message, error: {error}"), e.Message);
}
}
@@ -150,7 +150,7 @@ private void OnArrayMessage(string msg)
var parsed = BitfinexSerialization.Deserialize(msg);
if (parsed.Count() < 2)
{
- Log.Warn(L("Invalid message format, too low items"));
+ _logger.LogWarning(L("Invalid message format, too low items"));
return;
}
@@ -158,7 +158,7 @@ private void OnArrayMessage(string msg)
if (!_channelIdToHandler.ContainsKey(channelId))
{
- Log.Debug($"Unrecognized channel id '{channelId}', ignoring..");
+ _logger.LogDebug("Unrecognized channel id '{channelId}', ignoring..", channelId);
return;
}
diff --git a/src/Bitfinex.Client.Websocket/Files/BitfinexFileCommunicator.cs b/src/Bitfinex.Client.Websocket/Files/BitfinexFileCommunicator.cs
index 2aa5dfe..c74aa87 100644
--- a/src/Bitfinex.Client.Websocket/Files/BitfinexFileCommunicator.cs
+++ b/src/Bitfinex.Client.Websocket/Files/BitfinexFileCommunicator.cs
@@ -7,7 +7,6 @@
using System.Threading.Tasks;
using Bitfinex.Client.Websocket.Communicator;
using Websocket.Client;
-using Websocket.Client.Models;
namespace Bitfinex.Client.Websocket.Files
{
@@ -24,6 +23,7 @@ public class BitfinexFileCommunicator : IBitfinexCommunicator
public TimeSpan? ReconnectTimeout { get; set; } = TimeSpan.FromSeconds(60);
public TimeSpan? ErrorReconnectTimeout { get; set; } = TimeSpan.FromSeconds(60);
+ public TimeSpan? LostReconnectTimeout { get; set; } = TimeSpan.FromSeconds(60);
public string Name { get; set; }
public bool IsStarted { get; private set; }
public bool IsRunning { get; private set; }
@@ -39,7 +39,7 @@ public class BitfinexFileCommunicator : IBitfinexCommunicator
public virtual void Dispose()
{
-
+
}
public virtual Task Start()
@@ -64,16 +64,19 @@ public Task StopOrFail(WebSocketCloseStatus status, string statusDescripti
return Task.FromResult(true);
}
- public virtual void Send(string message)
+ public virtual bool Send(string message)
{
+ return true;
}
- public void Send(byte[] message)
+ public bool Send(byte[] message)
{
+ return true;
}
- public void Send(ArraySegment message)
+ public bool Send(ArraySegment message)
{
+ return true;
}
public virtual Task SendInstant(string message)
@@ -86,6 +89,16 @@ public Task SendInstant(byte[] message)
return Task.CompletedTask;
}
+ public bool SendAsText(byte[] message)
+ {
+ return true;
+ }
+
+ public bool SendAsText(ArraySegment message)
+ {
+ return true;
+ }
+
public Task Reconnect()
{
return Task.CompletedTask;
@@ -107,7 +120,7 @@ private void StartStreaming()
{
if (FileNames == null)
throw new InvalidOperationException("FileNames are not set, provide at least one path to historical data");
- if(string.IsNullOrEmpty(Delimiter))
+ if (string.IsNullOrEmpty(Delimiter))
throw new InvalidOperationException("Delimiter is not set (separator between messages in the file)");
foreach (var fileName in FileNames)
@@ -126,19 +139,19 @@ private void StartStreaming()
}
}
-
+
private static string ReadByDelimeter(StreamReader sr, string delimiter)
{
var line = new StringBuilder();
int matchIndex = 0;
while (sr.Peek() > 0)
- {
+ {
var nextChar = (char)sr.Read();
line.Append(nextChar);
if (nextChar == delimiter[matchIndex])
{
- if(matchIndex == delimiter.Length - 1)
+ if (matchIndex == delimiter.Length - 1)
{
return line.ToString().Substring(0, line.Length - delimiter.Length);
}
diff --git a/src/Bitfinex.Client.Websocket/Responses/AuthenticationResponse.cs b/src/Bitfinex.Client.Websocket/Responses/AuthenticationResponse.cs
index 80350d6..0ff222f 100644
--- a/src/Bitfinex.Client.Websocket/Responses/AuthenticationResponse.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/AuthenticationResponse.cs
@@ -1,17 +1,12 @@
using System.Reactive.Subjects;
using Bitfinex.Client.Websocket.Client;
-using Bitfinex.Client.Websocket.Logging;
using Bitfinex.Client.Websocket.Messages;
using Newtonsoft.Json;
-using static Bitfinex.Client.Websocket.Client.BitfinexLogger;
-
namespace Bitfinex.Client.Websocket.Responses
{
public class AuthenticationResponse : MessageBase
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
public string Status { get; set; }
public int ChanId { get; set; }
public int UserId { get; set; }
@@ -21,16 +16,15 @@ public class AuthenticationResponse : MessageBase
///
/// Returns true if authentication succeed
///
- [JsonIgnore]
+ [JsonIgnore]
public bool IsAuthenticated => Status == "OK";
internal static void Handle(string msg, Subject subject)
{
var response = BitfinexSerialization.Deserialize(msg);
-; if (!response.IsAuthenticated)
- Log.Warn(L("Authentication failed. Code: " + response.Code));
- subject.OnNext(response);
+ if (response != null)
+ subject.OnNext(response);
}
}
}
diff --git a/src/Bitfinex.Client.Websocket/Responses/Balance/BalanceInfo.cs b/src/Bitfinex.Client.Websocket/Responses/Balance/BalanceInfo.cs
index 2fd6261..e555cde 100644
--- a/src/Bitfinex.Client.Websocket/Responses/Balance/BalanceInfo.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/Balance/BalanceInfo.cs
@@ -1,6 +1,5 @@
using System.Diagnostics;
using System.Reactive.Subjects;
-using Bitfinex.Client.Websocket.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -13,8 +12,6 @@ namespace Bitfinex.Client.Websocket.Responses.Balance
[JsonConverter(typeof(BalanceInfoConverter))]
public class BalanceInfo
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
///
/// Total Assets Under Management
///
@@ -28,19 +25,14 @@ public class BalanceInfo
internal static void Handle(JToken token, Subject subject)
{
var data = token[2];
- if (data.Type != JTokenType.Array)
+ if (data?.Type != JTokenType.Array)
{
- Log.Warn(L("BalanceInfo - Invalid message format, third param not array"));
return;
}
var parsed = data.ToObject();
- subject.OnNext(parsed);
- }
-
- private static string L(string msg)
- {
- return $"[BFX BALANCE INFO HANDLER] {msg}";
+ if (parsed != null)
+ subject.OnNext(parsed);
}
}
}
\ No newline at end of file
diff --git a/src/Bitfinex.Client.Websocket/Responses/ErrorResponse.cs b/src/Bitfinex.Client.Websocket/Responses/ErrorResponse.cs
index 2ab092a..ec3a025 100644
--- a/src/Bitfinex.Client.Websocket/Responses/ErrorResponse.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/ErrorResponse.cs
@@ -1,16 +1,11 @@
using System.Reactive.Subjects;
using Bitfinex.Client.Websocket.Client;
-using Bitfinex.Client.Websocket.Logging;
using Bitfinex.Client.Websocket.Messages;
-using static Bitfinex.Client.Websocket.Client.BitfinexLogger;
-
namespace Bitfinex.Client.Websocket.Responses
{
public class ErrorResponse : MessageBase
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
public string Code { get; set; }
public string Msg { get; set; }
@@ -18,8 +13,8 @@ public class ErrorResponse : MessageBase
internal static void Handle(string msg, Subject subject)
{
var error = BitfinexSerialization.Deserialize(msg);
- Log.Error(L($"Error received - message: {error.Msg}, code: {error.Code}"));
- subject.OnNext(error);
+ if (error != null)
+ subject.OnNext(error);
}
}
}
diff --git a/src/Bitfinex.Client.Websocket/Responses/Margin/MarginInfo.cs b/src/Bitfinex.Client.Websocket/Responses/Margin/MarginInfo.cs
index 2ca7ec3..8e9792a 100644
--- a/src/Bitfinex.Client.Websocket/Responses/Margin/MarginInfo.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/Margin/MarginInfo.cs
@@ -1,6 +1,5 @@
using System.Diagnostics;
using System.Reactive.Subjects;
-using Bitfinex.Client.Websocket.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -13,8 +12,6 @@ namespace Bitfinex.Client.Websocket.Responses.Margin
[JsonConverter(typeof(MarginInfoConverter))]
public class MarginInfo
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
///
/// User Profit and Loss (P/L)
///
@@ -43,9 +40,8 @@ public class MarginInfo
internal static void Handle(JToken token, Subject subject)
{
var data = token[2];
- if (data.Type != JTokenType.Array)
+ if (data?.Type != JTokenType.Array)
{
- Log.Warn(L("MarginInfo - Invalid message format, third param not array"));
return;
}
diff --git a/src/Bitfinex.Client.Websocket/Responses/Notifications/Notification.cs b/src/Bitfinex.Client.Websocket/Responses/Notifications/Notification.cs
index 0439153..b01cc20 100644
--- a/src/Bitfinex.Client.Websocket/Responses/Notifications/Notification.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/Notifications/Notification.cs
@@ -1,7 +1,6 @@
using System;
using System.Diagnostics;
using System.Reactive.Subjects;
-using Bitfinex.Client.Websocket.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -14,8 +13,6 @@ namespace Bitfinex.Client.Websocket.Responses.Notifications
[JsonConverter(typeof(NotificationConverter))]
public class Notification
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
///
/// Timestamp of the update
///
@@ -55,19 +52,14 @@ public class Notification
internal static void Handle(JToken token, Subject subject)
{
var data = token[2];
- if (data.Type != JTokenType.Array)
+ if (data?.Type != JTokenType.Array)
{
- Log.Warn(L("Notification - Invalid message format, third param not array"));
return;
}
var parsed = data.ToObject();
- subject.OnNext(parsed);
- }
-
- private static string L(string msg)
- {
- return $"[BFX NOTIFICATION HANDLER] {msg}";
+ if (parsed != null)
+ subject.OnNext(parsed);
}
}
}
\ No newline at end of file
diff --git a/src/Bitfinex.Client.Websocket/Responses/Notifications/NotificationConverter.cs b/src/Bitfinex.Client.Websocket/Responses/Notifications/NotificationConverter.cs
index 451b033..497af60 100644
--- a/src/Bitfinex.Client.Websocket/Responses/Notifications/NotificationConverter.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/Notifications/NotificationConverter.cs
@@ -1,5 +1,4 @@
using System;
-using Bitfinex.Client.Websocket.Logging;
using Bitfinex.Client.Websocket.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -8,8 +7,6 @@ namespace Bitfinex.Client.Websocket.Responses.Notifications
{
class NotificationConverter : JsonConverter
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Notification);
@@ -33,12 +30,12 @@ private Notification JArrayToNotification(JArray array)
{
return new Notification
{
- Mts = BitfinexTime.ConvertToTime((long) array[0]),
- Type = ParseNotificationType((string) array[1]),
- MessageId = (long?) array[2],
+ Mts = BitfinexTime.ConvertToTime((long)array[0]),
+ Type = ParseNotificationType((string)array[1]),
+ MessageId = (long?)array[2],
NotifyInfo = array[4].ToString(),
- Code = (long?) array[5],
- Status = (string) array[6],
+ Code = (long?)array[5],
+ Status = (string)array[6],
Text = array[7].ToString(),
};
}
@@ -76,7 +73,6 @@ private static NotificationType ParseNotificationType(string type)
return NotificationType.DepositComplete;
}
- Log.Warn("Can't parse NotificationType, input: " + safe);
return NotificationType.Undefined;
}
}
diff --git a/src/Bitfinex.Client.Websocket/Responses/Orders/Order.cs b/src/Bitfinex.Client.Websocket/Responses/Orders/Order.cs
index 538d1c1..4c69f66 100644
--- a/src/Bitfinex.Client.Websocket/Responses/Orders/Order.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/Orders/Order.cs
@@ -1,7 +1,6 @@
using System;
using System.Diagnostics;
using System.Reactive.Subjects;
-using Bitfinex.Client.Websocket.Logging;
using Bitfinex.Client.Websocket.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -15,8 +14,6 @@ namespace Bitfinex.Client.Websocket.Responses.Orders
[JsonConverter(typeof(OrderConverter))]
public class Order
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
///
/// Order ID
///
@@ -165,33 +162,26 @@ public class Order
internal static void Handle(JToken token, Subject subject)
{
var data = token[2];
- if (data.Type != JTokenType.Array)
+ if (data?.Type != JTokenType.Array)
{
- Log.Warn(L("Orders - Invalid message format, third param not array"));
return;
}
var parsed = data.ToObject();
- subject.OnNext(parsed);
+ if (parsed != null) subject.OnNext(parsed);
}
internal static void Handle(JToken token, Subject subject)
{
var data = token[2];
- if (data.Type != JTokenType.Array)
+ if (data?.Type != JTokenType.Array)
{
- Log.Warn(L("Order info - Invalid message format, third param not array"));
return;
}
var parsed = data.ToObject();
- subject.OnNext(parsed);
- }
-
- private static string L(string msg)
- {
- return $"[BFX ORDER HANDLER] {msg}";
+ if (parsed != null) subject.OnNext(parsed);
}
}
}
diff --git a/src/Bitfinex.Client.Websocket/Responses/Orders/OrderConverter.cs b/src/Bitfinex.Client.Websocket/Responses/Orders/OrderConverter.cs
index 7d873da..58a3185 100644
--- a/src/Bitfinex.Client.Websocket/Responses/Orders/OrderConverter.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/Orders/OrderConverter.cs
@@ -1,6 +1,5 @@
using System;
using Bitfinex.Client.Websocket.Exceptions;
-using Bitfinex.Client.Websocket.Logging;
using Bitfinex.Client.Websocket.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -9,8 +8,6 @@ namespace Bitfinex.Client.Websocket.Responses.Orders
{
internal class OrderConverter : JsonConverter
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Order);
@@ -103,7 +100,6 @@ public static OrderStatus ParseStatus(string status)
return OrderStatus.PartiallyFilled;
}
- Log.Warn("Can't parse OrderStatus, input: " + safe);
return OrderStatus.Undefined;
}
@@ -151,7 +147,6 @@ public static OrderType ParseType(string type)
case var s when s.StartsWith("exchange fok"):
return OrderType.ExchangeFok;
}
- Log.Warn("Can't parse OrderType, input: " + safe);
return OrderType.Undefined;
}
diff --git a/src/Bitfinex.Client.Websocket/Responses/Positions/Position.cs b/src/Bitfinex.Client.Websocket/Responses/Positions/Position.cs
index de83b90..d703ecc 100644
--- a/src/Bitfinex.Client.Websocket/Responses/Positions/Position.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/Positions/Position.cs
@@ -1,6 +1,6 @@
-using System.Diagnostics;
+using System;
+using System.Diagnostics;
using System.Reactive.Subjects;
-using Bitfinex.Client.Websocket.Logging;
using Bitfinex.Client.Websocket.Responses.Configurations;
using Bitfinex.Client.Websocket.Utils;
using Newtonsoft.Json;
@@ -15,8 +15,6 @@ namespace Bitfinex.Client.Websocket.Responses.Positions
[JsonConverter(typeof(PositionConverter))]
public class Position : ResponseBase
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
///
/// Pair (tBTCUSD, etc).
///
@@ -85,13 +83,12 @@ public class Position : ResponseBase
internal static void Handle(JToken token, ConfigurationState config, Subject subject)
{
var data = token[2];
- if (data.Type != JTokenType.Array)
+ if (data?.Type != JTokenType.Array)
{
- Log.Warn(L("Positions - Invalid message format, third param not array"));
return;
}
- var parsed = data.ToObject();
+ var parsed = data.ToObject() ?? Array.Empty();
foreach (var position in parsed)
{
SetGlobalData(position, config, token, 2, true);
@@ -102,20 +99,17 @@ internal static void Handle(JToken token, ConfigurationState config, Subject subject)
{
var data = token[2];
- if (data.Type != JTokenType.Array)
+ if (data?.Type != JTokenType.Array)
{
- Log.Warn(L("Position - Invalid message format, third param not array"));
return;
}
var position = data.ToObject();
- SetGlobalData(position, config, token, 2, true);
- subject.OnNext(position);
- }
-
- private static string L(string msg)
- {
- return $"[BFX POSITION HANDLER] {msg}";
+ if (position != null)
+ {
+ SetGlobalData(position, config, token, 2, true);
+ subject.OnNext(position);
+ }
}
}
}
diff --git a/src/Bitfinex.Client.Websocket/Responses/Positions/PositionConverter.cs b/src/Bitfinex.Client.Websocket/Responses/Positions/PositionConverter.cs
index 9f02aa1..0dc95e5 100644
--- a/src/Bitfinex.Client.Websocket/Responses/Positions/PositionConverter.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/Positions/PositionConverter.cs
@@ -1,5 +1,4 @@
using System;
-using Bitfinex.Client.Websocket.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -7,8 +6,6 @@ namespace Bitfinex.Client.Websocket.Responses.Positions
{
internal class PositionConverter : JsonConverter
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Position);
@@ -58,7 +55,6 @@ public static PositionStatus ParseStatus(string status)
case var s when s.Contains("closed"):
return PositionStatus.Closed;
}
- Log.Warn("Can't parse PositionStatus, input: " + safe);
return PositionStatus.Undefined;
}
@@ -73,7 +69,6 @@ public static MarginFundingType ParseFundingType(int? type)
case 1:
return MarginFundingType.Term;
}
- Log.Warn("Can't parse MarginFundingType, input: " + type);
return MarginFundingType.Undefined;
}
}
diff --git a/src/Bitfinex.Client.Websocket/Responses/ResponseBase.cs b/src/Bitfinex.Client.Websocket/Responses/ResponseBase.cs
index 4e53860..c3820df 100644
--- a/src/Bitfinex.Client.Websocket/Responses/ResponseBase.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/ResponseBase.cs
@@ -1,5 +1,4 @@
using System;
-using Bitfinex.Client.Websocket.Logging;
using Bitfinex.Client.Websocket.Responses.Configurations;
using Bitfinex.Client.Websocket.Utils;
using Newtonsoft.Json.Linq;
@@ -11,8 +10,6 @@ namespace Bitfinex.Client.Websocket.Responses
///
public class ResponseBase
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
///
/// Unique channel id for this type of response.
///
@@ -69,7 +66,7 @@ internal static void SetGlobalData(ResponseBase response, ConfigurationState con
}
catch (Exception e)
{
- Log.Warn($"[BFX response] Failed to parse global data (timestamp, sequence). Error: {e.Message}");
+ Console.WriteLine($"[BFX response] Failed to parse global data (timestamp, sequence). Error: {e.Message}");
}
}
}
diff --git a/src/Bitfinex.Client.Websocket/Responses/TradesPrivate/PrivateTrade.cs b/src/Bitfinex.Client.Websocket/Responses/TradesPrivate/PrivateTrade.cs
index b6c8f24..55d0151 100644
--- a/src/Bitfinex.Client.Websocket/Responses/TradesPrivate/PrivateTrade.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/TradesPrivate/PrivateTrade.cs
@@ -1,6 +1,5 @@
using System;
using System.Reactive.Subjects;
-using Bitfinex.Client.Websocket.Logging;
using Bitfinex.Client.Websocket.Responses.Configurations;
using Bitfinex.Client.Websocket.Responses.Orders;
using Bitfinex.Client.Websocket.Responses.Trades;
@@ -16,8 +15,6 @@ namespace Bitfinex.Client.Websocket.Responses.TradesPrivate
[JsonConverter(typeof(PrivateTradeConverter))]
public class PrivateTrade : ResponseBase
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
///
/// Trade id
///
@@ -89,22 +86,18 @@ public class PrivateTrade : ResponseBase
internal static void Handle(JToken token, ConfigurationState config, Subject subject, TradeType type)
{
var data = token[2];
- if (data.Type != JTokenType.Array)
+ if (data?.Type != JTokenType.Array)
{
- Log.Warn(L("Private trade info - Invalid message format, third param not array"));
return;
}
var trade = data.ToObject();
- trade.Type = type;
- SetGlobalData(trade, config, token, 2, true);
-
- subject.OnNext(trade);
- }
-
- private static string L(string msg)
- {
- return $"[BFX PRIVATE TRADE HANDLER] {msg}";
+ if (trade != null)
+ {
+ trade.Type = type;
+ SetGlobalData(trade, config, token, 2, true);
+ subject.OnNext(trade);
+ }
}
}
}
diff --git a/src/Bitfinex.Client.Websocket/Responses/Wallets/Wallet.cs b/src/Bitfinex.Client.Websocket/Responses/Wallets/Wallet.cs
index 59f0820..770500b 100644
--- a/src/Bitfinex.Client.Websocket/Responses/Wallets/Wallet.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/Wallets/Wallet.cs
@@ -1,7 +1,6 @@
using System.Diagnostics;
using System.Linq;
using System.Reactive.Subjects;
-using Bitfinex.Client.Websocket.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -14,8 +13,6 @@ namespace Bitfinex.Client.Websocket.Responses.Wallets
[JsonConverter(typeof(WalletConverter))]
public class Wallet
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
///
/// Wallet name (exchange, margin, funding)
///
@@ -42,37 +39,34 @@ public class Wallet
///
public double? BalanceAvailable { get; set; }
-
+
internal static void Handle(JToken token, Subject subject, Subject subjectMultiple)
{
var data = token[2];
- if (data.Type != JTokenType.Array)
+ if (data?.Type != JTokenType.Array)
{
- Log.Warn(L("Wallets - Invalid message format, third param not array"));
return;
}
var parsed = data.ToObject();
- subjectMultiple.OnNext(parsed);
- parsed.ToList().ForEach(subject.OnNext);
+ if (parsed != null)
+ {
+ subjectMultiple.OnNext(parsed);
+ parsed.ToList().ForEach(subject.OnNext);
+ }
}
internal static void Handle(JToken token, Subject subject)
{
var data = token[2];
- if (data.Type != JTokenType.Array)
+ if (data?.Type != JTokenType.Array)
{
- Log.Warn(L("Wallet update - Invalid message format, third param not array"));
return;
}
var parsed = data.ToObject();
- subject.OnNext(parsed);
- }
-
- private static string L(string msg)
- {
- return $"[BFX WALLET HANDLER] {msg}";
+ if (parsed != null)
+ subject.OnNext(parsed);
}
}
}
diff --git a/src/Bitfinex.Client.Websocket/Responses/Wallets/WalletConverter.cs b/src/Bitfinex.Client.Websocket/Responses/Wallets/WalletConverter.cs
index 6d8dedc..518fc07 100644
--- a/src/Bitfinex.Client.Websocket/Responses/Wallets/WalletConverter.cs
+++ b/src/Bitfinex.Client.Websocket/Responses/Wallets/WalletConverter.cs
@@ -1,5 +1,4 @@
using System;
-using Bitfinex.Client.Websocket.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -7,8 +6,6 @@ namespace Bitfinex.Client.Websocket.Responses.Wallets
{
class WalletConverter : JsonConverter
{
- private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
-
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Wallet);
@@ -57,7 +54,6 @@ public static WalletType ParseWalletType(string type)
case var s when s.StartsWith("funding"):
return WalletType.Funding;
}
- Log.Warn("Can't parse WalletType, input: " + safe);
return WalletType.Undefined;
}
}
diff --git a/src/Bitfinex.Client.Websocket/Websockets/BitfinexWebsocketCommunicator.cs b/src/Bitfinex.Client.Websocket/Websockets/BitfinexWebsocketCommunicator.cs
index 4b43015..87c1e43 100644
--- a/src/Bitfinex.Client.Websocket/Websockets/BitfinexWebsocketCommunicator.cs
+++ b/src/Bitfinex.Client.Websocket/Websockets/BitfinexWebsocketCommunicator.cs
@@ -1,6 +1,7 @@
using System;
using System.Net.WebSockets;
using Bitfinex.Client.Websocket.Communicator;
+using Microsoft.Extensions.Logging;
using Websocket.Client;
namespace Bitfinex.Client.Websocket.Websockets
@@ -9,9 +10,15 @@ namespace Bitfinex.Client.Websocket.Websockets
public class BitfinexWebsocketCommunicator : WebsocketClient, IBitfinexCommunicator
{
///
- public BitfinexWebsocketCommunicator(Uri url, Func clientFactory = null)
+ public BitfinexWebsocketCommunicator(Uri url, Func? clientFactory = null)
: base(url, clientFactory)
{
}
+
+ ///
+ public BitfinexWebsocketCommunicator(Uri url, ILogger logger, Func? clientFactory = null)
+ : base(url, logger, clientFactory)
+ {
+ }
}
}
diff --git a/src/Bitfinex.Client.Websocket/icon.png b/src/Bitfinex.Client.Websocket/icon.png
new file mode 100644
index 0000000..6a2dae5
Binary files /dev/null and b/src/Bitfinex.Client.Websocket/icon.png differ
diff --git a/test/Bitfinex.Client.Websocket.Tests/Bitfinex.Client.Websocket.Tests.csproj b/test/Bitfinex.Client.Websocket.Tests/Bitfinex.Client.Websocket.Tests.csproj
index 7d46416..3258c64 100644
--- a/test/Bitfinex.Client.Websocket.Tests/Bitfinex.Client.Websocket.Tests.csproj
+++ b/test/Bitfinex.Client.Websocket.Tests/Bitfinex.Client.Websocket.Tests.csproj
@@ -1,23 +1,23 @@
-
- net6
+
+ net8
- false
-
+ false
+
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
-
-
-
+
+
+
diff --git a/test_integration/Bitfinex.Client.Websocket.Sample/Bitfinex.Client.Websocket.Sample.csproj b/test_integration/Bitfinex.Client.Websocket.Sample/Bitfinex.Client.Websocket.Sample.csproj
index 1845a03..a10a53e 100644
--- a/test_integration/Bitfinex.Client.Websocket.Sample/Bitfinex.Client.Websocket.Sample.csproj
+++ b/test_integration/Bitfinex.Client.Websocket.Sample/Bitfinex.Client.Websocket.Sample.csproj
@@ -1,15 +1,15 @@
-
+
-
- Exe
- net6
-
+
+ Exe
+ net8
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/test_integration/Bitfinex.Client.Websocket.Sample/Program.cs b/test_integration/Bitfinex.Client.Websocket.Sample/Program.cs
index 2abf958..730dc06 100644
--- a/test_integration/Bitfinex.Client.Websocket.Sample/Program.cs
+++ b/test_integration/Bitfinex.Client.Websocket.Sample/Program.cs
@@ -14,21 +14,23 @@
using Bitfinex.Client.Websocket.Responses.Trades;
using Bitfinex.Client.Websocket.Utils;
using Bitfinex.Client.Websocket.Websockets;
+using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Events;
+using Serilog.Extensions.Logging;
namespace Bitfinex.Client.Websocket.Sample
{
class Program
{
- private static readonly ManualResetEvent ExitEvent = new ManualResetEvent(false);
+ private static readonly ManualResetEvent ExitEvent = new(false);
- private static readonly string API_KEY = "your_api_key";
- private static readonly string API_SECRET = "";
+ private const string ApiKey = "your_api_key";
+ private const string ApiSecret = "";
static void Main(string[] args)
{
- InitLogging();
+ var logger = InitLogging();
AppDomain.CurrentDomain.ProcessExit += CurrentDomainOnProcessExit;
AssemblyLoadContext.Default.Unloading += DefaultOnUnloading;
@@ -45,18 +47,18 @@ static void Main(string[] args)
var url = BitfinexValues.ApiWebsocketUrl;
- using (var communicator = new BitfinexWebsocketCommunicator(url))
+ using (var communicator = new BitfinexWebsocketCommunicator(url, logger.CreateLogger()))
{
communicator.Name = "Bitfinex-1";
communicator.ReconnectTimeout = TimeSpan.FromSeconds(30);
communicator.ReconnectionHappened.Subscribe(info =>
- Log.Information($"Reconnection happened, type: {info.Type}"));
+ Log.Information("Reconnection happened, type: {type}", info.Type));
- using (var client = new BitfinexWebsocketClient(communicator))
+ using (var client = new BitfinexWebsocketClient(communicator, logger.CreateLogger()))
{
client.Streams.InfoStream.Subscribe(info =>
{
- Log.Information($"Info received version: {info.Version}, reconnection happened, resubscribing to streams");
+ Log.Information("Info received version: {version}, reconnection happened, resubscribing to streams", info.Version);
SendSubscriptionRequests(client).Wait();
});
@@ -77,12 +79,12 @@ static void Main(string[] args)
private static async Task SendSubscriptionRequests(BitfinexWebsocketClient client)
{
//client.Send(new ConfigurationRequest(ConfigurationFlag.Timestamp | ConfigurationFlag.Sequencing));
- client.Send(new PingRequest() {Cid = 123456});
+ client.Send(new PingRequest() { Cid = 123456 });
//client.Send(new TickerSubscribeRequest("BTC/USD"));
//client.Send(new TickerSubscribeRequest("ETH/USD"));
- //client.Send(new TradesSubscribeRequest("BTC/USD"));
+ client.Send(new TradesSubscribeRequest("BTC/USD"));
//client.Send(new TradesSubscribeRequest("NEC/ETH")); // Nectar coin from ETHFINEX
//client.Send(new FundingsSubscribeRequest("BTC"));
//client.Send(new FundingsSubscribeRequest("USD"));
@@ -96,16 +98,16 @@ private static async Task SendSubscriptionRequests(BitfinexWebsocketClient clien
//client.Send(new BookSubscribeRequest("fUSD", BitfinexPrecision.P0, BitfinexFrequency.Realtime));
- client.Send(new RawBookSubscribeRequest("BTCUSD", "100"));
+ //client.Send(new RawBookSubscribeRequest("BTCUSD", "100"));
//client.Send(new RawBookSubscribeRequest("fUSD", "25"));
//client.Send(new RawBookSubscribeRequest("fBTC", "25"));
//client.Send(new StatusSubscribeRequest("liq:global"));
//client.Send(new StatusSubscribeRequest("deriv:tBTCF0:USTF0"));
- if (!string.IsNullOrWhiteSpace(API_SECRET))
+ if (!string.IsNullOrWhiteSpace(ApiSecret))
{
- client.Authenticate(API_KEY, API_SECRET);
+ client.Authenticate(ApiKey, ApiSecret);
#pragma warning disable 4014
Task.Run(async () =>
@@ -161,10 +163,10 @@ private static void SubscribeToStreams(BitfinexWebsocketClient client)
Log.Information($"Configuration happened {x.Status}, flags: {x.Flags}, server timestamp enabled: {client.Configuration.IsTimestampEnabled}"));
client.Streams.PongStream.Subscribe(pong => Log.Information($"Pong received! Id: {pong.Cid}"));
-
+
client.Streams.TickerStream.Subscribe(ticker =>
Log.Information($"{ticker.ServerSequence} {ticker.Pair} - last price: {ticker.LastPrice}, bid: {ticker.Bid}, ask: {ticker.Ask}, {ShowServerTimestamp(client, ticker)}"));
-
+
client.Streams.TradesSnapshotStream.Subscribe(trades =>
{
foreach (var x in trades)
@@ -176,7 +178,7 @@ private static void SubscribeToStreams(BitfinexWebsocketClient client)
client.Streams.TradesStream.Where(x => x.Type == TradeType.Executed).Subscribe(x =>
Log.Information($"{x.ServerSequence} Trade {x.Pair} executed. Time: {x.Mts:mm:ss.fff}, Amount: {x.Amount}, Price: {x.Price}, {ShowServerTimestamp(client, x)}"));
-
+
client.Streams.FundingStream.Where(x => x.Type == FundingType.Executed).Subscribe(x =>
Log.Information($"Funding, Symbol {x.Symbol} executed. Time: {x.Mts:mm:ss.fff}, Amount: {x.Amount}, Rate: {x.Rate}, Period: {x.Period}"));
@@ -193,14 +195,14 @@ private static void SubscribeToStreams(BitfinexWebsocketClient client)
Log.Information(
book.Period <= 0 ?
$"{book.ServerSequence} Book | channel: {book.ChanId} pair: {book.Pair}, price: {book.Price}, amount {book.Amount}, count: {book.Count}, {ShowServerTimestamp(client, book)}" :
- $"{book.ServerSequence} Book | channel: {book.ChanId} sym: {book.Symbol}, rate: {book.Rate*100}% (p.a. {(book.Rate*100*365):F}%), period: {book.Period} amount {book.Amount}, count: {book.Count}, {ShowServerTimestamp(client, book)}"));
+ $"{book.ServerSequence} Book | channel: {book.ChanId} sym: {book.Symbol}, rate: {book.Rate * 100}% (p.a. {(book.Rate * 100 * 365):F}%), period: {book.Period} amount {book.Amount}, count: {book.Count}, {ShowServerTimestamp(client, book)}"));
client.Streams.RawBookStream.Subscribe(book =>
{
Log.Information(
book.OrderId > 0
? $"{book.ServerSequence} RawBook | channel: {book.ChanId} pair: {book.Pair}, order: {book.OrderId}, price: {book.Price}, amount {book.Amount} {ShowServerTimestamp(client, book)}"
- : $"{book.ServerSequence} RawBook | channel: {book.ChanId} sym: {book.Symbol}, offer: {book.OfferId}, period: {book.Period} days, rate {book.Rate*100}% (p.a. {(book.Rate*100*365):F}%) {ShowServerTimestamp(client, book)}");
+ : $"{book.ServerSequence} RawBook | channel: {book.ChanId} sym: {book.Symbol}, offer: {book.OfferId}, period: {book.Period} days, rate {book.Rate * 100}% (p.a. {(book.Rate * 100 * 365):F}%) {ShowServerTimestamp(client, book)}");
});
@@ -248,7 +250,7 @@ private static void SubscribeToStreams(BitfinexWebsocketClient client)
// Flags = OrderFlag.PostOnly
//});
});
-
+
client.Streams.OrderUpdatedStream.Subscribe(info =>
Log.Information($"Order #{info.Cid} group: {info.Gid} updated: {info.Pair} - {info.Type} - {info.Amount} @ {info.Price} | {info.OrderStatus}"));
@@ -256,7 +258,7 @@ private static void SubscribeToStreams(BitfinexWebsocketClient client)
client.Streams.OrderCanceledStream.Subscribe(info =>
Log.Information($"Order #{info.Cid} group: {info.Gid} {info.OrderStatus}: {info.Pair} - {info.Type} - {info.Amount} @ {info.Price}"));
- client.Streams.PrivateTradeStream.Subscribe(trade =>
+ client.Streams.PrivateTradeStream.Subscribe(trade =>
Log.Information($"Private trade {trade.Pair} executed. Time: {trade.MtsCreate:mm:ss.fff}, Amount: {trade.ExecAmount}, Price: {trade.ExecPrice}, " +
$"Fee: {trade.Fee} {trade.FeeCurrency}, type: {trade.OrderType}, " +
$"{ShowServerSequence(client, trade)}, {ShowServerTimestamp(client, trade)}"));
@@ -290,7 +292,7 @@ private static void SubscribeToStreams(BitfinexWebsocketClient client)
client.Streams.NotificationStream.Subscribe(notification =>
Log.Information(
$"Notification: {notification.Text} code: {notification.Code}, status: {notification.Status}, type : {notification.Type}"));
-
+
client.Streams.BalanceInfoStream.Subscribe(info =>
Log.Information($"Balance, total: {info.TotalAum}, net: {info.NetAum}"));
@@ -324,28 +326,30 @@ private static void SubscribeToStreams(BitfinexWebsocketClient client)
private static string ShowServerTimestamp(BitfinexWebsocketClient client, ResponseBase response)
{
- if(!client.Configuration.IsTimestampEnabled)
+ if (!client.Configuration.IsTimestampEnabled)
return string.Empty;
return $"server timestamp: {response.ServerTimestamp:mm:ss.fff}";
}
private static string ShowServerSequence(BitfinexWebsocketClient client, ResponseBase response)
{
- if(!client.Configuration.IsSequencingEnabled)
+ if (!client.Configuration.IsSequencingEnabled)
return string.Empty;
return $"sequence: {response.ServerSequence} / {response.ServerPrivateSequence}";
}
- private static void InitLogging()
+ private static SerilogLoggerFactory InitLogging()
{
var executingDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var logPath = Path.Combine(executingDir, "logs", "verbose.log");
- Log.Logger = new LoggerConfiguration()
+ var logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.WriteTo.File(logPath, rollingInterval: RollingInterval.Day)
- .WriteTo.ColoredConsole(LogEventLevel.Debug, outputTemplate:
+ .WriteTo.Console(LogEventLevel.Debug, outputTemplate:
"[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}")
.CreateLogger();
+ Log.Logger = logger;
+ return new SerilogLoggerFactory(logger);
}
private static void CurrentDomainOnProcessExit(object sender, EventArgs eventArgs)
diff --git a/test_integration/Bitfinex.Client.Websocket.Tests.Integration/Bitfinex.Client.Websocket.Tests.Integration.csproj b/test_integration/Bitfinex.Client.Websocket.Tests.Integration/Bitfinex.Client.Websocket.Tests.Integration.csproj
index 4ebc46e..b0a6f30 100644
--- a/test_integration/Bitfinex.Client.Websocket.Tests.Integration/Bitfinex.Client.Websocket.Tests.Integration.csproj
+++ b/test_integration/Bitfinex.Client.Websocket.Tests.Integration/Bitfinex.Client.Websocket.Tests.Integration.csproj
@@ -1,30 +1,30 @@
-
- net6
+
+ net8
- false
-
+ false
+
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
-
-
-
+
+
+
-
-
- PreserveNewest
-
-
+
+
+ PreserveNewest
+
+