private void ClearGeneratedApiObjects() { lock (GeneratedApiObjects) { foreach (var item in GeneratedApiObjects.Keys) { try { if (GeneratedApiObjects.TryRemove(item, out var value)) { GeneratedAPI target = null; if (value?.TryGetTarget(out target) ?? false) { _ = Task.Run(() => { try { target?.OnClosed(); } catch { } }); } } } catch (Exception ex) { logger.Error(ex); } } } }
private void StartReceiveLoop(CancellationToken cancellationToken) { _ = Task.Run(async() => { byte[] buffer = new byte[4096 * 8]; #region Helper to Notify API Objects void notifyGeneratedAPI(WeakReference <GeneratedAPI> wrGeneratedAPI, bool close) { Console.WriteLine("notifyGeneratedAPI"); GeneratedAPI generatedAPI = null; wrGeneratedAPI?.TryGetTarget(out generatedAPI); if (generatedAPI != null) { Console.WriteLine("notifyGeneratedAPI - genAPI"); _ = Task.Run(() => { try { Console.WriteLine("notifyGeneratedAPI - RUN"); if (close) { generatedAPI?.OnClosed(); } else { generatedAPI?.OnChanged(); } } catch (Exception ex) { logger.Error(ex); } }).ConfigureAwait(false); } } #endregion try { while (!cancellationToken.IsCancellationRequested && socket != null && socket.State == WebSocketState.Open) { var writeSegment = new ArraySegment <byte>(buffer); WebSocketReceiveResult result; do { result = await socket.ReceiveAsync(writeSegment, cancellationToken).ConfigureAwait(false); writeSegment = new ArraySegment <byte>(buffer, writeSegment.Offset + result.Count, writeSegment.Count - result.Count); // check buffer overflow if (!result.EndOfMessage && writeSegment.Count == 0) { // autoIncreaseRecieveBuffer) Array.Resize(ref buffer, buffer.Length * 2); writeSegment = new ArraySegment <byte>(buffer, writeSegment.Offset, buffer.Length - writeSegment.Offset); } } while (!result.EndOfMessage); var message = Encoding.UTF8.GetString(buffer, 0, writeSegment.Offset); logger.Trace("Response" + message); try { var responseMessage = JsonConvert.DeserializeObject <JsonRpcGeneratedAPIResponseMessage>(message); try { var list = Messages.GetBuffer(); if (responseMessage != null) { foreach (var item in list) { if (item != null && item.ID == responseMessage.Id) { var ts = DateTime.Now - item.StartTime; item.Duration = ts.TotalMilliseconds; item.Error = responseMessage.Error?.ToString() ?? ""; } } } } catch (Exception ex) { logger.Error(ex); } if (responseMessage != null && (responseMessage.Result != null || responseMessage.Error != null || responseMessage.Change?.Count > 0 || responseMessage.Closed?.Count > 0 )) { if (responseMessage.Id != null) { OpenRequests.TryRemove(responseMessage.Id.Value, out var tcs); if (responseMessage.Error != null) { tcs?.SetException(new Exception(responseMessage.Error?.ToString())); } else { tcs?.SetResult(responseMessage.Result); } } #region Notify Changed or Closed API Objects if (responseMessage.Change != null) { foreach (var item in responseMessage.Change) { logger.Trace($"Object Id: {item} changed."); GeneratedApiObjects.TryGetValue(item, out var wkValues); notifyGeneratedAPI(wkValues, false); } } if (responseMessage.Closed != null) { foreach (var item in responseMessage.Closed) { logger.Trace($"Object Id: {item} closed."); GeneratedApiObjects.TryRemove(item, out var wkValues); notifyGeneratedAPI(wkValues, true); } } #endregion } else { var requestMessage = JsonConvert.DeserializeObject <JsonRpcRequestMessage>(message); if (requestMessage != null) { _ = Task.Run(() => { try { this.RPCMethodCalled?.Invoke(this, requestMessage); } catch (Exception ex) { logger.Error(ex); } }); } } } catch (Exception ex) { logger.Error(ex); } } ClearGeneratedApiObjects(); } catch (Exception ex) { logger.Error(ex); } }); }