public NotificationSubscriber(RedisSubscriber redisSubscriber, string connectionId, string userId)
 {
     _redisSubscriber = redisSubscriber;
     ConnectionId     = connectionId;
     UserId           = userId;
 }
Beispiel #2
0
        public void Subscribe(string connectionId, string userId)
        {
            string channelName   = this._keyBuilder.BuildChannelName(userId);
            string subscriberKey = this._keyBuilder.BuildSubscriberKey(connectionId, userId);

            RedisSubscriber        redisSub = _redisManager.GetSubscriber(channelName);
            NotificationSubscriber hubSub   = new NotificationSubscriber(redisSub, connectionId, userId);

            if (HubSubscribers.TryAdd(subscriberKey, hubSub))
            {
                hubSub.OnMessage(async message =>
                {
                    // check exchange message integrity
                    if (message.Properties?.ContainsKey("RouteName") != true)
                    {
                        throw new Exception("The exchange message does not contain a route name property");
                    }

                    string routeName = message.Properties["RouteName"];

                    // check registered routes
                    NotificationRouteDescriptor route = this._routes.GetRoute(routeName);

                    if (route is null)
                    {
                        throw new Exception($"Could not find route with name {route.RouteName}. Each message must contain a route name that will redirect the message handling to the proper controller");
                    }

                    MethodInfo methodInfo = this._controllerRegistry.GetMethodInfoForRoute(route.RouteName);

                    if (methodInfo is null)
                    {
                        throw new Exception("Could not found a controller that contains a method decorated with " +
                                            $"{nameof(NotificationRouteAttribute)} to handle the received message");
                    }

                    // create controller
                    object controllerObject  = ActivatorUtilities.CreateInstance(this._serviceProvider, methodInfo.ReflectedType);
                    FieldInfo subscriberInfo = FindField(methodInfo.ReflectedType, "_subscriber");

                    if (subscriberInfo is null)
                    {
                        throw new ApplicationException("Could not find _subscriber field in the redis controller base class");
                    }

                    // initialize controller properties
                    subscriberInfo.SetValue(controllerObject, hubSub);

                    // deserialize exchange model inner model
                    object model = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(message.Body), route.ModelType);

                    // invoke controller method
                    object result = methodInfo.Invoke(controllerObject, new object[] { model });

                    if (typeof(Task).IsAssignableFrom(result.GetType()))
                    {
                        Task taskResult = result as Task;
                        await taskResult;
                    }
                });
                //this.OnNewSubscriber(hubSub);
            }
        }