internal static async Task DisableLiveTask() { // Cancel streaming operation(s) and unsubscribe all. await ClientManager.UnsubscribeAllAsync(); // Cancel streaming operation(s). LiveUserDataTokenSource?.Cancel(); // Wait for live task to complete. if (LiveUserDataTask != null && !LiveUserDataTask.IsCompleted) { await LiveUserDataTask; } LiveUserDataTokenSource?.Dispose(); LiveUserDataTokenSource = null; LiveUserDataTask = null; // Unsubscribe all combined streams from global web socket stream. var webSocket = ServiceProvider.GetService <IWebSocketStream>(); webSocket.UnsubscribeAll(); lock (ConsoleSync) { if (UserDataManager != null) { Console.WriteLine(); Console.WriteLine(" ...live account feed disabled."); } UserDataManager = null; } }
public static async Task Main(string[] args) { // Un-comment to run... //await AccountBalancesExample.ExampleMain(args); //await AccountBalancesExample.AdvancedExampleMain(args); //await MinimalWithDependencyInjection.ExampleMain(args); //await MinimalWithoutDependencyInjection.ExampleMain(args); //await OrderBookCacheAccountBalanceExample.AdvancedExampleMain(args); //await ReadMeExample.ExampleMain(args); var cts = new CancellationTokenSource(); try { // Load configuration. Configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", true, false) .AddUserSecrets <Program>() // for access to API key and secret. .Build(); // Configure services. ServiceProvider = new ServiceCollection() // ReSharper disable once ArgumentsStyleLiteral .AddBinance(useSingleCombinedStream: true) // add default Binance services. // Use alternative, low-level, web socket client implementation. //.AddTransient<IWebSocketClient, WebSocket4NetClient>() //.AddTransient<IWebSocketClient, WebSocketSharpClient>() .AddOptions() .Configure <BinanceApiOptions>(Configuration.GetSection("ApiOptions")) .AddLogging(builder => builder.SetMinimumLevel(LogLevel.Trace)) .BuildServiceProvider(); // Configure logging. ServiceProvider .GetService <ILoggerFactory>() .AddConsole(Configuration.GetSection("Logging:Console")) .AddFile(Configuration.GetSection("Logging:File")); // NOTE: Using ":" requires Microsoft.Extensions.Configuration.Binder. var apiKey = Configuration["BinanceApiKey"] // user secrets configuration. ?? Configuration.GetSection("User")["ApiKey"]; // appsettings.json configuration. var apiSecret = Configuration["BinanceApiSecret"] // user secrets configuration. ?? Configuration.GetSection("User")["ApiSecret"]; // appsettings.json configuration. if (string.IsNullOrWhiteSpace(apiKey) || string.IsNullOrWhiteSpace(apiSecret)) { PrintApiNotice(); } if (!string.IsNullOrEmpty(apiKey)) { User = ServiceProvider .GetService <IBinanceApiUserProvider>() .CreateUser(apiKey, apiSecret); } Api = ServiceProvider.GetService <IBinanceApi>(); ClientManager = ServiceProvider.GetService <IBinanceWebSocketClientManager>(); ClientManager.Error += (s, e) => { lock (ConsoleSync) { Console.WriteLine(); Console.WriteLine($"! Client Manager Error: \"{e.Exception.Message}\""); Console.WriteLine(); } }; UserDataManager = ServiceProvider.GetService <IUserDataWebSocketManager>(); // Instantiate all assembly command handlers. foreach (var type in Assembly.GetExecutingAssembly().GetTypes()) { if (typeof(IHandleCommand).IsAssignableFrom(type) && !type.IsAbstract) { CommandHandlers.Add((IHandleCommand)Activator.CreateInstance(type)); } } await SuperLoopAsync(cts.Token); } catch (Exception e) { lock (ConsoleSync) { Console.WriteLine($"! FAIL: \"{e.Message}\""); if (e.InnerException != null) { Console.WriteLine($" -> Exception: \"{e.InnerException.Message}\""); } } } finally { await DisableLiveTaskAsync(); cts.Cancel(); cts.Dispose(); User?.Dispose(); ClientManager?.Dispose(); lock (ConsoleSync) { Console.WriteLine(); Console.WriteLine(" ...press any key to close window."); Console.ReadKey(true); } } }
/// <summary> /// /// </summary> /// <param name="manager"></param> /// <param name="user"></param> /// <param name="token"></param> /// <returns></returns> public static Task SubscribeAndStreamAsync(this IUserDataWebSocketManager manager, IBinanceApiUser user, CancellationToken token) => manager.SubscribeAndStreamAsync(user, null, token);
/// <summary> /// Wait until web socket is open. /// </summary> /// <param name="manager"></param> /// <param name="token"></param> /// <returns></returns> public static Task WaitUntilWebSocketOpenAsync(this IUserDataWebSocketManager manager, CancellationToken token = default) => manager.Client.Publisher.Stream.WaitUntilWebSocketOpenAsync(token);
/// <summary> /// /// </summary> /// <param name="manager"></param> /// <param name="user"></param> /// <param name="token"></param> /// <returns></returns> public static Task UnsubscribeAsync(this IUserDataWebSocketManager manager, IBinanceApiUser user, CancellationToken token = default) => manager.UnsubscribeAsync <UserDataEventArgs>(user, null, token);