From 5366b2909d4a70022147f8320b2a61e0eff471ae Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Thu, 18 Jun 2020 14:06:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E9=80=9A=E7=9F=A5=E5=8A=9F?= =?UTF-8?q?=E8=83=BD,=E5=A2=9E=E5=8A=A0=E9=80=9A=E7=9F=A5=E7=94=9F?= =?UTF-8?q?=E5=91=BD=E5=91=A8=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SignalRNotificationPublishProvider.cs | 6 ++- .../WeApp/WeChatWeAppNotificationSender.cs | 18 ++++++++- .../Notifications/INotificationDispatcher.cs | 8 ---- .../Internal/DefaultNotificationDispatcher.cs | 37 +++++-------------- .../Notifications/NotificationDefinition.cs | 6 +++ .../Notifications/NotificationEventData.cs | 2 + .../Abp/Notifications/NotificationInfo.cs | 3 ++ .../Abp/Notifications/NotificationLifetime.cs | 18 +++++++++ ...geServiceNotificationDefinitionProvider.cs | 4 ++ .../Notifications/NotificationStore.cs | 5 +-- .../Subscriptions/IUserSubscribeRepository.cs | 2 + .../EfCoreUserSubscribeRepository.cs | 6 +++ .../Distributed/NotificationEventHandler.cs | 7 ++++ .../MessageServiceDefinitionProvider.cs | 7 ++-- 14 files changed, 83 insertions(+), 46 deletions(-) create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationLifetime.cs diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs index 02c9a216c..04afc41a8 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; namespace LINGYUN.Abp.Notifications.SignalR @@ -31,22 +32,23 @@ namespace LINGYUN.Abp.Notifications.SignalR { // 返回标准数据给前端 notification.Data = NotificationData.ToStandardData(notification.Data); - foreach (var identifier in identifiers) { + Logger.LogDebug($"Find online client with user {identifier.UserId} - {identifier.UserName}"); var onlineClientContext = new OnlineClientContext(notification.TenantId, identifier.UserId); var onlineClients = _onlineClientManager.GetAllByContext(onlineClientContext); foreach (var onlineClient in onlineClients) { try { + Logger.LogDebug($"Find online client {onlineClient.UserId} - {onlineClient.ConnectionId}"); var signalRClient = _hubContext.Clients.Client(onlineClient.ConnectionId); if (signalRClient == null) { Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!"); continue; } - + Logger.LogDebug($"Found a singalr client, begin senging notifications"); await signalRClient.SendAsync("getNotification", notification); } catch (Exception ex) diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs index 701c11573..44ecac7db 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs @@ -1,4 +1,6 @@ using LINGYUN.Abp.WeChat.Authorization; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Newtonsoft.Json; using System.Collections.Generic; using System.Net.Http; @@ -13,6 +15,7 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp public class WeChatWeAppNotificationSender : IWeChatWeAppNotificationSender, ITransientDependency { public const string SendNotificationClientName = "WeChatWeAppSendNotificationClient"; + public ILogger Logger { get; set; } protected IHttpClientFactory HttpClientFactory { get; } protected IJsonSerializer JsonSerializer { get; } protected IWeChatTokenProvider WeChatTokenProvider { get; } @@ -24,6 +27,8 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp JsonSerializer = jsonSerializer; HttpClientFactory = httpClientFactory; WeChatTokenProvider = weChatTokenProvider; + + Logger = NullLogger.Instance; } public virtual async Task SendAsync(WeChatWeAppSendNotificationData notificationData) @@ -38,7 +43,14 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp var requestUrl = BuildRequestUrl(weChatSendNotificationUrl, weChatSendNotificationPath, requestParamters); var responseContent = await MakeRequestAndGetResultAsync(requestUrl, notificationData); var weChatSenNotificationResponse = JsonSerializer.Deserialize(responseContent); - weChatSenNotificationResponse.ThrowIfNotSuccess(); + + if (!weChatSenNotificationResponse.IsSuccessed) + { + Logger.LogWarning("Send wechat we app subscribe message failed"); + Logger.LogWarning($"Error code: {weChatSenNotificationResponse.ErrorCode}, message: {weChatSenNotificationResponse.ErrorMessage}"); + } + // 失败是否抛出异常 + // weChatSenNotificationResponse.ThrowIfNotSuccess(); } protected virtual async Task MakeRequestAndGetResultAsync(string url, WeChatWeAppSendNotificationData notificationData) { @@ -53,7 +65,7 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp var response = await client.SendAsync(requestMessage); if (!response.IsSuccessStatusCode) { - throw new AbpException($"Baidu http request service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}"); + throw new AbpException($"WeChat send subscribe message http request service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}"); } var resultContent = await response.Content.ReadAsStringAsync(); @@ -83,6 +95,8 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp [JsonProperty("errmsg")] public string ErrorMessage { get; set; } + public bool IsSuccessed => ErrorCode == 0; + public void ThrowIfNotSuccess() { if (ErrorCode != 0) diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs index 708d24f58..cc450bb9f 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs @@ -8,14 +8,6 @@ namespace LINGYUN.Abp.Notifications /// public interface INotificationDispatcher { - /// - /// 发送通知 - /// - /// - /// - [Obsolete("Api已过时,请调用 DispatcheAsync(string notificationName, NotificationData data, Guid? tenantId = null)")] - Task DispatchAsync(NotificationInfo notification); - /// /// 发送通知 /// diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs index f081278cf..b4802b2bd 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs @@ -84,6 +84,7 @@ namespace LINGYUN.Abp.Notifications.Internal Name = notificationName.Name, CreationTime = DateTime.Now, NotificationSeverity = notificationSeverity, + Lifetime = defineNotification.NotificationLifetime, NotificationType = defineNotification.NotificationType, TenantId = tenantId, Data = data @@ -98,6 +99,13 @@ namespace LINGYUN.Abp.Notifications.Internal } await PublishFromProvidersAsync(providers, notificationInfo); + + if (notificationInfo.Lifetime == NotificationLifetime.OnlyOne) + { + // 一次性通知在发送完成后就取消用户订阅 + await _notificationStore.DeleteAllUserSubscriptionAsync(notificationInfo.TenantId, + notificationInfo.Name); + } } /// /// 发送通知事件 @@ -119,6 +127,7 @@ namespace LINGYUN.Abp.Notifications.Internal Name = notificationName.Name, CreationTime = DateTime.Now, NotificationSeverity = notificationSeverity, + Lifetime = defineNotification.NotificationLifetime, NotificationType = defineNotification.NotificationType, TenantId = tenantId, Data = data @@ -126,34 +135,6 @@ namespace LINGYUN.Abp.Notifications.Internal // 发布分布式通知事件,让消息中心统一处理 await DistributedEventBus.PublishAsync(notificationEventData); } - /// - /// 发送通知 - /// - /// 通知信息 - /// - public virtual async Task DispatchAsync(NotificationInfo notification) - { - // 获取自定义的通知 - var defineNotification = _notificationDefinitionManager.GetOrNull(notification.Name); - - // 没有定义的通知,应该也要能发布、订阅, - // 比如订单之类的,是以订单编号为通知名称,这是动态的,没法自定义 - if (defineNotification == null) - { - defineNotification = new NotificationDefinition(notification.Name); - } - - var providers = Enumerable - .Reverse(_notificationPublishProviderManager.Providers); - - if (defineNotification.Providers.Any()) - { - providers = providers.Where(p => defineNotification.Providers.Contains(p.Name)); - } - - await PublishFromProvidersAsync(providers, notification); - } - /// /// 指定提供者发布通知 /// diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs index d43ec8ec0..f585fbafb 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs @@ -40,6 +40,10 @@ namespace LINGYUN.Abp.Notifications /// public bool AllowSubscriptionToClients { get; set; } /// + /// 存活类型 + /// + public NotificationLifetime NotificationLifetime { get; set; } + /// /// 通知类型 /// public NotificationType NotificationType { get; set; } @@ -53,11 +57,13 @@ namespace LINGYUN.Abp.Notifications ILocalizableString displayName = null, ILocalizableString description = null, NotificationType notificationType = NotificationType.Application, + NotificationLifetime lifetime = NotificationLifetime.Persistent, bool allowSubscriptionToClients = false) { CateGory = category; DisplayName = displayName ?? new FixedLocalizableString(category); Description = description; + NotificationLifetime = lifetime; NotificationType = notificationType; AllowSubscriptionToClients = allowSubscriptionToClients; diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationEventData.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationEventData.cs index 1859937aa..6eebfcd41 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationEventData.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationEventData.cs @@ -10,6 +10,7 @@ namespace LINGYUN.Abp.Notifications public string Id { get; set; } public NotificationData Data { get; set; } public DateTime CreationTime { get; set; } + public NotificationLifetime Lifetime { get; set; } public NotificationType NotificationType { get; set; } public NotificationSeverity NotificationSeverity { get; set; } @@ -29,6 +30,7 @@ namespace LINGYUN.Abp.Notifications Name = Name, CateGory = CateGory, NotificationType = NotificationType, + Lifetime = Lifetime, TenantId = TenantId }; } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs index ebb3c325a..8b5745359 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs @@ -10,11 +10,13 @@ namespace LINGYUN.Abp.Notifications public string Id { get; set; } public NotificationData Data { get; set; } public DateTime CreationTime { get; set; } + public NotificationLifetime Lifetime { get; set; } public NotificationType NotificationType { get; set; } public NotificationSeverity NotificationSeverity { get; set; } public NotificationInfo() { Data = new NotificationData(); + Lifetime = NotificationLifetime.Persistent; NotificationType = NotificationType.Application; NotificationSeverity = NotificationSeverity.Info; @@ -47,6 +49,7 @@ namespace LINGYUN.Abp.Notifications Id = Id, Name = Name, CateGory = CateGory, + Lifetime = Lifetime, NotificationType = NotificationType, TenantId = TenantId }; diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationLifetime.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationLifetime.cs new file mode 100644 index 000000000..6127ca0f1 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationLifetime.cs @@ -0,0 +1,18 @@ +namespace LINGYUN.Abp.Notifications +{ + /// + /// 通知存活时间 + /// 发送之后取消用户订阅,类似于微信小程序 + /// + public enum NotificationLifetime + { + /// + /// 持久化 + /// + Persistent = 0, + /// + /// 一次性 + /// + OnlyOne = 1 + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/AbpMessageServiceNotificationDefinitionProvider.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/AbpMessageServiceNotificationDefinitionProvider.cs index 4b7098ed6..493cf83d0 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/AbpMessageServiceNotificationDefinitionProvider.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/AbpMessageServiceNotificationDefinitionProvider.cs @@ -14,11 +14,15 @@ namespace LINGYUN.Abp.MessageService.Notifications UserNotificationNames.WelcomeToApplication, L("WelcomeToApplicationNotification"), L("WelcomeToApplicationNotification"), + notificationType: NotificationType.System, + lifetime: NotificationLifetime.OnlyOne, allowSubscriptionToClients: true)); context.Add(new NotificationDefinition( TenantNotificationNames.NewTenantRegistered, L("NewTenantRegisterdNotification"), L("NewTenantRegisterdNotification"), + notificationType: NotificationType.System, + lifetime: NotificationLifetime.OnlyOne, allowSubscriptionToClients: true)); } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs index a7b5a5bef..ae4002684 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs @@ -95,9 +95,7 @@ namespace LINGYUN.Abp.MessageService.Notifications using (var unitOfWork = _unitOfWorkManager.Begin()) using (CurrentTenant.Change(tenantId)) { - var userSubscribes = await UserSubscribeRepository.GetSubscribesAsync(notificationName); - - await UserSubscribeRepository.DeleteUserSubscriptionAsync(userSubscribes); + await UserSubscribeRepository.DeleteUserSubscriptionAsync(notificationName); await unitOfWork.SaveChangesAsync(); } @@ -122,6 +120,7 @@ namespace LINGYUN.Abp.MessageService.Notifications using (var unitOfWork = _unitOfWorkManager.Begin()) using (CurrentTenant.Change(tenantId)) { + // TODO:不追踪用户订阅实体? var userSubscribes = await UserSubscribeRepository.GetSubscribesAsync(notificationName); var removeUserSubscribes = userSubscribes.Where(us => identifiers.Any(id => id.UserId.Equals(us.UserId))); diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Subscriptions/IUserSubscribeRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Subscriptions/IUserSubscribeRepository.cs index 090e738a3..3b3915751 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Subscriptions/IUserSubscribeRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Subscriptions/IUserSubscribeRepository.cs @@ -22,5 +22,7 @@ namespace LINGYUN.Abp.MessageService.Subscriptions Task InsertUserSubscriptionAsync(IEnumerable userSubscribes); Task DeleteUserSubscriptionAsync(IEnumerable userSubscribes); + + Task DeleteUserSubscriptionAsync(string notificationName); } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Subscriptions/EfCoreUserSubscribeRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Subscriptions/EfCoreUserSubscribeRepository.cs index 621be16b3..7d2178527 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Subscriptions/EfCoreUserSubscribeRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Subscriptions/EfCoreUserSubscribeRepository.cs @@ -78,6 +78,12 @@ namespace LINGYUN.Abp.MessageService.Subscriptions await DbSet.AddRangeAsync(userSubscribes); } + public async Task DeleteUserSubscriptionAsync(string notificationName) + { + var userSubscribes = await DbSet.Where(x => x.NotificationName.Equals(notificationName)).ToListAsync(); + DbSet.RemoveRange(userSubscribes); + } + public Task DeleteUserSubscriptionAsync(IEnumerable userSubscribes) { DbSet.RemoveRange(userSubscribes); diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs index b099fd697..a8623dea1 100644 --- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs @@ -96,6 +96,13 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed { await PublishAsync(provider, notificationInfo, subscriptionUserIdentifiers); } + + if (notificationInfo.Lifetime == NotificationLifetime.OnlyOne) + { + // 一次性通知在发送完成后就取消用户订阅 + await NotificationStore.DeleteAllUserSubscriptionAsync(notificationInfo.TenantId, + notificationInfo.Name); + } } /// /// 发布通知 diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Notifications/MessageServiceDefinitionProvider.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Notifications/MessageServiceDefinitionProvider.cs index 2dcca0a0c..144ee3b3a 100644 --- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Notifications/MessageServiceDefinitionProvider.cs +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Notifications/MessageServiceDefinitionProvider.cs @@ -2,7 +2,7 @@ using LINGYUN.Abp.Notifications; using Volo.Abp.Localization; -namespace LINGYUN.Abp.MessageService.LINGYUN.Abp.MessageService.Notifications +namespace LINGYUN.Abp.MessageService.Notifications { public class MessageServiceDefinitionProvider : NotificationDefinitionProvider { @@ -12,8 +12,9 @@ namespace LINGYUN.Abp.MessageService.LINGYUN.Abp.MessageService.Notifications "TestApplicationNotofication", L("TestApplicationNotofication"), L("TestApplicationNotofication"), - NotificationType.Application, - true)); + notificationType: NotificationType.Application, + lifetime: NotificationLifetime.OnlyOne, + allowSubscriptionToClients: true)); } protected LocalizableString L(string name)