Beispiel #1
0
        /// <summary>
        /// 发送数据。
        /// </summary>
        /// <param name="subject"></param>
        private void PublishSubject(StoredSubject subject)
        {
            var connection = GetConnection();

            using (var channel = connection.CreateModel())
            {
                var bytes = Serialize(subject);

                if (string.IsNullOrEmpty(Setting.ExchangeType))
                {
                    channel.QueueDeclare(subject.Name, true, false, false, null);

                    var properties = channel.CreateBasicProperties();
                    properties.Persistent   = true;
                    properties.DeliveryMode = 2;

                    channel.BasicPublish(string.Empty, subject.Name, properties, bytes);
                }
                else
                {
                    var exchangeName = GetExchangeName(subject.Name);
                    channel.ExchangeDeclare(exchangeName, Setting.ExchangeType);
                    channel.BasicPublish(exchangeName, subject.Name, null, bytes);
                }
            }
        }
Beispiel #2
0
        private void RetryPublishData(StoredSubject subject, Exception exception)
        {
            try
            {
                if (subject != null && Setting.RetryTimes > 0 && subject.AcceptRetries < Setting.RetryTimes)
                {
                    if (_notification != null)
                    {
                        var context = new SubscribeNotificationContext(subject.Name, subject.Body, exception);
                        _notification.OnConsumeError(context);
                        if (!context.CanRetry)
                        {
                            return;
                        }
                    }

                    Task.Run(() =>
                    {
                        Thread.Sleep((int)Setting.RetryDelayTime.TotalMilliseconds);
                        try
                        {
                            var client = GetConnection(null);
                            subject.AcceptRetries++;
                            PublishSubject(client, subject);
                        }
                        catch (Exception exp)
                        {
                            PersistSubject(subject, exp);
                        }
                    });
                }
            }
            catch { }
        }
Beispiel #3
0
        /// <summary>
        /// 在 Redis 服务器中添加一个订阅方法。
        /// </summary>
        /// <param name="subjectType">主题的类型。</param>
        /// <param name="subscriber">读取主题的方法。</param>
        public void AddSubscriber(Type subjectType, Delegate subscriber)
        {
            var client = GetConnection();
            var name   = TopicHelper.GetTopicName(subjectType);

            _channels.GetOrAdd(name, () => new List <CSRedisClient.SubscribeObject>())
            .Add(client.Subscribe((name, msg =>
            {
                StoredSubject subject = null;
                try
                {
                    try
                    {
                        subject = Deserialize <StoredSubject>(msg.Body);
                        subscriber.DynamicInvoke(Deserialize(subjectType, subject.Body));
                    }
                    catch (SerializationException)
                    {
                        subscriber.DynamicInvoke(Deserialize(subjectType, msg.Body));
                    }
                }
                catch (Exception exp)
                {
                    Tracer.Error($"Throw exception when consume message of '{name}':\n{exp.Output()}");

                    RetryPublishData(subject, exp);
                }
            }
                                   )));
        }
Beispiel #4
0
        /// <summary>
        /// 在 Redis 服务器中添加一个订阅方法。
        /// </summary>
        /// <typeparam name="TSubject"></typeparam>
        /// <param name="name">主题名称。</param>
        /// <param name="subscriber">读取主题的方法。</param>
        public void AddAsyncSubscriber <TSubject>(string name, Func <TSubject, Task> subscriber) where TSubject : class
        {
            var client = GetConnection(null);

            _channels.GetOrAdd(name, () => new List <CSRedisClient.SubscribeObject>())
            .Add(client.Subscribe((name, msg =>
            {
                StoredSubject subject = null;
                try
                {
                    try
                    {
                        subject = Deserialize <StoredSubject>(msg.Body);
                        subscriber(Deserialize <TSubject>(subject.Body)).AsSync();
                    }
                    catch (SerializationException)
                    {
                        subscriber(Deserialize <TSubject>(msg.Body)).AsSync();
                    }
                }
                catch (Exception exp)
                {
                    Tracer.Error($"Throw exception when consume message of '{name}':\n{exp.Output()}");

                    RetryPublishData(subject, exp);
                }
            }
                                   )));
        }
Beispiel #5
0
        private void PersistSubject(StoredSubject subject, Exception exception)
        {
            if (_persistance != null && subject.PublishRetries == 0)
            {
                if (_notification != null)
                {
                    var context = new SubscribeNotificationContext(subject.Name, subject.Body, exception);
                    _notification.OnPublishError(context);
                    if (!context.CanRetry)
                    {
                        return;
                    }
                }

                if (_persistance.SaveSubject("rabbit", subject))
                {
                    Tracer.Debug($"{_persistance} was persisted of '{subject.Name}'.");
                }
            }
        }
Beispiel #6
0
        private void Publish(string name, byte[] data)
        {
            var pdata = new StoredSubject(name, data);

            try
            {
                PublishSubject(pdata);
            }
            catch (Exception exp)
            {
                if (Setting.RetryTimes > 0)
                {
                    PersistSubject(pdata, exp);
                }
                else
                {
                    throw exp;
                }
            }
        }
Beispiel #7
0
        private async Task PublishAsync(CSRedisClient client, string name, byte[] data)
        {
            var pdata = new StoredSubject(name, data);

            try
            {
                await PublishSubjectAsync(client, pdata);
            }
            catch (Exception exp)
            {
                if (Setting.RetryTimes > 0)
                {
                    PersistSubject(pdata, exp);
                }
                else
                {
                    throw exp;
                }
            }
        }
Beispiel #8
0
        private void RetryPublishData(CustomEventingBasicConsumer consumer, BasicDeliverEventArgs args, StoredSubject subject, Exception exception)
        {
            try
            {
                if (!consumer.Model.IsOpen)
                {
                    return;
                }

                consumer.Model.BasicNack(args.DeliveryTag, false, false);

                if (subject != null && Setting.RetryTimes > 0 && subject.AcceptRetries < Setting.RetryTimes)
                {
                    if (_notification != null)
                    {
                        var context = new SubscribeNotificationContext(subject.Name, subject.Body, exception);
                        _notification.OnConsumeError(context);
                        if (!context.CanRetry)
                        {
                            return;
                        }
                    }

                    Task.Run(() =>
                    {
                        Thread.Sleep((int)Setting.RetryDelayTime.TotalMilliseconds);
                        try
                        {
                            subject.AcceptRetries++;
                            PublishSubject(subject);
                        }
                        catch (Exception exp)
                        {
                            PersistSubject(subject, exp);
                        }
                    });
                }
            }
            catch { }
        }
Beispiel #9
0
        private void ConsumeData(CustomEventingBasicConsumer consumer, BasicDeliverEventArgs args)
        {
            if (!_subscribers.TryGetValue(consumer.ChannelName, out RabbitChannelCollection channels))
            {
                return;
            }

            var found = channels.Find(consumer.Model);

            if (found == null || !consumer.Model.IsOpen)
            {
                return;
            }

            StoredSubject subject = null;

            try
            {
                object body;

                try
                {
                    subject = Deserialize(typeof(StoredSubject), args.Body) as StoredSubject;
                    if (subject == null)
                    {
                        return;
                    }

                    if (found.Handler.DataType == typeof(byte[]))
                    {
                        body = subject.Body;
                    }
                    else
                    {
                        body = Deserialize(found.Handler.DataType, subject.Body);
                    }
                }
                catch (SerializationException)
                {
                    if (found.Handler.DataType == typeof(byte[]))
                    {
                        body = args.Body;
                    }
                    else
                    {
                        body = Deserialize(found.Handler.DataType, args.Body);
                    }
                }

                if (body != null)
                {
                    found.Handler.Invoke(body);
                    consumer.Model.BasicAck(args.DeliveryTag, false);
                }
            }
            catch (Exception exp)
            {
                Tracer.Error($"Throw exception when consume message of '{consumer.ChannelName}':\n{exp.Output()}");

                RetryPublishData(consumer, args, subject, exp);
            }
        }
Beispiel #10
0
 private async Task PublishSubjectAsync(CSRedisClient client, StoredSubject subject)
 {
     await client.PublishAsync(subject.Name, Serialize(subject));
 }
Beispiel #11
0
 private void PublishSubject(CSRedisClient client, StoredSubject subject)
 {
     client.Publish(subject.Name, Serialize(subject));
 }