private async Task HandleGroupMessage(MsmqMessage m)
        {
            try
            {
                var groupMessage = this.protocol.ReadGroupCommand(m.Body);

                var connection = this.connections[groupMessage.ConnectionId];
                if (connection == null)
                {
                    // user not on this server
                    return;
                }

                if (groupMessage.Action == GroupAction.Remove)
                {
                    await this.RemoveGroupAsyncCore(connection, groupMessage.GroupName);
                }

                if (groupMessage.Action == GroupAction.Add)
                {
                    await this.AddGroupAsyncCore(connection, groupMessage.GroupName);
                }

                // Send an ack to the server that sent the original command.
                var ack = this.protocol.WriteAck(groupMessage.Id);
                await this.msmqBus.PublishAsync(this.queues.GroupManagement(groupMessage.ServerName), ack);
            }
            catch (Exception ex)
            {
                MsmqLog.InternalMessageFailed(this.logger, ex);
            }
        }
        private async Task EnsureMsmqServerConnection()
        {
            if (this.msmqChannel == null)
            {
                await this.connectionLock.WaitAsync();

                try
                {
                    if (this.msmqChannel == null)
                    {
                        this.msmqChannel = await this.msmqBus.SubscribeAsync(this.queues.Invocations(Environment.MachineName));

                        MsmqLog.Connected(this.logger);
                        this.msmqChannel.OnMessage(this.HandleRegularMessage);

                        var msmqGroupChannel = await this.msmqBus.SubscribeAsync(this.queues.GroupManagement(Environment.MachineName));

                        msmqGroupChannel.OnMessage(this.HandleGroupMessage);

                        var msmqAckChannel = await this.msmqBus.SubscribeAsync(this.queues.Ack(Environment.MachineName));

                        msmqAckChannel.OnMessage(this.HandleAckMessage);
                    }
                }
                catch (Exception e)
                {
                    MsmqLog.ConnectionFailed(this.logger, e);
                }
                finally
                {
                    this.connectionLock.Release();
                }
            }
        }
        private async Task HandleRegularMessage(MsmqMessage m)
        {
            try
            {
                MsmqLog.ReceivedFromChannel(this.logger, m.ChannelName);

                var invocation = this.protocol.ReadInvocation(m.Body);

                var tasks = new List <Task>(this.connections.Count);

                foreach (var connection in this.connections)
                {
                    if (invocation.ExcludedConnectionIds == null || !invocation.ExcludedConnectionIds.Contains(connection.ConnectionId))
                    {
                        tasks.Add(connection.WriteAsync(invocation.Message).AsTask());
                    }
                }

                await Task.WhenAll(tasks);
            }
            catch (Exception ex)
            {
                MsmqLog.FailedWritingMessage(this.logger, ex);
            }
        }
 private Task RemoveUserAsync(HubConnectionContext connection)
 {
     return(this.users.RemoveSubscriptionAsync(connection.UserIdentifier, connection, channelName =>
     {
         MsmqLog.Unsubscribe(this.logger, "user:" + connection.UserIdentifier);
         return Task.CompletedTask;
     }));
 }
 /// <summary>
 /// This takes <see cref="HubConnectionContext"/> because we want to remove the connection from the
 /// _connections list in OnDisconnectedAsync and still be able to remove groups with this method.
 /// </summary>
 private async Task RemoveGroupAsyncCore(HubConnectionContext connection, string groupName)
 {
     await this.groups.RemoveSubscriptionAsync(groupName, connection, channelName =>
     {
         MsmqLog.Unsubscribe(this.logger, channelName);
         return(Task.CompletedTask);
     });
 }
        private async Task PublishGroupCommandAsync(byte[] payload)
        {
            var channels = await this.msmqBus.GetAllQueueNamesAsync();

            foreach (var channel in channels.Where(x => x.StartsWith(this.queues.GroupManagement(string.Empty))))
            {
                MsmqLog.PublishToChannel(this.logger, channel);
                await this.msmqBus.PublishAsync(channel, payload);
            }
        }
        private async Task PublishAsync(byte[] payload)
        {
            await this.EnsureMsmqServerConnection();

            var channels = await this.msmqBus.GetAllQueueNamesAsync();

            foreach (var channel in channels.Where(x => x.StartsWith(this.queues.Invocations(string.Empty))))
            {
                MsmqLog.PublishToChannel(this.logger, channel);
                await this.msmqBus.PublishAsync(channel, payload);
            }
        }
        private Task HandleAckMessage(MsmqMessage m)
        {
            try
            {
                var ackId = this.protocol.ReadAck(m.Body);
                this.ackHandler.TriggerAck(ackId);
            }
            catch (Exception ex)
            {
                MsmqLog.InternalMessageFailed(this.logger, ex);
            }

            return(Task.CompletedTask);
        }
        public MsmqHubLifetimeManager(
            ILogger <MsmqHubLifetimeManager <THub> > logger,
            IOptions <MsmqOptions> options,
            IHubProtocolResolver hubProtocolResolver,
            IMsmqBus msmqBus)
        {
            this.logger     = logger;
            this.options    = options.Value;
            this.protocol   = new MsmqProtocol(hubProtocolResolver.AllProtocols);
            this.msmqBus    = msmqBus;
            this.queues     = new MsmqQueues(this.options.ApplicationName);
            this.ackHandler = new AckHandler();

            MsmqLog.ConnectingToEndpoints(this.logger, this.options.ConnectionString, this.options.ApplicationName);
            _ = this.EnsureMsmqServerConnection();
        }
Exemplo n.º 10
0
        public bool CanRecalculate(MsmqLog log, DateTime arrivedTime)
        {
            if (log != null)
            {
                //last recalculation was done
                if (log.EndTime.HasValue)
                {
                    //last arrivedTime is older that recalculation end time so no need of action.
                    if (log.EndTime.Value > arrivedTime)
                    {
                        return(false);
                    }
                }
                //last recalculation was not finished and it is the same or newer that arrived time.
                else if (log.StartTime.HasValue && log.StartTime.Value >= arrivedTime)
                {
                    return(false);
                }
            }

            return(true);
        }