private void Setup(IClientEmulator forwardingClient, IDotNetifyHubForwarderFactory hubForwarderFactory, IClientEmulator[] clients, Action <string, string> callback = null) { // Build a mock hub proxy that will be used to forward messages. This proxy will be set to communicate to another hub emulator. var hubProxy = Substitute.For <IDotNetifyHubProxy>(); hubProxy.StartAsync().Returns(Task.CompletedTask); hubProxy.ConnectionState.Returns(HubConnectionState.Connected); // When the hub proxy's Invoke method is called, call the other hub emulator's Invoke method, // then get the response through the client emulator connecting with that hub, and finally // raise the hub proxy's own Response_VM event with the response. hubProxy.Invoke(Arg.Any <string>(), Arg.Any <object[]>(), Arg.Any <IDictionary <string, object> >()) .Returns(arg => { var callType = arg[0].ToString(); var methodArgs = (arg[1] as object[]).Select(x => { if (x is string) { return(x); } if (x != null) { return(JObject.FromObject(x)); } return(null); }).ToArray(); var metadataString = JsonSerializer.Serialize((IDictionary <string, object>)arg[2]); var metadata = Newtonsoft.Json.JsonConvert.DeserializeObject <IDictionary <string, object> >(metadataString); foreach (var kvp in metadata.ToList()) { metadata[kvp.Key] = kvp.Value is string?kvp.Value: JObject.FromObject(kvp.Value); } forwardingClient.Hub.InvokeAsync(callType, methodArgs, metadata).GetAwaiter().GetResult(); var responses = forwardingClient.ResponseHistory.Select(x => x.Payload).ToArray(); forwardingClient.ResponseHistory.Clear(); foreach (var response in responses) { hubProxy.Response_VM += Raise.EventWith(this, (ResponseVMEventArgs) new InvokeResponseEventArgs { MethodName = response[0].ToString(), MethodArgs = (response[1] as object[]).Select(x => x.ToString()).ToArray(), Metadata = (response[2] as Dictionary <string, object>).ToDictionary(x => x.Key, x => x.Value.ToString()) }); } callback?.Invoke(callType, methodArgs[0].ToString()); return(Task.CompletedTask); }); // Build a mock hub response that will receive response back to the above hub proxy. var hubResponse = Stubber.Create <IDotNetifyHubResponse>() .Setup(x => x.SendAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns((string connectionId, string vmId, string data) => { var client = clients.First(x => x.ConnectionId == connectionId); return((client as IClientProxy).SendCoreAsync(nameof(IDotNetifyHubMethod.Response_VM), new object[] { new object[] { vmId, data } })); }) .Setup(x => x.SendToManyAsync(It.IsAny <IReadOnlyList <string> >(), It.IsAny <string>(), It.IsAny <string>())) .Returns((IReadOnlyList <string> connectionIds, string vmId, string data) => { foreach (var connectionId in connectionIds) { var client = clients.First(x => x.ConnectionId == connectionId); (client as IClientProxy).SendCoreAsync(nameof(IDotNetifyHubMethod.Response_VM), new object[] { new object[] { vmId, data } }); } return(Task.CompletedTask); }) .Object; var hubForwarder = new DotNetifyHubForwarder(hubProxy, hubResponse); hubForwarderFactory.InvokeInstanceAsync(Arg.Any <string>(), Arg.Any <ForwardingOptions>(), Arg.Any <Func <DotNetifyHubForwarder, Task> >()) .Returns((callInfo) => callInfo.Arg <Func <DotNetifyHubForwarder, Task> >().Invoke(hubForwarder)); }
/// <summary> /// Invokes Response_VM on multple connections. /// </summary> /// <param name="connectionId">SignalR connection.</param> /// <param name="vmId">Identifies the view model.</param> /// <param name="vmData">View model data.</param> public Task SendToManyAsync(IReadOnlyList <string> connectionIds, string vmId, string vmData) { return(_hubContext.Clients.Clients(_connectionId).SendAsync(RESPONSE_VM, new object[] { nameof(SendToManyAsync), new object[] { vmId, vmData }, DotNetifyHubForwarder.BuildResponseMetadata(connectionIds.ToArray()) })); }
/// <summary> /// Removes a connection from a group. /// </summary> /// <param name="connectionId">SignalR connection.</param> /// <param name="groupName">SignalR group name.</param> public Task RemoveFromGroupAsync(string connectionId, string groupName) { return(_hubContext.Clients.Client(_connectionId).SendAsync(RESPONSE_VM, new object[] { nameof(RemoveFromGroupAsync), new object[] { groupName }, DotNetifyHubForwarder.BuildResponseMetadata(connectionId) })); }
/// <summary> /// Invokes Response_VM on a connection. /// </summary> /// <param name="connectionId">SignalR connection.</param> /// <param name="vmId">Identifies the view model.</param> /// <param name="vmData">View model data.</param> public Task SendAsync(string connectionId, string vmId, string vmData) { return(_hubContext.Clients.Client(_connectionId).SendAsync(RESPONSE_VM, new object[] { nameof(SendAsync), new object[] { vmId, vmData }, DotNetifyHubForwarder.BuildResponseMetadata(connectionId) })); }
/// <summary> /// Invokes Response_VM on a group but exclude some connections. /// </summary> /// <param name="groupName">SignalR group name.</param> /// <param name="excludedConnectionIds">Excluded SignalR connections.</param> /// <param name="vmId">Identifies the view model.</param> /// <param name="vmData">View model data.</param> public Task SendToGroupExceptAsync(string groupName, IReadOnlyList <string> excludedConnectionIds, string vmId, string vmData) { return(_hubContext.Clients.Client(_connectionId).SendAsync(RESPONSE_VM, new object[] { nameof(SendToGroupExceptAsync), new object[] { groupName, vmId, vmData }, DotNetifyHubForwarder.BuildResponseMetadata(excludedConnectionIds.ToArray()) })); }