public async Task RequestVMAsync(string vmId, object vmArg) { object data = NormalizeType(vmArg); try { _callerContext = Context; _hubContext = new DotNetifyHubContext(_callerContext, nameof(IDotNetifyHubMethod.Request_VM), vmId, data, null, Principal); await _hubPipeline.RunMiddlewaresAsync(_hubContext, async ctx => { Principal = ctx.Principal; string groupName = await VMController.OnRequestVMAsync(Context.ConnectionId, ctx.VMId, ctx.Data); // A multicast view model may be assigned to a SignalR group. If so, add the connection to the group. if (!string.IsNullOrEmpty(groupName)) { await _globalHubContext.Groups.AddToGroupAsync(Context.ConnectionId, groupName); } }); } catch (Exception ex) { var finalEx = await _hubPipeline.RunExceptionMiddlewareAsync(Context, ex); if (finalEx is OperationCanceledException == false) { await ResponseVMAsync(Context.ConnectionId, vmId, SerializeException(finalEx)); } } }
public async Task InvokeAsync(string methodName, object[] methodArgs, IDictionary <string, object> metadata) { Context.Items.Clear(); if (metadata != null) { foreach (var kvp in metadata) { Context.Items[kvp.Key] = kvp.Value; } } switch (methodName) { case nameof(IDotNetifyHubMethod.Request_VM): methodName = nameof(RequestVMAsync); break; case nameof(IDotNetifyHubMethod.Update_VM): methodName = nameof(UpdateVMAsync); break; case nameof(IDotNetifyHubMethod.Dispose_VM): methodName = nameof(DisposeVMAsyc); break; case nameof(IDotNetifyHubMethod.Response_VM): methodName = nameof(OnHubForwardResponseAsync); break; } var methodInfo = GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (methodInfo != null) { var methodParams = methodInfo.GetParameters(); for (int i = 0; i < methodArgs.Length; i++) { var paramType = methodParams[i].ParameterType; if (methodArgs[i] is string || methodArgs[i] is JsonElement || methodArgs[i] is JObject) { methodArgs[i] = methodArgs[i].ToString().ConvertFromString(paramType); } } await methodInfo.InvokeAsync(this, methodArgs); } else { // Unknown method. Run it through the middleware pipeline in case one wants to take action on it. var hubContext = new DotNetifyHubContext(Context, methodName, null, methodArgs, null, Context.User); await _hubPipeline.RunMiddlewaresAsync(hubContext, ctx => Task.CompletedTask); } }
/// <summary> /// Creates view model filter delegate that runs before it responds to something. /// </summary> /// <param name="hubContext">DotNetify hub context.</param> /// <param name="hubPipeline">Middleware/VM filter pipeline.</param> /// <param name="vmData">View model data from the request.</param> /// <returns>View model filter delegate.</returns> private VMController.FilterDelegate CreateRespondingVMFilter(IHubPipeline hubPipeline, string vmId, object vmData) { return(async(_vmId, vm, data, vmAction) => { var hubContext = new DotNetifyHubContext(new HttpCallerContext(HttpContext), nameof(DotNetifyHub.ResponseVMAsync), vmId, vmData, BuildHeaders(), HttpContext?.User); await hubPipeline.RunMiddlewaresAsync(hubContext, async ctx => { await CreateVMFilter(hubContext, hubPipeline)(_vmId, vm, data, vmAction); }); }); }
public async Task <string> Request_VM( string vmId, [FromQuery] string vmArg, [FromServices] IVMFactory vmFactory, [FromServices] IHubServiceProvider hubServiceProvider, [FromServices] IVMServiceScopeFactory serviceScopeFactory, [FromServices] IHubPipeline hubPipeline, [FromServices] IPrincipalAccessor principalAccessor ) { var taskCompletionSource = new TaskCompletionSource <string>(TaskCreationOptions.RunContinuationsAsynchronously); Task responseVM(string arg1, string arg2, string arg3) { taskCompletionSource.TrySetResult(arg3); return(Task.CompletedTask); } var vmController = new VMController(responseVM, vmFactory, serviceScopeFactory.CreateScope()) { ResponseVMFilter = CreateRespondingVMFilter(hubPipeline, vmId, vmArg) }; var httpCallerContext = InitializeContext(vmController, hubServiceProvider, principalAccessor); var connectionId = httpCallerContext.ConnectionId; try { var hubContext = new DotNetifyHubContext(httpCallerContext, nameof(Request_VM), vmId, vmArg, BuildHeaders(), httpCallerContext.User); vmController.RequestVMFilter = CreateVMFilter(hubContext, hubPipeline); await hubPipeline.RunMiddlewaresAsync(hubContext, async ctx => { await vmController.OnRequestVMAsync(connectionId, ctx.VMId, ctx.Data); vmController.Dispose(); }); } catch (Exception ex) { var finalEx = await hubPipeline.RunExceptionMiddlewareAsync(httpCallerContext, ex); if (finalEx is OperationCanceledException == false) { taskCompletionSource.TrySetResult(DotNetifyHub.SerializeException(finalEx)); } } return(await taskCompletionSource.Task); }