public async Task <WebSocketSession> SubscribeToAccountBalance(string account, string[] objectIds, Action <string> cb) { _logger.LogInformation($"[AccountService] SubscribeToAccountBalance: account {account}, objectIds {string.Join("-", objectIds)}"); var lastDt = DateTime.Now; var notifier = new GrapheneWitnessNotifier(_webSocketClientFactory, _grapheneConfig); WebSocketSession ws = null; ws = await notifier.InitNotifierForObjects(objectIds); if (ws == null) { return(null); } EventHandler <Tuple <DateTime, string> > eventH1 = (object sender, Tuple <DateTime, string> e) => { cb(e.Item2); }; ws.SubscribeConsumePublic += eventH1; return(ws); }
public async Task <ExchangeLimitOrderDescription> CreateExchange(string account, decimal sellAmount, string sellAsset, decimal buyAmount, string buyAsset, string expiration, bool isFillOrKill, string fee_asset_id, string feeAssetSymbol, string guidLabel, int timeoutInMilliSecond) { _logger.LogInformation($"[BlockchainApi] Creating Exchange: account {account}, sellAmount {sellAmount}, sellAsset {sellAsset}, buyAmount {buyAmount}, buyAsset {buyAsset}, expiration {expiration}, isFillOrKill {isFillOrKill}, fee_asset_id {fee_asset_id}, feeAssetSymbol {feeAssetSymbol}, guidLabel {guidLabel}, timeoutInMilliSecond {timeoutInMilliSecond}"); ExchangeLimitOrderDescription returnVal = null; var lastDt = DateTime.Now; ManualResetEvent oSignalEvent = new ManualResetEvent(false); var notifier = new GrapheneWitnessNotifier(_webSocketClientFactory, _grapheneConfig); WebSocketSession ws = null; await semaphoreSlim.WaitAsync(); try { ws = await notifier.InitNotifierForMarket(sellAsset, buyAsset); if (ws == null) { return(null); } //var resPast = ws.OnTickCollection.Where(x => { // JToken token = JObject.Parse(x.Item2); // var guidFromWs = token.SelectToken("params[1][0][0][0][1].strguidone"); // if (guidFromWs != null && guidFromWs.ToString().Contains(guidLabel)) // { // return true; // } // return false; //}); //if (resPast.Any()) //{ // var rF = resPast.First(); // JToken tokenT = JObject.Parse(rF.Item2); // returnVal = tokenT.SelectToken("params[1][0][0][0][1]").ToObject<ExchangeLimitOrderDescription>(); // lastDt = rF.Item1; // oSignalEvent.Set(); //} EventHandler <Tuple <DateTime, string> > eventH1 = (object sender, Tuple <DateTime, string> e) => { JToken token = JObject.Parse(e.Item2); var guidFromWs = token.SelectToken("params[1][0][0][0][1].strguidone"); if (guidFromWs != null && guidFromWs.ToString().Equals(guidLabel, StringComparison.CurrentCultureIgnoreCase)) { returnVal = token.SelectToken("params[1][0][0][0][1]").ToObject <ExchangeLimitOrderDescription>(); lastDt = e.Item1; oSignalEvent.Set(); } }; ws.SubscribeConsumePublic += eventH1; var orderRes = await CreateLimitOrder(account, sellAmount, sellAsset, buyAmount, buyAsset, expiration, isFillOrKill, fee_asset_id, feeAssetSymbol, guidLabel, true); oSignalEvent.WaitOne(timeoutInMilliSecond); ws.SubscribeConsumePublic -= eventH1; ws.IsBusy = false; return(returnVal); } finally { //When the task is ready, release the semaphore. It is vital to ALWAYS release the semaphore when we are ready, or else we will end up with a Semaphore that is forever locked. //This is why it is important to do the Release within a try...finally clause; program execution may crash or take a different path, this way you are guaranteed execution semaphoreSlim.Release(); } }