/// <summary> /// Pumps incoming messages from <paramref name="socket"/> into their corresponding observables. /// </summary> /// <param name="socket"> /// The socket. /// </param> /// <param name="observableParams"> /// The incoming observables. /// </param> /// <returns> /// A <see cref="Task"/> which completes when an error occurs, the socket closes, or . /// </returns> private static async Task IncomingMessagePump(WebSocket socket, IDictionary<string, SingleSubscriptionObservable> observableParams) { while (!socket.IsClosed) { try { var message = await socket.ReceiveString(); if (string.IsNullOrWhiteSpace(message)) { continue; } // Get the name of the incoming observable. var nameIndex = message.IndexOf('.'); if (nameIndex <= 0) { nameIndex = message.Length; } var name = message.Substring(1, nameIndex - 1); // Retrieve the named observable. SingleSubscriptionObservable subscription; if (!observableParams.TryGetValue(name, out subscription) || subscription.Subscription.IsCancellationRequested) { // Observable not found, meaning that the controller method does not care about this observable. continue; } var observer = await subscription.Observer; // Route the message to the correct method. switch (message[0]) { case ResponseKind.Final: { var payload = message.Substring(nameIndex + 1); observer.OnNext(payload); observer.OnCompleted(); // Remove the observable, it will never be called again. observableParams.Remove(name); break; } case ResponseKind.Next: { var payload = message.Substring(nameIndex + 1); observer.OnNext(payload); break; } case ResponseKind.Error: { var payload = message.Substring(nameIndex + 1); observer.OnError(new Exception(payload)); // Remove the observable, it will never be called again. observableParams.Remove(name); break; } case ResponseKind.Completed: { observer.OnCompleted(); // Remove the observable, it will never be called again. observableParams.Remove(name); break; } } } catch (Exception) { // An error occurred, exit. break; } if (!observableParams.Any()) { // No more observables, exit. break; } } foreach (var subscription in observableParams.Values.Where(subscription => !subscription.Subscription.IsCancellationRequested)) { (await subscription.Observer).OnCompleted(); } }
/// <summary> /// Pumps incoming messages from <paramref name="socket"/> into their corresponding observables. /// </summary> /// <param name="socket"> /// The socket. /// </param> /// <param name="observableParams"> /// The incoming observables. /// </param> /// <returns> /// A <see cref="Task"/> which completes when an error occurs, the socket closes, or . /// </returns> private static async Task IncomingMessagePump(WebSocket socket, IDictionary <string, SingleSubscriptionObservable> observableParams) { while (!socket.IsClosed) { try { var message = await socket.ReceiveString(); if (string.IsNullOrWhiteSpace(message)) { continue; } // Get the name of the incoming observable. var nameIndex = message.IndexOf('.'); if (nameIndex <= 0) { nameIndex = message.Length; } var name = message.Substring(1, nameIndex - 1); // Retrieve the named observable. SingleSubscriptionObservable subscription; if (!observableParams.TryGetValue(name, out subscription) || subscription.Subscription.IsCancellationRequested) { // Observable not found, meaning that the controller method does not care about this observable. continue; } var observer = await subscription.Observer; // Route the message to the correct method. switch (message[0]) { case ResponseKind.Final: { var payload = message.Substring(nameIndex + 1); observer.OnNext(payload); observer.OnCompleted(); // Remove the observable, it will never be called again. observableParams.Remove(name); break; } case ResponseKind.Next: { var payload = message.Substring(nameIndex + 1); observer.OnNext(payload); break; } case ResponseKind.Error: { var payload = message.Substring(nameIndex + 1); observer.OnError(new Exception(payload)); // Remove the observable, it will never be called again. observableParams.Remove(name); break; } case ResponseKind.Completed: { observer.OnCompleted(); // Remove the observable, it will never be called again. observableParams.Remove(name); break; } } } catch (Exception) { // An error occurred, exit. break; } if (!observableParams.Any()) { // No more observables, exit. break; } } foreach (var subscription in observableParams.Values.Where(subscription => !subscription.Subscription.IsCancellationRequested)) { (await subscription.Observer).OnCompleted(); } }