@@ -263,16 +263,20 @@ await SendInvocationError(hubMethodInvocationMessage.InvocationId, connection,
263
263
{
264
264
var result = await ExecuteHubMethod ( methodExecutor , hub , arguments ) ;
265
265
266
- if ( ! TryGetStreamingEnumerator ( connection , hubMethodInvocationMessage . InvocationId , descriptor , result , out var enumerator , ref cts ) )
266
+ if ( result == null )
267
267
{
268
268
Log . InvalidReturnValueFromStreamingMethod ( _logger , methodExecutor . MethodInfo . Name ) ;
269
269
await SendInvocationError ( hubMethodInvocationMessage . InvocationId , connection ,
270
- $ "The value returned by the streaming method '{ methodExecutor . MethodInfo . Name } ' is not a ChannelReader<>.") ;
270
+ $ "The value returned by the streaming method '{ methodExecutor . MethodInfo . Name } ' is not a ChannelReader<> or IAsyncEnumerable<> .") ;
271
271
return ;
272
272
}
273
273
274
+ cts = cts ?? CancellationTokenSource . CreateLinkedTokenSource ( connection . ConnectionAborted ) ;
275
+ connection . ActiveRequestCancellationSources . TryAdd ( hubMethodInvocationMessage . InvocationId , cts ) ;
276
+ var enumerable = descriptor . FromReturnedStream ( result , cts . Token ) ;
277
+
274
278
Log . StreamingResult ( _logger , hubMethodInvocationMessage . InvocationId , methodExecutor ) ;
275
- _ = StreamResultsAsync ( hubMethodInvocationMessage . InvocationId , connection , enumerator , scope , hubActivator , hub , cts ) ;
279
+ _ = StreamResultsAsync ( hubMethodInvocationMessage . InvocationId , connection , enumerable , scope , hubActivator , hub , cts ) ;
276
280
}
277
281
278
282
else if ( string . IsNullOrEmpty ( hubMethodInvocationMessage . InvocationId ) )
@@ -358,7 +362,7 @@ await SendInvocationError(hubMethodInvocationMessage.InvocationId, connection,
358
362
}
359
363
}
360
364
361
- private async Task StreamResultsAsync ( string invocationId , HubConnectionContext connection , IAsyncEnumerator < object > enumerator , IServiceScope scope ,
365
+ private async Task StreamResultsAsync ( string invocationId , HubConnectionContext connection , IAsyncEnumerable < object > enumerable , IServiceScope scope ,
362
366
IHubActivator < THub > hubActivator , THub hub , CancellationTokenSource streamCts )
363
367
{
364
368
string error = null ;
@@ -367,10 +371,11 @@ private async Task StreamResultsAsync(string invocationId, HubConnectionContext
367
371
{
368
372
try
369
373
{
370
- while ( await enumerator . MoveNextAsync ( ) )
374
+
375
+ await foreach ( var streamItem in enumerable )
371
376
{
372
377
// Send the stream item
373
- await connection . WriteAsync ( new StreamItemMessage ( invocationId , enumerator . Current ) ) ;
378
+ await connection . WriteAsync ( new StreamItemMessage ( invocationId , streamItem ) ) ;
374
379
}
375
380
}
376
381
catch ( ChannelClosedException ex )
@@ -389,8 +394,6 @@ private async Task StreamResultsAsync(string invocationId, HubConnectionContext
389
394
}
390
395
finally
391
396
{
392
- await enumerator . DisposeAsync ( ) ;
393
-
394
397
hubActivator . Release ( hub ) ;
395
398
396
399
// Dispose the linked CTS for the stream.
@@ -470,10 +473,10 @@ private static async Task<bool> IsHubMethodAuthorizedSlow(IServiceProvider provi
470
473
return authorizationResult . Succeeded ;
471
474
}
472
475
473
- private async Task < bool > ValidateInvocationMode ( HubMethodDescriptor hubMethodDescriptor , bool isStreamedInvocation ,
476
+ private async Task < bool > ValidateInvocationMode ( HubMethodDescriptor hubMethodDescriptor , bool isStreamResponse ,
474
477
HubMethodInvocationMessage hubMethodInvocationMessage , HubConnectionContext connection )
475
478
{
476
- if ( hubMethodDescriptor . IsStreamable && ! isStreamedInvocation )
479
+ if ( hubMethodDescriptor . IsStreamResponse && ! isStreamResponse )
477
480
{
478
481
// Non-null/empty InvocationId? Blocking
479
482
if ( ! string . IsNullOrEmpty ( hubMethodInvocationMessage . InvocationId ) )
@@ -486,7 +489,7 @@ await connection.WriteAsync(CompletionMessage.WithError(hubMethodInvocationMessa
486
489
return false ;
487
490
}
488
491
489
- if ( ! hubMethodDescriptor . IsStreamable && isStreamedInvocation )
492
+ if ( ! hubMethodDescriptor . IsStreamResponse && isStreamResponse )
490
493
{
491
494
Log . NonStreamingMethodCalledWithStream ( _logger , hubMethodInvocationMessage ) ;
492
495
await connection . WriteAsync ( CompletionMessage . WithError ( hubMethodInvocationMessage . InvocationId ,
@@ -498,26 +501,6 @@ await connection.WriteAsync(CompletionMessage.WithError(hubMethodInvocationMessa
498
501
return true ;
499
502
}
500
503
501
- private bool TryGetStreamingEnumerator ( HubConnectionContext connection , string invocationId , HubMethodDescriptor hubMethodDescriptor , object result , out IAsyncEnumerator < object > enumerator , ref CancellationTokenSource streamCts )
502
- {
503
- if ( result != null )
504
- {
505
- if ( hubMethodDescriptor . IsStreamable )
506
- {
507
- if ( streamCts == null )
508
- {
509
- streamCts = CancellationTokenSource . CreateLinkedTokenSource ( connection . ConnectionAborted ) ;
510
- }
511
- connection . ActiveRequestCancellationSources . TryAdd ( invocationId , streamCts ) ;
512
- enumerator = hubMethodDescriptor . FromReturnedStream ( result , streamCts . Token ) ;
513
- return true ;
514
- }
515
- }
516
-
517
- enumerator = null ;
518
- return false ;
519
- }
520
-
521
504
private void DiscoverHubMethods ( )
522
505
{
523
506
var hubType = typeof ( THub ) ;
0 commit comments