Beispiel #1
0
        private bool TryGetStreamingEnumerator(HubConnectionContext connection, string invocationId, ObjectMethodExecutor methodExecutor, object result, Type resultType, out IAsyncEnumerator <object> enumerator)
        {
            if (result != null)
            {
                // TODO: cache reflection for performance, on HubMethodDescriptor maybe?
                resultType = UnwrapTask(resultType);

                var observableInterface = IsIObservable(resultType) ?
                                          resultType :
                                          resultType.GetInterfaces().FirstOrDefault(IsIObservable);
                if (observableInterface != null)
                {
                    enumerator = AsyncEnumeratorAdapters.FromObservable(result, observableInterface, CreateCancellation());
                    return(true);
                }

                if (IsChannel(resultType, out var payloadType))
                {
                    enumerator = AsyncEnumeratorAdapters.FromChannel(result, payloadType, CreateCancellation());
                    return(true);
                }
            }

            enumerator = null;
            return(false);

            CancellationToken CreateCancellation()
            {
                var streamCts = new CancellationTokenSource();

                connection.ActiveRequestCancellationSources.TryAdd(invocationId, streamCts);
                return(CancellationTokenSource.CreateLinkedTokenSource(connection.ConnectionAbortedToken, streamCts.Token).Token);
            }
        }
Beispiel #2
0
        private IAsyncEnumerator <object> GetStreamingEnumerator(HubConnectionContext connection, string invocationId, ObjectMethodExecutor methodExecutor, object result, Type resultType)
        {
            if (result != null)
            {
                var observableInterface = IsIObservable(resultType) ?
                                          resultType :
                                          resultType.GetInterfaces().FirstOrDefault(IsIObservable);
                if (observableInterface != null)
                {
                    return(AsyncEnumeratorAdapters.FromObservable(result, observableInterface, CreateCancellation()));
                }

                if (IsChannel(resultType, out var payloadType))
                {
                    return(AsyncEnumeratorAdapters.FromChannel(result, payloadType, CreateCancellation()));
                }
            }

            Log.InvalidReturnValueFromStreamingMethod(_logger, methodExecutor.MethodInfo.Name);
            throw new InvalidOperationException($"The value returned by the streaming method '{methodExecutor.MethodInfo.Name}' is null, does not implement the IObservable<> interface or is not a ReadableChannel<>.");

            CancellationToken CreateCancellation()
            {
                var streamCts = new CancellationTokenSource();

                connection.ActiveRequestCancellationSources.TryAdd(invocationId, streamCts);
                return(CancellationTokenSource.CreateLinkedTokenSource(connection.ConnectionAbortedToken, streamCts.Token).Token);
            }
        }