protected override void Initialize(HttpControllerContext controllerContext) { var hub = ((IHub)this); var hubName = this.GetType().FullName; var hubManager = _resolver.Resolve<IHubManager>(); var descriptor = hubManager.EnsureHub(hubName); var user = controllerContext.Request.GetUserPrincipal(); // Response parameter is null here because outgoing broadcast messages will always go // via the SignalR intrinsics, and method return values via the Web API intrinsics. var hostContext = new HostContext(new WebApiRequest(controllerContext.Request), null, user); var connectionId = hostContext.Request.QueryString["connectionId"]; hub.Context = new HubContext(hostContext, connectionId); var connection = _resolver.Resolve<IConnectionManager>().GetConnection<HubDispatcher>(); var state = new TrackingDictionary(); var agent = new ClientAgent(connection, descriptor.Name); hub.Caller = new SignalAgent(connection, connectionId, descriptor.Name, state); hub.Agent = agent; hub.GroupManager = agent; base.Initialize(controllerContext); }
protected override Task OnDisconnectAsync(string connectionId) { // Loop over each hub and call disconnect (if the hub supports it) foreach (Type type in GetDisconnectTypes()) { string hubName = type.FullName; IHub hub = _hubFactory.CreateHub(hubName); var disconnect = hub as IDisconnect; if (disconnect != null) { // REVIEW: We don't have any client state here since we're calling this from the server. // Will this match user expectations? var state = new TrackingDictionary(); hub.Context = new HubContext(_context, connectionId); hub.Caller = new SignalAgent(Connection, connectionId, hubName, state); var agent = new ClientAgent(Connection, hubName); hub.Agent = agent; hub.GroupManager = agent; disconnect.Disconnect(); } } return(TaskAsyncHelper.Empty); }
protected override void OnDisconnect(string clientId) { // Loop over each hub and call disconnect (if the hub supports it) foreach (Type type in _hubLocator.GetHubs()) { string hubName = type.FullName; IHub hub = _hubFactory.CreateHub(hubName); var disconnect = hub as IDisconnect; if (disconnect != null) { // REVIEW: We don't have any client state here since we're calling this from the server. // Will this match user expectations? var state = new TrackingDictionary(); hub.Context = new HubContext(clientId, _cookies, _user); hub.Caller = new SignalAgent(Connection, clientId, hubName, state); var agent = new ClientAgent(Connection, hubName); hub.Agent = agent; hub.GroupManager = agent; disconnect.Disconnect(); } } }
protected override Task OnReceivedAsync(string connectionId, string data) { var hubRequest = _serializer.Deserialize<HubRequest>(data); // Create the hub IHub hub = _hubFactory.CreateHub(hubRequest.Hub); // Deserialize the parameter name value pairs so we can match it up with the method's parameters var parameters = hubRequest.Data; // Resolve the action ActionInfo actionInfo = _actionResolver.ResolveAction(hub.GetType(), hubRequest.Action, parameters); if (actionInfo == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "'{0}' could not be resolved.", hubRequest.Action)); } string hubName = hub.GetType().FullName; var state = new TrackingDictionary(hubRequest.State); hub.Context = new HubContext(connectionId, _cookies, _user); hub.Caller = new SignalAgent(Connection, connectionId, hubName, state); var agent = new ClientAgent(Connection, hubName); hub.Agent = agent; hub.GroupManager = agent; Task resultTask; try { // Execute the method object result = actionInfo.Method.Invoke(hub, actionInfo.Arguments); Type returnType = result != null ? result.GetType() : actionInfo.Method.ReturnType; if (typeof(Task).IsAssignableFrom(returnType)) { var task = (Task)result; if (!returnType.IsGenericType) { return task.ContinueWith(t => ProcessResult(state, null, hubRequest, t.Exception)) .FastUnwrap(); } else { // Get the <T> in Task<T> Type resultType = returnType.GetGenericArguments().Single(); // Get the correct ContinueWith overload var continueWith = TaskAsyncHelper.GetContinueWith(task.GetType()); var taskParameter = Expression.Parameter(continueWith.Type); var processResultMethod = typeof(HubDispatcher).GetMethod("ProcessResult", BindingFlags.NonPublic | BindingFlags.Instance); var taskResult = Expression.Property(taskParameter, "Result"); var taskException = Expression.Property(taskParameter, "Exception"); var body = Expression.Call(Expression.Constant(this), processResultMethod, Expression.Constant(state), Expression.Convert(taskResult, typeof(object)), Expression.Constant(hubRequest), Expression.Convert(taskException, typeof(Exception))); var lambda = Expression.Lambda(body, taskParameter); var call = Expression.Call(Expression.Constant(task, continueWith.Type), continueWith.Method, lambda); return Expression.Lambda<Func<Task<Task>>>(call).Compile()().FastUnwrap(); } } else { resultTask = ProcessResult(state, result, hubRequest, null); } } catch (TargetInvocationException e) { resultTask = ProcessResult(state, null, hubRequest, e); } return resultTask .ContinueWith(_ => base.OnReceivedAsync(connectionId, data)) .FastUnwrap(); }
protected override void OnDisconnect(string connectionId) { // Loop over each hub and call disconnect (if the hub supports it) foreach (Type type in GetDisconnectTypes()) { string hubName = type.FullName; IHub hub = _hubFactory.CreateHub(hubName); var disconnect = hub as IDisconnect; if (disconnect != null) { // REVIEW: We don't have any client state here since we're calling this from the server. // Will this match user expectations? var state = new TrackingDictionary(); hub.Context = new HubContext(connectionId, _cookies, _user); hub.Caller = new SignalAgent(Connection, connectionId, hubName, state); var agent = new ClientAgent(Connection, hubName); hub.Agent = agent; hub.GroupManager = agent; disconnect.Disconnect(); } } }
protected override Task OnReceivedAsync(string clientId, string data) { var hubRequest = _serializer.Deserialize <HubRequest>(data); // Create the hub IHub hub = _hubFactory.CreateHub(hubRequest.Hub); // Deserialize the parameter name value pairs so we can match it up with the method's parameters var parameters = hubRequest.Data; // Resolve the action ActionInfo actionInfo = _actionResolver.ResolveAction(hub.GetType(), hubRequest.Action, parameters); if (actionInfo == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "'{0}' could not be resolved.", hubRequest.Action)); } string hubName = hub.GetType().FullName; var state = new TrackingDictionary(hubRequest.State); hub.Context = new HubContext(clientId, _cookies, _user); hub.Caller = new SignalAgent(Connection, clientId, hubName, state); var agent = new ClientAgent(Connection, hubName); hub.Agent = agent; hub.GroupManager = agent; try { // Execute the method object result = actionInfo.Method.Invoke(hub, actionInfo.Arguments); Type returnType = result != null?result.GetType() : actionInfo.Method.ReturnType; if (typeof(Task).IsAssignableFrom(returnType)) { var task = (Task)result; if (!returnType.IsGenericType) { return(task.ContinueWith(t => ProcessResult(state, null, hubRequest, t.Exception))); } else { // Get the <T> in Task<T> Type resultType = returnType.GetGenericArguments().Single(); // Get the correct ContinueWith overload var continueWith = (from m in task.GetType().GetMethods() let methodParameters = m.GetParameters() where m.Name.Equals("ContinueWith", StringComparison.OrdinalIgnoreCase) && methodParameters.Length == 1 let parameter = methodParameters[0] where parameter.ParameterType.IsGenericType && typeof(Action <>) == parameter.ParameterType.GetGenericTypeDefinition() select new { Method = m, ArgType = parameter.ParameterType.GetGenericArguments()[0] }) .FirstOrDefault(); var taskParameter = Expression.Parameter(continueWith.ArgType); var processResultMethod = typeof(HubDispatcher).GetMethod("ProcessResult", BindingFlags.NonPublic | BindingFlags.Instance); var taskResult = Expression.Property(taskParameter, "Result"); var taskException = Expression.Property(taskParameter, "Exception"); var body = Expression.Call(Expression.Constant(this), processResultMethod, Expression.Constant(state), Expression.Convert(taskResult, typeof(object)), Expression.Constant(hubRequest), Expression.Convert(taskException, typeof(Exception))); var lambda = Expression.Lambda(body, taskParameter); var call = Expression.Call(Expression.Constant(task, continueWith.ArgType), continueWith.Method, lambda); return(Expression.Lambda <Func <Task> >(call).Compile()()); } } else { ProcessResult(state, result, hubRequest, null); } } catch (TargetInvocationException e) { ProcessResult(state, null, hubRequest, e); } return(base.OnReceivedAsync(clientId, data)); }
public Task Invoke(string method, params object[] args) { return(ClientAgent.Invoke(_connection, _signal, _hubName, method, args)); }
public static Task Invoke(string hubName, string method, params object[] args) { var connection = Connection.GetConnection <HubDispatcher>(); return(ClientAgent.Invoke(connection, method, hubName, method, args)); }
protected override Task OnReceivedAsync(string connectionId, string data) { var hubRequest = _serializer.Deserialize <HubRequest>(data); // Create the hub IHub hub = _hubFactory.CreateHub(hubRequest.Hub); // Deserialize the parameter name value pairs so we can match it up with the method's parameters var parameters = hubRequest.Data; // Resolve the action ActionInfo actionInfo = _actionResolver.ResolveAction(hub.GetType(), hubRequest.Action, parameters); if (actionInfo == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "'{0}' could not be resolved.", hubRequest.Action)); } string hubName = hub.GetType().FullName; var state = new TrackingDictionary(hubRequest.State); hub.Context = new HubContext(_context, connectionId); hub.Caller = new SignalAgent(Connection, connectionId, hubName, state); var agent = new ClientAgent(Connection, hubName); hub.Agent = agent; hub.GroupManager = agent; Task resultTask; try { // Execute the method object result = actionInfo.Method.Invoke(hub, actionInfo.Arguments); Type returnType = result != null?result.GetType() : actionInfo.Method.ReturnType; if (typeof(Task).IsAssignableFrom(returnType)) { var task = (Task)result; if (!returnType.IsGenericType) { return(task.ContinueWith(t => ProcessResult(state, null, hubRequest, t.Exception)) .FastUnwrap()); } else { // Get the <T> in Task<T> Type resultType = returnType.GetGenericArguments().Single(); // Get the correct ContinueWith overload var continueWith = TaskAsyncHelper.GetContinueWith(task.GetType()); var taskParameter = Expression.Parameter(continueWith.Type); var processResultMethod = typeof(HubDispatcher).GetMethod("ProcessTaskResult", BindingFlags.NonPublic | BindingFlags.Instance).MakeGenericMethod(resultType); var body = Expression.Call(Expression.Constant(this), processResultMethod, Expression.Constant(state), Expression.Constant(hubRequest), taskParameter); var lambda = Expression.Lambda(body, taskParameter); var call = Expression.Call(Expression.Constant(task, continueWith.Type), continueWith.Method, lambda); Func <Task <Task> > continueWithMethod = Expression.Lambda <Func <Task <Task> > >(call).Compile(); return(continueWithMethod.Invoke().FastUnwrap()); } } else { resultTask = ProcessResult(state, result, hubRequest, null); } } catch (TargetInvocationException e) { resultTask = ProcessResult(state, null, hubRequest, e); } return(resultTask .ContinueWith(_ => base.OnReceivedAsync(connectionId, data)) .FastUnwrap()); }
public ClientsProxy(ClientAgent clientAgent) { _clientAgent = clientAgent; }