Example #1
0
        private static bool SendDirect(BaseMessage message, int delaySend = 0)
        {
            if (string.IsNullOrWhiteSpace(message.Source))
            {
                throw new ArgumentNullException("message.Source");
            }

            if (!PrePersistMessage(message))
            {
                return(false);
            }

            var messageType = message.GetType();

            delaySend = delaySend == 0 ? delaySend : Math.Max(delaySend, 1000); // 至少保证1秒的延迟,否则意义不大
            using (var pooled = InnerCreateChannel(messageType))
            {
                IModel channel = pooled.Channel;
                pooled.PreRecord(message.MsgHash);

                var exchange  = string.Empty;
                var route_key = string.Empty;
                var queue     = string.Empty;
                EnsureQueue(channel, messageType, out exchange, out route_key, out queue, delaySend);

                var json  = JsonConvert.SerializeObject(message);
                var bytes = Encoding.UTF8.GetBytes(json);
                var props = channel.CreateBasicProperties();
                props.ContentType  = "text/plain";
                props.DeliveryMode = 2;
                channel.BasicPublish(exchange, route_key, props, bytes);
                var time_out = Math.Max(default_retry_wait, message.RetryCount_Publish * 2 /*2倍往上扩大,防止出现均等*/ * 1000);
                var ret      = channel.WaitForConfirms(TimeSpan.FromMilliseconds(time_out));
                if (!ret)
                {
                    // 数据库更新该条消息的状态信息
                    if (message.RetryCount_Publish < default_retry_count)
                    {
                        var ok = _message_queue_helper.Update(
                            message.MsgHash,
                            fromStatus1: MsgStatus.Created, // 之前的状态只能是1 Created 或者2 Retry
                            fromStatus2: MsgStatus.Retrying,
                            toStatus: MsgStatus.Retrying);
                        if (ok)
                        {
                            message.RetryCount_Publish += 1;
                            message.LastRetryTime       = DateTime.Now;
                            direct_queue.Enqueue(message);
                            return(true);
                        }
                        throw new Exception("数据库update出现异常");
                    }
                    throw new Exception($"消息发送超过最大重试次数({default_retry_count}次)");
                }
            }

            return(true);
        }
        // broker正常接受到消息,会触发该ack事件
        private void Channel_BasicAcks(object sender, BasicAckEventArgs e)
        {
            // 数据更新该条消息的状态信息
            long msgHash = 0;

            if (_unconfirm.TryGetValue(e.DeliveryTag, out msgHash))
            {
                var ok = _message_queue_helper.Update(
                    msgHash,
                    fromStatus1: MsgStatus.Created, // 之前的状态只能是1 Created 或者2 Retry
                    fromStatus2: MsgStatus.Retrying,
                    toStatus: MsgStatus.ArrivedBroker);
                if (ok)
                {
                    _unconfirm.Remove(e.DeliveryTag);
                }
                else
                {
                    throw new Exception("数据库update出现异常");
                }
            }
        }