private void UpdateDb(SendMessageQueue sendMessageQueue, SEND_SMS_RESULT sendMessageResult) { // 寫入對應的 SendMessageResult var every8d_SendMessageResult = new Every8d_SendMessageResult(); every8d_SendMessageResult.SourceTable = SourceTable.SendMessageQueue; every8d_SendMessageResult.SourceTableId = sendMessageQueue.Id; every8d_SendMessageResult.SendTime = sendMessageQueue.SendTime; every8d_SendMessageResult.Subject = sendMessageQueue.SendTitle; every8d_SendMessageResult.Content = sendMessageQueue.SendBody; every8d_SendMessageResult.CreatedTime = DateTime.UtcNow; every8d_SendMessageResult.CREDIT = sendMessageResult.CREDIT; every8d_SendMessageResult.SENDED = sendMessageResult.SENDED; every8d_SendMessageResult.COST = sendMessageResult.COST; every8d_SendMessageResult.UNSEND = sendMessageResult.UNSEND; every8d_SendMessageResult.BATCH_ID = sendMessageResult.BATCH_ID; every8d_SendMessageResult = this.unitOfWork.Repository <Every8d_SendMessageResult>().Insert(every8d_SendMessageResult); // Every8d 在此階段無法取得寫入 SendMessageHistory,無對應資料結構 // CreateSendMessageHistory(sendMessageQueue.Id); // 在 Thread 中等待 30 秒,再寫入 DeliveryReportQueue var delayMilliseconds = (int)30 * 1000; FaFTaskFactory.StartNew(delayMilliseconds, () => { using (var context = new ApplicationDbContext()) { var _unitOfWork = new UnitOfWork(context); var _repository = _unitOfWork.Repository <DeliveryReportQueue>(); // 寫入簡訊派送結果等待取回序列 var deliveryReportQueue = new DeliveryReportQueue(); deliveryReportQueue.SourceTableId = sendMessageQueue.Id; deliveryReportQueue.SourceTable = SourceTable.SendMessageQueue; deliveryReportQueue.RequestId = every8d_SendMessageResult.BATCH_ID; deliveryReportQueue.ProviderName = this.Name; deliveryReportQueue.CreatedTime = DateTime.UtcNow; deliveryReportQueue.SendMessageResultItemCount = every8d_SendMessageResult.SENDED.HasValue ? every8d_SendMessageResult.SENDED.Value : 0; deliveryReportQueue.DeliveryReportCount = 0; deliveryReportQueue = _repository.Insert(deliveryReportQueue); } }); }
public void RetrySMS() { try { var sendMessageHistoryRepository = this.unitOfWork.Repository <SendMessageHistory>(); var predicate = PredicateBuilder.True <SendMessageHistory>(); // 發送失敗 predicate = predicate.And(p => p.Delivered == false && p.DeliveryStatus != DeliveryReportStatus.MessageAccepted && p.DeliveryStatus != DeliveryReportStatus.DeliveredToTerminal); // 未超過最大重送次數 predicate = predicate.And(p => p.RetryMaxTimes > p.RetryTotalTimes); var innerPredicate = PredicateBuilder.False <SendMessageHistory>(); // 尚未重送過 innerPredicate = innerPredicate.Or(p => p.SendMessageRetryHistory == null); // 最後一次重送,仍然發送失敗 innerPredicate = innerPredicate.Or(p => p.SendMessageRetryHistory != null && p.SendMessageRetryHistory.Delivered == false && p.DeliveryStatus != DeliveryReportStatus.MessageAccepted && p.DeliveryStatus != DeliveryReportStatus.DeliveredToTerminal); predicate = predicate.And(innerPredicate); var sendMessageHistorys = sendMessageHistoryRepository.GetAll().AsExpandable().Where(predicate); foreach (var sendMessageHistory in sendMessageHistorys) { FaFTaskFactory.StartNew(() => { BackgroundJob.Enqueue <CommonSmsService>(x => x.RetrySMS(sendMessageHistory.Id)); }); } } catch (Exception ex) { this.logService.Error(ex); throw; } }
public void SendSMS() { try { // 對於預約發送簡訊,須滿足以下條件才會發送簡訊 // (1) SendMessageRuleStatus == SendMessageRuleStatus.Ready // (2) 預計發送時間必須小於等於目前時間 // (3) 在 SendMessageQueue 沒有對應資料 (根據 SendMessageRuleId) // 對於週期發送簡訊,須滿足以下條件才會發送簡訊 // (1) SendMessageRuleStatus == SendMessageRuleStatus.Ready // (2) 預計發送時間必須小於等於目前時間 // (3) 在 SendMessageQueue 最大一筆(ORDER BY SendTime DESC) 對應資料的發送時間,比預計發送時間小 var rules = this.unitOfWork.Repository <SendMessageRule>().GetMany(p => p.SendMessageRuleStatus == SendMessageRuleStatus.Ready && (p.SendTimeType == SendTimeType.Deliver || p.SendTimeType == SendTimeType.Cycle)).ToList(); var sendMessageQueueRepository = this.unitOfWork.Repository <SendMessageQueue>(); DateTime utcNow = DateTime.UtcNow; if (!rules.Any()) { //this.logService.Debug("無任何待發送預約簡訊或週期簡訊"); return; } this.logService.Debug("待發送簡訊(預約簡訊:{0} 個,週期簡訊:{1} 個)" , rules.Where(p => p.SendTimeType == SendTimeType.Deliver).Count() , rules.Where(p => p.SendTimeType == SendTimeType.Cycle).Count() ); foreach (var rule in rules) { // 預約發送的發送時間,不會是 null // 週期發送的發送時間,如果為 null,表示找不到比目前時間小的發送時間 DateTime?nullableTime = rule.GetSendTime(); if (nullableTime.HasValue == false) { continue; } DateTime sendTime = nullableTime.Value; // (2) 預計發送時間必須小於等於目前時間,因此不滿足此條件就忽略 //if (sendTime > utcNow) continue; // (2) 預計發送時間必須小於等於(目前時間 + 簡訊準備時間),因此不滿足此條件就忽略 if (sendTime > utcNow + SmsPreparationTimeSpan) { continue; } //BackgroundJob.Enqueue<CommonSmsService>(x => x.SendSMS(rule.Id, sendTime)); var delayTimeSpan = (sendTime - utcNow) - SmsLatencyTimeSpan; var delayMilliseconds = (int)delayTimeSpan.TotalMilliseconds; FaFTaskFactory.StartNew(delayMilliseconds, () => { BackgroundJob.Enqueue <CommonSmsService>(x => x.SendSMS(rule.Id, sendTime)); }); } } catch (Exception ex) { this.logService.Error(ex); throw; } }
private void UpdateDb_RetrySMS(SendMessageHistory sendMessageHistory, SendMessageResult sendMessageResult) { // 寫入對應的 SendMessageResult var infobip_SendMessageResult = new Infobip_SendMessageResult(); infobip_SendMessageResult.SourceTable = SourceTable.SendMessageHistory; infobip_SendMessageResult.SourceTableId = sendMessageHistory.Id; infobip_SendMessageResult.ClientCorrelator = sendMessageResult.ClientCorrelator; infobip_SendMessageResult.CreatedTime = DateTime.UtcNow; // 接收發送命令回傳值的時間 infobip_SendMessageResult.Balance = this.Balance; infobip_SendMessageResult = this.unitOfWork.Repository <Infobip_SendMessageResult>().Insert(infobip_SendMessageResult); var sendMessageResultItemRepository = this.unitOfWork.Repository <Infobip_SendMessageResultItem>(); for (var i = 0; i < sendMessageResult.SendMessageResults.Length; i++) { // 一個 messageReceiver 對應一個 sendMessageResult // 尚未驗證,是否我傳送的 destinations 順序與 SendMessageResults 順序一致 // 【目前假設是一致的】 var sendMessageResultItem = sendMessageResult.SendMessageResults[i]; // 20160715 Norman, 改成以下方式,用以解決以下問題 // The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Infobip_DeliveryReport_dbo.Infobip_SendMessageResultItem_MessageId". The conflict occurred in database "EFunTechSms", table "dbo.Infobip_SendMessageResultItem", column 'MessageId'. var infobip_SendMessageResultItem = sendMessageResultItemRepository.Get(p => p.MessageId == sendMessageResultItem.MessageId); if (infobip_SendMessageResultItem == null) { // insert infobip_SendMessageResultItem = new Infobip_SendMessageResultItem(); infobip_SendMessageResultItem.MessageId = sendMessageResultItem.MessageId; infobip_SendMessageResultItem.MessageStatusString = sendMessageResultItem.MessageStatus; EFunTech.Sms.Schema.MessageStatus MessageStatus = EFunTech.Sms.Schema.MessageStatus.Unknown; Enum.TryParse <EFunTech.Sms.Schema.MessageStatus>(sendMessageResultItem.MessageStatus, out MessageStatus); infobip_SendMessageResultItem.MessageStatus = MessageStatus; infobip_SendMessageResultItem.SenderAddress = sendMessageResultItem.SenderAddress; infobip_SendMessageResultItem.DestinationAddress = sendMessageResultItem.DestinationAddress; infobip_SendMessageResultItem.SendMessageResult = infobip_SendMessageResult; infobip_SendMessageResultItem.DestinationName = sendMessageHistory.DestinationName; infobip_SendMessageResultItem.Email = sendMessageHistory.Email; infobip_SendMessageResultItem = sendMessageResultItemRepository.Insert(infobip_SendMessageResultItem); } else { // update //infobip_SendMessageResultItem.MessageId = sendMessageResultItem.MessageId; // update 不需要這個欄位 infobip_SendMessageResultItem.MessageStatusString = sendMessageResultItem.MessageStatus; EFunTech.Sms.Schema.MessageStatus MessageStatus = EFunTech.Sms.Schema.MessageStatus.Unknown; Enum.TryParse <EFunTech.Sms.Schema.MessageStatus>(sendMessageResultItem.MessageStatus, out MessageStatus); infobip_SendMessageResultItem.MessageStatus = MessageStatus; infobip_SendMessageResultItem.SenderAddress = sendMessageResultItem.SenderAddress; infobip_SendMessageResultItem.DestinationAddress = sendMessageResultItem.DestinationAddress; infobip_SendMessageResultItem.SendMessageResult = infobip_SendMessageResult; infobip_SendMessageResultItem.DestinationName = sendMessageHistory.DestinationName; infobip_SendMessageResultItem.Email = sendMessageHistory.Email; sendMessageResultItemRepository.Update(infobip_SendMessageResultItem); } } var infobip_ResourceReference = new Infobip_ResourceReference(); infobip_ResourceReference.SendMessageResultId = infobip_SendMessageResult.Id; infobip_ResourceReference.ResourceURL = sendMessageResult.ResourceRef.ResourceURL; infobip_ResourceReference = this.unitOfWork.Repository <Infobip_ResourceReference>().Insert(infobip_ResourceReference); CreateSendMessageRetryHistory(sendMessageHistory); // 在 Thread 中等待 30 秒,再寫入 DeliveryReportQueue var delayMilliseconds = (int)30 * 1000; FaFTaskFactory.StartNew(delayMilliseconds, () => { using (var context = new ApplicationDbContext()) { var _unitOfWork = new UnitOfWork(context); var _repository = _unitOfWork.Repository <DeliveryReportQueue>(); // 寫入簡訊派送結果等待取回序列 var deliveryReportQueue = new DeliveryReportQueue(); deliveryReportQueue.SourceTableId = sendMessageHistory.Id; deliveryReportQueue.SourceTable = SourceTable.SendMessageHistory; deliveryReportQueue.RequestId = infobip_SendMessageResult.ClientCorrelator; deliveryReportQueue.ProviderName = this.Name; deliveryReportQueue.CreatedTime = DateTime.UtcNow; deliveryReportQueue.SendMessageResultItemCount = infobip_SendMessageResult.SendMessageResults.Count; deliveryReportQueue.DeliveryReportCount = 0; deliveryReportQueue = _repository.Insert(deliveryReportQueue); } }); }