Browse Source

fix(signalr): signalr序列化协议需要保持一致,移除不必要的客户端管理

pull/437/head
cKey 4 years ago
parent
commit
b6879ddcc0
  1. 1
      .gitignore
  2. 2
      apps/vue/.env
  3. 2
      apps/vue/package.json
  4. 11731
      apps/vue/pnpm-lock.yaml
  5. 2
      apps/vue/src/layouts/default/header/components/notify/useMessages.ts
  6. 2
      apps/vue/src/layouts/default/header/components/notify/useNotifications.ts
  7. 1
      aspnet-core/.gitignore
  8. 48
      aspnet-core/LINGYUN.MicroService.All.sln
  9. 2
      aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Emailing/LINGYUN/Abp/ExceptionHandling/Emailing/AbpEmailingExceptionSubscriber.cs
  10. 2
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN.Abp.IM.SignalR.csproj
  11. 13
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalRModule.cs
  12. 98
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessagesHub.cs
  13. 19
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSenderProvider.cs
  14. 33
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/UserOnlineChecker.cs
  15. 16
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/NullUserOnlineChanger.cs
  16. 16
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/NullUserOnlineChecker.cs
  17. 4
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN.Abp.Notifications.SignalR.csproj
  18. 13
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs
  19. 30
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs
  20. 22
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs
  21. 37
      aspnet-core/modules/common/LINGYUN.Abp.RealTime.SignalR/LINGYUN/Abp/RealTime/SignalR/Hubs/OnlineClientHubBase.cs
  22. 10
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IClient.cs
  23. 28
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IOnlineClient.cs
  24. 30
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IOnlineClientManager.cs
  25. 23
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IOnlineClientStore.cs
  26. 57
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/InMemoryOnlineClientStore.cs
  27. 72
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClient.cs
  28. 17
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClientContext.cs
  29. 14
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClientEventArgs.cs
  30. 15
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClientExtensions.cs
  31. 111
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClientManager.cs
  32. 26
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClientManagerExtensions.cs
  33. 13
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineUserEventArgs.cs
  34. 22
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionPageWrapResultFilter.cs
  35. 20
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionWrapResultFilter.cs
  36. 6
      aspnet-core/modules/open-api/LINGYUN.Abp.OpenApi.Authorization/LINGYUN/Abp/OpenApi/Authorization/OpenApiAuthorizationService.cs
  37. 1
      aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/LY.MicroService.RealtimeMessage.HttpApi.Host.csproj
  38. 2
      aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Properties/launchSettings.json
  39. 16
      aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.Configure.cs
  40. 4
      aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.cs
  41. 2
      gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/.gitignore
  42. 2
      gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.Internal.ApiGateway/Dockerfile
  43. 34
      gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.Internal.ApiGateway/ocelot.Development.json
  44. 61
      gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.Internal.ApiGateway/ocelot.messages.json

1
.gitignore

@ -12,6 +12,7 @@ tempkey.jwk
.vs .vs
Publish Publish
LocalNuget LocalNuget
pnpm-lock.yaml
/tests/e2e/videos/ /tests/e2e/videos/
/tests/e2e/screenshots/ /tests/e2e/screenshots/

2
apps/vue/.env

@ -2,7 +2,7 @@
VITE_PORT=3100 VITE_PORT=3100
# spa-title # spa-title
VITE_GLOB_APP_TITLE = Vben Admin VITE_GLOB_APP_TITLE=Abp vNext Admin
# spa shortname # spa shortname
VITE_GLOB_APP_SHORT_NAME=vue_vben_admin VITE_GLOB_APP_SHORT_NAME=vue_vben_admin

2
apps/vue/package.json

@ -36,7 +36,7 @@
"@ant-design/colors": "^6.0.0", "@ant-design/colors": "^6.0.0",
"@ant-design/icons-vue": "^6.0.1", "@ant-design/icons-vue": "^6.0.1",
"@iconify/iconify": "^2.0.4", "@iconify/iconify": "^2.0.4",
"@microsoft/signalr": "^5.0.11", "@microsoft/signalr": "^6.0.0",
"@vueuse/core": "^6.7.4", "@vueuse/core": "^6.7.4",
"@vueuse/shared": "^6.7.4", "@vueuse/shared": "^6.7.4",
"@zxcvbn-ts/core": "^1.0.0-beta.0", "@zxcvbn-ts/core": "^1.0.0-beta.0",

11731
apps/vue/pnpm-lock.yaml

File diff suppressed because it is too large

2
apps/vue/src/layouts/default/header/components/notify/useMessages.ts

@ -29,7 +29,7 @@ export function useMessages() {
const { createConfirm, createMessage } = useMessage(); const { createConfirm, createMessage } = useMessage();
const signalR = useSignalR({ const signalR = useSignalR({
autoStart: false, autoStart: false,
serverUrl: '/signalr-hubs/signalr-hubs/messages', serverUrl: '/signalr-hubs/messages',
}); });
onMounted(() => { onMounted(() => {

2
apps/vue/src/layouts/default/header/components/notify/useNotifications.ts

@ -26,7 +26,7 @@ export function useNotifications() {
list: [], list: [],
}); });
const signalR = useSignalR({ const signalR = useSignalR({
serverUrl: '/signalr-hubs/signalr-hubs/notifications', serverUrl: '/signalr-hubs/notifications',
}); });
onMounted(() => { onMounted(() => {

1
aspnet-core/.gitignore

@ -5,3 +5,4 @@ LocalNuget
templates templates
nupkg nupkg
consoles consoles
*.configs.cache

48
aspnet-core/LINGYUN.MicroService.All.sln

@ -198,12 +198,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.PermissionManag
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.PermissionManagement.Domain.Identity", "modules\identity\LINGYUN.Abp.PermissionManagement.Domain.Identity\LINGYUN.Abp.PermissionManagement.Domain.Identity.csproj", "{2D377D3A-70EC-4BB3-9F4C-6C933693DA98}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.PermissionManagement.Domain.Identity", "modules\identity\LINGYUN.Abp.PermissionManagement.Domain.Identity\LINGYUN.Abp.PermissionManagement.Domain.Identity.csproj", "{2D377D3A-70EC-4BB3-9F4C-6C933693DA98}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.SignalR.JwtToken", "modules\common\LINGYUN.Abp.AspNetCore.SignalR\LINGYUN.Abp.AspNetCore.SignalR.JwtToken.csproj", "{A66D48C9-F141-4111-9169-CEB64AFFF61D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.RealTime.SignalR", "modules\common\LINGYUN.Abp.RealTime.SignalR\LINGYUN.Abp.RealTime.SignalR.csproj", "{524276E1-053D-4191-ABF7-4CDA01BFFBC3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json", "modules\common\LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json\LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json.csproj", "{43083268-74DE-4C68-824A-FB0CEC77358D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wechat", "wechat", "{DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wechat", "wechat", "{DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat", "modules\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj", "{BAE74ABC-1096-495F-A624-BEBFBC1896F2}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat", "modules\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj", "{BAE74ABC-1096-495F-A624-BEBFBC1896F2}"
@ -347,6 +341,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LY.MicroService.RealtimeMes
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Dapr.Client.Wrapper", "modules\dapr\LINGYUN.Abp.Dapr.Client.Wrapper\LINGYUN.Abp.Dapr.Client.Wrapper.csproj", "{842E19B3-8110-40FE-AAFF-D288BC928E55}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Dapr.Client.Wrapper", "modules\dapr\LINGYUN.Abp.Dapr.Client.Wrapper\LINGYUN.Abp.Dapr.Client.Wrapper.csproj", "{842E19B3-8110-40FE-AAFF-D288BC928E55}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mvc", "mvc", "{AEE7BFF0-D16C-49F6-B4E9-9FED2417894E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Mvc.Wrapper", "modules\mvc\LINGYUN.Abp.AspNetCore.Mvc.Wrapper\LINGYUN.Abp.AspNetCore.Mvc.Wrapper.csproj", "{C1319EC1-A489-482B-A343-38B52D8AB0B0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "open-api", "open-api", "{3C7A8246-DE82-4330-8697-24EF1B1C515D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OpenApi", "modules\open-api\LINGYUN.Abp.OpenApi\LINGYUN.Abp.OpenApi.csproj", "{4059F87E-9762-46C1-AEB1-B1128EA533AE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OpenApi.Authorization", "modules\open-api\LINGYUN.Abp.OpenApi.Authorization\LINGYUN.Abp.OpenApi.Authorization.csproj", "{433AD1FB-2DE8-479F-B89E-A17217591538}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -657,18 +661,6 @@ Global
{2D377D3A-70EC-4BB3-9F4C-6C933693DA98}.Debug|Any CPU.Build.0 = Debug|Any CPU {2D377D3A-70EC-4BB3-9F4C-6C933693DA98}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D377D3A-70EC-4BB3-9F4C-6C933693DA98}.Release|Any CPU.ActiveCfg = Release|Any CPU {2D377D3A-70EC-4BB3-9F4C-6C933693DA98}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D377D3A-70EC-4BB3-9F4C-6C933693DA98}.Release|Any CPU.Build.0 = Release|Any CPU {2D377D3A-70EC-4BB3-9F4C-6C933693DA98}.Release|Any CPU.Build.0 = Release|Any CPU
{A66D48C9-F141-4111-9169-CEB64AFFF61D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A66D48C9-F141-4111-9169-CEB64AFFF61D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A66D48C9-F141-4111-9169-CEB64AFFF61D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A66D48C9-F141-4111-9169-CEB64AFFF61D}.Release|Any CPU.Build.0 = Release|Any CPU
{524276E1-053D-4191-ABF7-4CDA01BFFBC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{524276E1-053D-4191-ABF7-4CDA01BFFBC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{524276E1-053D-4191-ABF7-4CDA01BFFBC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{524276E1-053D-4191-ABF7-4CDA01BFFBC3}.Release|Any CPU.Build.0 = Release|Any CPU
{43083268-74DE-4C68-824A-FB0CEC77358D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43083268-74DE-4C68-824A-FB0CEC77358D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43083268-74DE-4C68-824A-FB0CEC77358D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43083268-74DE-4C68-824A-FB0CEC77358D}.Release|Any CPU.Build.0 = Release|Any CPU
{BAE74ABC-1096-495F-A624-BEBFBC1896F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BAE74ABC-1096-495F-A624-BEBFBC1896F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BAE74ABC-1096-495F-A624-BEBFBC1896F2}.Debug|Any CPU.Build.0 = Debug|Any CPU {BAE74ABC-1096-495F-A624-BEBFBC1896F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BAE74ABC-1096-495F-A624-BEBFBC1896F2}.Release|Any CPU.ActiveCfg = Release|Any CPU {BAE74ABC-1096-495F-A624-BEBFBC1896F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -905,6 +897,18 @@ Global
{842E19B3-8110-40FE-AAFF-D288BC928E55}.Debug|Any CPU.Build.0 = Debug|Any CPU {842E19B3-8110-40FE-AAFF-D288BC928E55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{842E19B3-8110-40FE-AAFF-D288BC928E55}.Release|Any CPU.ActiveCfg = Release|Any CPU {842E19B3-8110-40FE-AAFF-D288BC928E55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{842E19B3-8110-40FE-AAFF-D288BC928E55}.Release|Any CPU.Build.0 = Release|Any CPU {842E19B3-8110-40FE-AAFF-D288BC928E55}.Release|Any CPU.Build.0 = Release|Any CPU
{C1319EC1-A489-482B-A343-38B52D8AB0B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C1319EC1-A489-482B-A343-38B52D8AB0B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C1319EC1-A489-482B-A343-38B52D8AB0B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C1319EC1-A489-482B-A343-38B52D8AB0B0}.Release|Any CPU.Build.0 = Release|Any CPU
{4059F87E-9762-46C1-AEB1-B1128EA533AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4059F87E-9762-46C1-AEB1-B1128EA533AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4059F87E-9762-46C1-AEB1-B1128EA533AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4059F87E-9762-46C1-AEB1-B1128EA533AE}.Release|Any CPU.Build.0 = Release|Any CPU
{433AD1FB-2DE8-479F-B89E-A17217591538}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{433AD1FB-2DE8-479F-B89E-A17217591538}.Debug|Any CPU.Build.0 = Debug|Any CPU
{433AD1FB-2DE8-479F-B89E-A17217591538}.Release|Any CPU.ActiveCfg = Release|Any CPU
{433AD1FB-2DE8-479F-B89E-A17217591538}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -1003,9 +1007,6 @@ Global
{CC362C67-6FC1-42B3-A130-8120AA8D790C} = {C5CAD011-DF84-4914-939C-0C029DCEF26F} {CC362C67-6FC1-42B3-A130-8120AA8D790C} = {C5CAD011-DF84-4914-939C-0C029DCEF26F}
{B46D6DAF-98C6-441F-9FA5-3CAD7CF27727} = {CC362C67-6FC1-42B3-A130-8120AA8D790C} {B46D6DAF-98C6-441F-9FA5-3CAD7CF27727} = {CC362C67-6FC1-42B3-A130-8120AA8D790C}
{2D377D3A-70EC-4BB3-9F4C-6C933693DA98} = {52B5D4F7-237B-4E0A-A167-68442164F70A} {2D377D3A-70EC-4BB3-9F4C-6C933693DA98} = {52B5D4F7-237B-4E0A-A167-68442164F70A}
{A66D48C9-F141-4111-9169-CEB64AFFF61D} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{524276E1-053D-4191-ABF7-4CDA01BFFBC3} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{43083268-74DE-4C68-824A-FB0CEC77358D} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21} = {C5CAD011-DF84-4914-939C-0C029DCEF26F} {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21} = {C5CAD011-DF84-4914-939C-0C029DCEF26F}
{BAE74ABC-1096-495F-A624-BEBFBC1896F2} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21} {BAE74ABC-1096-495F-A624-BEBFBC1896F2} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
{E92A1CAA-5758-41EF-B67E-C0D394E85417} = {52B5D4F7-237B-4E0A-A167-68442164F70A} {E92A1CAA-5758-41EF-B67E-C0D394E85417} = {52B5D4F7-237B-4E0A-A167-68442164F70A}
@ -1076,6 +1077,11 @@ Global
{A200E783-CBA2-4F64-A6EC-49D5C6482DEB} = {E5D1B78A-1A8F-4D52-BF99-A4A863ADE898} {A200E783-CBA2-4F64-A6EC-49D5C6482DEB} = {E5D1B78A-1A8F-4D52-BF99-A4A863ADE898}
{A17C9F1D-457A-48AC-B89C-722D8B3955DA} = {608A3BD0-FC8D-48B0-B1C5-F3203A3BE99F} {A17C9F1D-457A-48AC-B89C-722D8B3955DA} = {608A3BD0-FC8D-48B0-B1C5-F3203A3BE99F}
{842E19B3-8110-40FE-AAFF-D288BC928E55} = {DC33925B-264D-421B-96CC-46F853CBCC70} {842E19B3-8110-40FE-AAFF-D288BC928E55} = {DC33925B-264D-421B-96CC-46F853CBCC70}
{AEE7BFF0-D16C-49F6-B4E9-9FED2417894E} = {C5CAD011-DF84-4914-939C-0C029DCEF26F}
{C1319EC1-A489-482B-A343-38B52D8AB0B0} = {AEE7BFF0-D16C-49F6-B4E9-9FED2417894E}
{3C7A8246-DE82-4330-8697-24EF1B1C515D} = {C5CAD011-DF84-4914-939C-0C029DCEF26F}
{4059F87E-9762-46C1-AEB1-B1128EA533AE} = {3C7A8246-DE82-4330-8697-24EF1B1C515D}
{433AD1FB-2DE8-479F-B89E-A17217591538} = {3C7A8246-DE82-4330-8697-24EF1B1C515D}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}

2
aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Emailing/LINGYUN/Abp/ExceptionHandling/Emailing/AbpEmailingExceptionSubscriber.cs

@ -51,7 +51,7 @@ namespace LINGYUN.Abp.ExceptionHandling.Emailing
triggertime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), triggertime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"),
sendstacktrace = EmailOptions.SendStackTrace, sendstacktrace = EmailOptions.SendStackTrace,
stacktrace = context.Exception.ToString(), stacktrace = context.Exception.ToString(),
footer = EmailOptions.DefaultContentFooter ?? "Copyright to LINGYUN © 2020" footer = EmailOptions.DefaultContentFooter ?? $"Copyright to LY Colin © {DateTime.Now.Year}"
}); });
await EmailSender.SendAsync(receivedUsers, await EmailSender.SendAsync(receivedUsers,

2
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN.Abp.IM.SignalR.csproj

@ -22,9 +22,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.AspNetCore.SignalR\LINGYUN.Abp.AspNetCore.SignalR.JwtToken.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.IM\LINGYUN.Abp.IM.csproj" /> <ProjectReference Include="..\LINGYUN.Abp.IM\LINGYUN.Abp.IM.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.RealTime.SignalR\LINGYUN.Abp.RealTime.SignalR.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

13
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalRModule.cs

@ -1,7 +1,6 @@
using LINGYUN.Abp.AspNetCore.SignalR.JwtToken; using LINGYUN.Abp.IM.Localization;
using LINGYUN.Abp.IM.Localization;
using LINGYUN.Abp.IM.SignalR.Messages; using LINGYUN.Abp.IM.SignalR.Messages;
using LINGYUN.Abp.RealTime.SignalR; using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem; using Volo.Abp.VirtualFileSystem;
@ -10,8 +9,7 @@ namespace LINGYUN.Abp.IM.SignalR
{ {
[DependsOn( [DependsOn(
typeof(AbpIMModule), typeof(AbpIMModule),
typeof(AbpRealTimeSignalRModule), typeof(AbpAspNetCoreSignalRModule))]
typeof(AbpAspNetCoreSignalRJwtTokenModule))]
public class AbpIMSignalRModule : AbpModule public class AbpIMSignalRModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
@ -32,11 +30,6 @@ namespace LINGYUN.Abp.IM.SignalR
.Get<AbpIMResource>() .Get<AbpIMResource>()
.AddVirtualJson("/LINGYUN/Abp/IM/SignalR/Localization/Resources"); .AddVirtualJson("/LINGYUN/Abp/IM/SignalR/Localization/Resources");
}); });
Configure<AbpAspNetCoreSignalRJwtTokenMapPathOptions>(options =>
{
options.MapPath("messages");
});
} }
} }
} }

98
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessagesHub.cs

@ -3,12 +3,9 @@ using LINGYUN.Abp.IM.Groups;
using LINGYUN.Abp.IM.Localization; using LINGYUN.Abp.IM.Localization;
using LINGYUN.Abp.IM.Messages; using LINGYUN.Abp.IM.Messages;
using LINGYUN.Abp.RealTime; using LINGYUN.Abp.RealTime;
using LINGYUN.Abp.RealTime.Client;
using LINGYUN.Abp.RealTime.Localization; using LINGYUN.Abp.RealTime.Localization;
using LINGYUN.Abp.RealTime.SignalR;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -17,13 +14,15 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.AspNetCore.ExceptionHandling; using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Users;
namespace LINGYUN.Abp.IM.SignalR.Hubs namespace LINGYUN.Abp.IM.SignalR.Hubs
{ {
[Authorize] [Authorize]
public class MessagesHub : OnlineClientHubBase public class MessagesHub : AbpHub
{ {
protected IMessageProcessor Processor => LazyServiceProvider.LazyGetService<IMessageProcessor>(); protected IMessageProcessor Processor => LazyServiceProvider.LazyGetService<IMessageProcessor>();
@ -33,72 +32,50 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
protected IExceptionToErrorInfoConverter ErrorInfoConverter => LazyServiceProvider.LazyGetRequiredService<IExceptionToErrorInfoConverter>(); protected IExceptionToErrorInfoConverter ErrorInfoConverter => LazyServiceProvider.LazyGetRequiredService<IExceptionToErrorInfoConverter>();
protected AbpIMSignalROptions Options { get; } protected AbpIMSignalROptions Options => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpIMSignalROptions>>().Value;
protected IFriendStore FriendStore { get; }
protected IMessageStore MessageStore { get; }
protected IUserGroupStore UserGroupStore { get; }
public MessagesHub( protected IFriendStore FriendStore => LazyServiceProvider.LazyGetRequiredService<IFriendStore>();
IFriendStore friendStore,
IMessageStore messageStore,
IUserGroupStore userGroupStore,
IOptions<AbpIMSignalROptions> options)
{
FriendStore = friendStore;
MessageStore = messageStore;
UserGroupStore = userGroupStore;
Options = options.Value;
}
protected override async Task OnClientConnectedAsync(IOnlineClient client) protected IMessageStore MessageStore => LazyServiceProvider.LazyGetRequiredService<IMessageStore>();
{
await base.OnClientConnectedAsync(client);
// 用户上线 protected IUserGroupStore UserGroupStore => LazyServiceProvider.LazyGetRequiredService<IUserGroupStore>();
await OnlineChanger?.ChangeAsync(client.TenantId, client.UserId.Value, UserOnlineState.Online);
await SendUserOnlineStateAsync(client); public override async Task OnConnectedAsync()
{
await base.OnConnectedAsync();
await SendUserOnlineStateAsync();
} }
protected override async Task OnClientDisconnectedAsync(IOnlineClient client) public override async Task OnDisconnectedAsync(Exception exception)
{ {
await base.OnClientDisconnectedAsync(client); await base.OnDisconnectedAsync(exception);
// 用户下线
await OnlineChanger?.ChangeAsync(client.TenantId, client.UserId.Value, UserOnlineState.Offline);
await SendUserOnlineStateAsync(client, false); await SendUserOnlineStateAsync(false);
} }
protected virtual async Task SendUserOnlineStateAsync(IOnlineClient client, bool isOnlined = true) protected virtual async Task SendUserOnlineStateAsync(bool isOnlined = true)
{ {
var methodName = isOnlined ? Options.UserOnlineMethod : Options.UserOfflineMethod; var methodName = isOnlined ? Options.UserOnlineMethod : Options.UserOfflineMethod;
var userGroups = await UserGroupStore.GetUserGroupsAsync(client.TenantId, client.UserId.Value); var userGroups = await UserGroupStore.GetUserGroupsAsync(CurrentTenant.Id, CurrentUser.GetId());
foreach (var group in userGroups) foreach (var group in userGroups)
{ {
if (isOnlined) if (isOnlined)
{ {
// 应使用群组标识 // 应使用群组标识
await Groups.AddToGroupAsync(client.ConnectionId, group.Id); await Groups.AddToGroupAsync(Context.ConnectionId, group.Id);
} }
var groupClient = Clients.Group(group.Id); var groupClient = Clients.Group(group.Id);
if (groupClient != null) await groupClient.SendAsync(methodName, CurrentTenant.Id, CurrentUser.GetId());
{
// 发送用户下线通知
await groupClient.SendAsync(methodName, client.TenantId, client.UserId.Value);
}
} }
var userFriends = await FriendStore.GetListAsync(client.TenantId, client.UserId.Value); var userFriends = await FriendStore.GetListAsync(CurrentTenant.Id, CurrentUser.GetId());
if (userFriends.Count > 0) if (userFriends.Count > 0)
{ {
var friendClientIds = userFriends.Select(friend => friend.FriendId.ToString()).ToImmutableArray(); var friendClientIds = userFriends.Select(friend => friend.FriendId.ToString()).ToImmutableArray();
var userClients = Clients.Users(friendClientIds); var userClients = Clients.Users(friendClientIds);
if (userClients != null) await userClients.SendAsync(methodName, CurrentTenant.Id, CurrentUser.GetId());
{
await userClients.SendAsync(methodName, client.TenantId, client.UserId.Value);
}
} }
} }
/// <summary> /// <summary>
@ -106,9 +83,8 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
/// </summary> /// </summary>
/// <param name="chatMessage"></param> /// <param name="chatMessage"></param>
/// <returns></returns> /// <returns></returns>
// [HubMethodName("SendMessage")]
[HubMethodName("send")] [HubMethodName("send")]
public virtual async Task SendAsync(ChatMessage chatMessage) public virtual async Task SendMessageAsync(ChatMessage chatMessage)
{ {
await SendMessageAsync(Options.GetChatMessageMethod, chatMessage, true); await SendMessageAsync(Options.GetChatMessageMethod, chatMessage, true);
} }
@ -223,39 +199,13 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
protected virtual async Task SendMessageToGroupAsync(string methodName, ChatMessage chatMessage) protected virtual async Task SendMessageToGroupAsync(string methodName, ChatMessage chatMessage)
{ {
var signalRClient = Clients.Group(chatMessage.GroupId); var signalRClient = Clients.Group(chatMessage.GroupId);
if (signalRClient == null)
{
Logger.LogDebug("Can not get group " + chatMessage.GroupId + " from SignalR hub!");
return;
}
await signalRClient.SendAsync(methodName, chatMessage); await signalRClient.SendAsync(methodName, chatMessage);
} }
protected virtual async Task SendMessageToUserAsync(string methodName, ChatMessage chatMessage) protected virtual async Task SendMessageToUserAsync(string methodName, ChatMessage chatMessage)
{ {
var onlineClientContext = new OnlineClientContext(chatMessage.TenantId, chatMessage.ToUserId.GetValueOrDefault()); var onlineClients = Clients.User(chatMessage.ToUserId.GetValueOrDefault().ToString());
var onlineClients = OnlineClientManager.GetAllByContext(onlineClientContext); await onlineClients.SendAsync(methodName, chatMessage);
foreach (var onlineClient in onlineClients)
{
try
{
var signalRClient = Clients.Client(onlineClient.ConnectionId);
if (signalRClient == null)
{
Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!");
continue;
}
await signalRClient.SendAsync(methodName, chatMessage);
}
catch (Exception ex)
{
// 发送异常记录就行了,因为消息已经持久化
Logger.LogWarning("Could not send message to user: {0}", chatMessage.ToUserId);
Logger.LogWarning("Send to user message error: {0}", ex.Message);
}
}
} }
} }
} }

19
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSenderProvider.cs

@ -1,12 +1,9 @@
using LINGYUN.Abp.IM.Messages; using LINGYUN.Abp.IM.Messages;
using LINGYUN.Abp.IM.SignalR.Hubs; using LINGYUN.Abp.IM.SignalR.Hubs;
using LINGYUN.Abp.RealTime.Client;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System; using System;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.AspNetCore.ExceptionHandling; using Volo.Abp.AspNetCore.ExceptionHandling;
@ -21,12 +18,9 @@ namespace LINGYUN.Abp.IM.SignalR.Messages
public override string Name => "SignalR"; public override string Name => "SignalR";
private readonly AbpIMSignalROptions _options; private readonly AbpIMSignalROptions _options;
private readonly IOnlineClientManager _onlineClientManager;
private readonly IHubContext<MessagesHub> _hubContext; private readonly IHubContext<MessagesHub> _hubContext;
public SignalRMessageSenderProvider( public SignalRMessageSenderProvider(
IOnlineClientManager onlineClientManager,
IHubContext<MessagesHub> hubContext, IHubContext<MessagesHub> hubContext,
IAbpLazyServiceProvider serviceProvider, IAbpLazyServiceProvider serviceProvider,
IOptions<AbpIMSignalROptions> options) IOptions<AbpIMSignalROptions> options)
@ -34,7 +28,6 @@ namespace LINGYUN.Abp.IM.SignalR.Messages
{ {
_options = options.Value; _options = options.Value;
_hubContext = hubContext; _hubContext = hubContext;
_onlineClientManager = onlineClientManager;
} }
protected override async Task SendMessageToGroupAsync(ChatMessage chatMessage) protected override async Task SendMessageToGroupAsync(ChatMessage chatMessage)
@ -76,17 +69,13 @@ namespace LINGYUN.Abp.IM.SignalR.Messages
{ {
try try
{ {
var onlineClientContext = new OnlineClientContext(chatMessage.TenantId, chatMessage.ToUserId.Value); var onlineClients = _hubContext.Clients.User(chatMessage.ToUserId.Value.ToString());
var onlineClients = _onlineClientManager.GetAllByContext(onlineClientContext); if (onlineClients == null)
var onlineClientConnectionIds = onlineClients.Select(client => client.ConnectionId).ToImmutableArray();
var signalRClients = _hubContext.Clients.Clients(onlineClientConnectionIds);
if (signalRClients == null)
{ {
Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " connection from SignalR hub!"); Logger.LogDebug("Can not get user " + chatMessage.ToUserId + " connection from SignalR hub!");
return; return;
} }
await signalRClients.SendAsync(_options.GetChatMessageMethod, chatMessage); await onlineClients.SendAsync(_options.GetChatMessageMethod, chatMessage);
} }
catch (Exception ex) catch (Exception ex)
{ {

33
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/UserOnlineChecker.cs

@ -1,33 +0,0 @@
using LINGYUN.Abp.RealTime.Client;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.IM.SignalR
{
public class UserOnlineChecker : IUserOnlineChecker, ITransientDependency
{
private readonly IOnlineClientManager _onlineClientManager;
public UserOnlineChecker(
IOnlineClientManager onlineClientManager)
{
_onlineClientManager = onlineClientManager;
}
public virtual Task<bool> CheckAsync(
Guid? tenantId,
Guid userId,
CancellationToken cancellationToken = default)
{
var onlineClients = _onlineClientManager
.GetAllClients(client => client.UserId.Equals(userId));
var userOnlined = onlineClients?.Any() == true;
return Task.FromResult(userOnlined);
}
}
}

16
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/NullUserOnlineChanger.cs

@ -0,0 +1,16 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.IM
{
[Dependency(TryRegister = true)]
public class NullUserOnlineChanger : IUserOnlineChanger, ISingletonDependency
{
public Task ChangeAsync(Guid? tenantId, Guid userId, UserOnlineState state, CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
}
}

16
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/NullUserOnlineChecker.cs

@ -0,0 +1,16 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.IM
{
[Dependency(TryRegister = true)]
public class NullUserOnlineChecker : IUserOnlineChecker, ISingletonDependency
{
public Task<bool> CheckAsync(Guid? tenantId, Guid userId, CancellationToken cancellationToken = default)
{
return Task.FromResult(false);
}
}
}

4
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN.Abp.Notifications.SignalR.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" /> <Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" /> <Import Project="..\..\..\common.props" />
@ -14,9 +14,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.AspNetCore.SignalR\LINGYUN.Abp.AspNetCore.SignalR.JwtToken.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" /> <ProjectReference Include="..\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.RealTime.SignalR\LINGYUN.Abp.RealTime.SignalR.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

13
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs

@ -1,15 +1,11 @@
using LINGYUN.Abp.AspNetCore.SignalR.JwtToken; using Volo.Abp.AspNetCore.SignalR;
using LINGYUN.Abp.RealTime.SignalR;
using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications.SignalR namespace LINGYUN.Abp.Notifications.SignalR
{ {
[DependsOn( [DependsOn(
typeof(AbpRealTimeSignalRModule),
typeof(AbpNotificationModule), typeof(AbpNotificationModule),
typeof(AbpAspNetCoreSignalRModule), typeof(AbpAspNetCoreSignalRModule))]
typeof(AbpAspNetCoreSignalRJwtTokenModule))]
public class AbpNotificationsSignalRModule : AbpModule public class AbpNotificationsSignalRModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
@ -21,11 +17,6 @@ namespace LINGYUN.Abp.Notifications.SignalR
.MappingDefault(SignalRNotificationPublishProvider.ProviderName, .MappingDefault(SignalRNotificationPublishProvider.ProviderName,
data => data.ToSignalRData()); data => data.ToSignalRData());
}); });
Configure<AbpAspNetCoreSignalRJwtTokenMapPathOptions>(options =>
{
options.MapPath("notifications");
});
} }
} }
} }

30
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs

@ -1,46 +1,48 @@
using LINGYUN.Abp.RealTime.Client; using Microsoft.AspNetCore.Authorization;
using LINGYUN.Abp.RealTime.SignalR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow; using Volo.Abp.Uow;
using Volo.Abp.Users; using Volo.Abp.Users;
namespace LINGYUN.Abp.Notifications.SignalR.Hubs namespace LINGYUN.Abp.Notifications.SignalR.Hubs
{ {
[Authorize] [Authorize]
public class NotificationsHub : OnlineClientHubBase public class NotificationsHub : AbpHub
{ {
protected INotificationStore NotificationStore => LazyServiceProvider.LazyGetRequiredService<INotificationStore>(); protected INotificationStore NotificationStore => LazyServiceProvider.LazyGetRequiredService<INotificationStore>();
protected override async Task OnClientConnectedAsync(IOnlineClient client) public override async Task OnConnectedAsync()
{ {
await base.OnClientConnectedAsync(client); await base.OnConnectedAsync();
if (client.TenantId.HasValue) if (CurrentTenant.IsAvailable)
{ {
// 以租户为分组,将用户加入租户通讯组 // 以租户为分组,将用户加入租户通讯组
await Groups.AddToGroupAsync(client.ConnectionId, client.TenantId.Value.ToString(), Context.ConnectionAborted); await Groups.AddToGroupAsync(Context.ConnectionId, CurrentTenant.GetId().ToString(), Context.ConnectionAborted);
} }
else else
{ {
await Groups.AddToGroupAsync(client.ConnectionId, "Global", Context.ConnectionAborted); await Groups.AddToGroupAsync(Context.ConnectionId, "Global", Context.ConnectionAborted);
} }
} }
protected override async Task OnClientDisconnectedAsync(IOnlineClient client) public override async Task OnDisconnectedAsync(Exception exception)
{ {
await base.OnClientDisconnectedAsync(client); await base.OnDisconnectedAsync(exception);
if (client.TenantId.HasValue)
if (CurrentTenant.IsAvailable)
{ {
// 以租户为分组,将移除租户通讯组 // 以租户为分组,将移除租户通讯组
await Groups.RemoveFromGroupAsync(client.ConnectionId, client.TenantId.Value.ToString(), Context.ConnectionAborted); await Groups.RemoveFromGroupAsync(Context.ConnectionId, CurrentTenant.GetId().ToString(), Context.ConnectionAborted);
} }
else else
{ {
await Groups.RemoveFromGroupAsync(client.ConnectionId, "Global", Context.ConnectionAborted); await Groups.RemoveFromGroupAsync(Context.ConnectionId, "Global", Context.ConnectionAborted);
} }
} }

22
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs

@ -1,11 +1,9 @@
using LINGYUN.Abp.Notifications.SignalR.Hubs; using LINGYUN.Abp.Notifications.SignalR.Hubs;
using LINGYUN.Abp.RealTime.Client;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -17,13 +15,10 @@ namespace LINGYUN.Abp.Notifications.SignalR
public const string ProviderName = "SignalR"; public const string ProviderName = "SignalR";
public override string Name => ProviderName; public override string Name => ProviderName;
private readonly IOnlineClientManager _onlineClientManager;
private readonly IHubContext<NotificationsHub> _hubContext; private readonly IHubContext<NotificationsHub> _hubContext;
private readonly AbpNotificationsSignalROptions _options; private readonly AbpNotificationsSignalROptions _options;
public SignalRNotificationPublishProvider( public SignalRNotificationPublishProvider(
IOnlineClientManager onlineClientManager,
IHubContext<NotificationsHub> hubContext, IHubContext<NotificationsHub> hubContext,
IOptions<AbpNotificationsSignalROptions> options, IOptions<AbpNotificationsSignalROptions> options,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
@ -31,7 +26,6 @@ namespace LINGYUN.Abp.Notifications.SignalR
{ {
_options = options.Value; _options = options.Value;
_hubContext = hubContext; _hubContext = hubContext;
_onlineClientManager = onlineClientManager;
} }
protected override async Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers, CancellationToken cancellationToken = default) protected override async Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers, CancellationToken cancellationToken = default)
@ -41,29 +35,17 @@ namespace LINGYUN.Abp.Notifications.SignalR
var groupName = notification.TenantId?.ToString() ?? "Global"; var groupName = notification.TenantId?.ToString() ?? "Global";
var singalRGroup = _hubContext.Clients.Group(groupName); var singalRGroup = _hubContext.Clients.Group(groupName);
if (singalRGroup == null)
{
Logger.LogDebug("Can not get group " + groupName + " from SignalR hub!");
return;
}
// 租户通知群发 // 租户通知群发
Logger.LogDebug($"Found a singalr group, begin senging notifications"); Logger.LogDebug($"Found a singalr group, begin senging notifications");
await singalRGroup.SendAsync(_options.MethodName, notification, cancellationToken); await singalRGroup.SendAsync(_options.MethodName, notification, cancellationToken);
} }
else else
{ {
var onlineClients = _onlineClientManager.GetAllClients(client => identifiers.Any(ids => client.UserId == ids.UserId));
var onlineClientConnectionIds = onlineClients.Select(client => client.ConnectionId).ToImmutableArray();
try try
{ {
var signalRClients = _hubContext.Clients.Clients(onlineClientConnectionIds); var onlineClients = _hubContext.Clients.Users(identifiers.Select(x => x.UserId.ToString()));
if (signalRClients == null)
{
Logger.LogDebug("Can not get users connection from SignalR hub!");
return;
}
Logger.LogDebug($"Found a singalr client, begin senging notifications"); Logger.LogDebug($"Found a singalr client, begin senging notifications");
await signalRClients.SendAsync(_options.MethodName, notification, cancellationToken); await onlineClients.SendAsync(_options.MethodName, notification, cancellationToken);
} }
catch (Exception ex) catch (Exception ex)
{ {

37
aspnet-core/modules/common/LINGYUN.Abp.RealTime.SignalR/LINGYUN/Abp/RealTime/SignalR/Hubs/OnlineClientHubBase.cs

@ -17,13 +17,21 @@ namespace LINGYUN.Abp.RealTime.SignalR
await base.OnConnectedAsync(); await base.OnConnectedAsync();
IOnlineClient onlineClient = CreateClientForCurrentConnection(); IOnlineClient onlineClient = CreateClientForCurrentConnection();
OnlineClientManager.Add(onlineClient);
await OnConnectedAsync(onlineClient); await OnConnectedAsync(onlineClient);
} }
public virtual async Task OnConnectedAsync(IOnlineClient client) public async Task OnConnectedAsync(IOnlineClient client)
{ {
Logger.LogDebug("A client is connected: " + client.ToString()); Logger.LogDebug("A client is connected: " + client.ToString());
OnlineClientManager.Add(client);
// 角色添加进组
foreach (var role in client.Roles)
{
await Groups.AddToGroupAsync(client.ConnectionId, role);
}
await OnClientConnectedAsync(client); await OnClientConnectedAsync(client);
} }
@ -36,15 +44,22 @@ namespace LINGYUN.Abp.RealTime.SignalR
await base.OnDisconnectedAsync(exception); await base.OnDisconnectedAsync(exception);
} }
public virtual async Task OnDisconnectedAsync(IOnlineClient client) public async Task OnDisconnectedAsync(IOnlineClient client)
{ {
if (client != null) if (client != null)
{ {
try try
{ {
// 角色添加进组
foreach (var role in client.Roles)
{
await Groups.RemoveFromGroupAsync(client.ConnectionId, role);
}
Logger.LogDebug("A client is disconnected: " + client); Logger.LogDebug("A client is disconnected: " + client);
// 移除在线客户端 // 移除在线客户端
OnlineClientManager.Remove(Context.ConnectionId); OnlineClientManager.Remove(Context.ConnectionId);
await OnClientDisconnectedAsync(client); await OnClientDisconnectedAsync(client);
} }
catch (Exception ex) catch (Exception ex)
@ -70,22 +85,14 @@ namespace LINGYUN.Abp.RealTime.SignalR
}; };
} }
protected virtual async Task OnClientConnectedAsync(IOnlineClient client) protected virtual Task OnClientConnectedAsync(IOnlineClient client)
{
// 角色添加进组
foreach (var role in client.Roles)
{ {
await Groups.AddToGroupAsync(client.ConnectionId, role); return Task.CompletedTask;
}
} }
protected virtual async Task OnClientDisconnectedAsync(IOnlineClient client) protected virtual Task OnClientDisconnectedAsync(IOnlineClient client)
{
// 角色添加进组
foreach (var role in client.Roles)
{ {
await Groups.RemoveFromGroupAsync(client.ConnectionId, role); return Task.CompletedTask;
}
} }
} }
} }

10
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IClient.cs

@ -1,10 +0,0 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.RealTime.Client
{
public interface IClient
{
Task OnConnectedAsync(IOnlineClient client);
Task OnDisconnectedAsync(IOnlineClient client);
}
}

28
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IOnlineClient.cs

@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
namespace LINGYUN.Abp.RealTime.Client
{
public interface IOnlineClient
{
string ConnectionId { get; }
string IpAddress { get; }
Guid? TenantId { get; }
Guid? UserId { get; }
string UserAccount { get; }
string UserName { get; }
DateTime ConnectTime { get; }
string[] Roles { get; }
object this[object key] { get; set; }
IDictionary<object, object> Properties { get; }
}
}

30
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IOnlineClientManager.cs

@ -1,30 +0,0 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace LINGYUN.Abp.RealTime.Client
{
public interface IOnlineClientManager
{
event EventHandler<OnlineClientEventArgs> ClientConnected;
event EventHandler<OnlineClientEventArgs> ClientDisconnected;
event EventHandler<OnlineUserEventArgs> UserConnected;
event EventHandler<OnlineUserEventArgs> UserDisconnected;
void Add(IOnlineClient client);
bool Remove(string connectionId);
IOnlineClient GetByConnectionIdOrNull(string connectionId);
IReadOnlyList<IOnlineClient> GetAllClients();
IReadOnlyList<IOnlineClient> GetAllClients(Expression<Func<IOnlineClient, bool>> predicate);
IReadOnlyList<IOnlineClient> GetAllByContext([NotNull] OnlineClientContext context);
}
}

23
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IOnlineClientStore.cs

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace LINGYUN.Abp.RealTime.Client
{
public interface IOnlineClientStore
{
void Add(IOnlineClient client);
bool Remove(string connectionId);
bool TryRemove(string connectionId, out IOnlineClient client);
bool TryGet(string connectionId, out IOnlineClient client);
bool Contains(string connectionId);
IReadOnlyList<IOnlineClient> GetAll();
IReadOnlyList<IOnlineClient> GetAll(Expression<Func<IOnlineClient, bool>> predicate);
}
}

57
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/InMemoryOnlineClientStore.cs

@ -1,57 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Linq.Expressions;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.RealTime.Client
{
public class InMemoryOnlineClientStore : IOnlineClientStore, ISingletonDependency
{
protected ConcurrentDictionary<string, IOnlineClient> Clients { get; }
public InMemoryOnlineClientStore()
{
Clients = new ConcurrentDictionary<string, IOnlineClient>();
}
public void Add(IOnlineClient client)
{
Clients.AddOrUpdate(client.ConnectionId, client, (s, o) => client);
}
public bool Remove(string connectionId)
{
return TryRemove(connectionId, out _);
}
public bool TryRemove(string connectionId, out IOnlineClient client)
{
return Clients.TryRemove(connectionId, out client);
}
public bool TryGet(string connectionId, out IOnlineClient client)
{
return Clients.TryGetValue(connectionId, out client);
}
public bool Contains(string connectionId)
{
return Clients.ContainsKey(connectionId);
}
public IReadOnlyList<IOnlineClient> GetAll()
{
return Clients.Values.ToImmutableList();
}
public IReadOnlyList<IOnlineClient> GetAll(Expression<Func<IOnlineClient, bool>> predicate)
{
return Clients.Values
.Where(predicate.Compile())
.ToImmutableList();
}
}
}

72
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClient.cs

@ -1,72 +0,0 @@
using System;
using System.Collections.Generic;
namespace LINGYUN.Abp.RealTime.Client
{
[Serializable]
public class OnlineClient : IOnlineClient
{
public object this[object key]
{
get { return Properties[key]; }
set { Properties[key] = value; }
}
public string ConnectionId { get; set; }
public string IpAddress { get; set; }
public Guid? TenantId { get; set; }
public Guid? UserId { get; }
public string UserAccount { get; set; }
public string UserName { get; set; }
public string[] Roles { get; set; }
public DateTime ConnectTime { get; set; }
private IDictionary<object, object> _properties;
public IDictionary<object, object> Properties
{
get { return _properties; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_properties = value;
}
}
public OnlineClient()
{
ConnectTime = DateTime.Now;
}
public OnlineClient(string connectionId, string ipAddress, Guid? tenantId, Guid? userId)
: this()
{
ConnectionId = connectionId;
IpAddress = ipAddress;
TenantId = tenantId;
UserId = userId;
Roles = new string[0];
Properties = new Dictionary<object, object>();
}
public override string ToString()
{
return string.Concat(
"-- ConnectionId:", ConnectionId,
"-- Connection Time:", ConnectTime,
"-- IpAddress:", IpAddress ?? "::1",
"-- UserName:", UserName,
"-- TenantId:", TenantId.HasValue ? TenantId.Value.ToString() : "None");
}
}
}

17
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClientContext.cs

@ -1,17 +0,0 @@
using System;
namespace LINGYUN.Abp.RealTime.Client
{
public class OnlineClientContext
{
public Guid? TenantId { get; }
public Guid UserId { get; }
public OnlineClientContext(Guid? tenantId, Guid userId)
{
TenantId = tenantId;
UserId = userId;
}
}
}

14
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClientEventArgs.cs

@ -1,14 +0,0 @@
using System;
namespace LINGYUN.Abp.RealTime.Client
{
public class OnlineClientEventArgs : EventArgs
{
public IOnlineClient Client { get; }
public OnlineClientEventArgs(IOnlineClient client)
{
Client = client;
}
}
}

15
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClientExtensions.cs

@ -1,15 +0,0 @@
using JetBrains.Annotations;
namespace LINGYUN.Abp.RealTime.Client
{
public static class OnlineClientExtensions
{
[CanBeNull]
public static OnlineClientContext ToClientContextOrNull(this IOnlineClient onlineClient)
{
return onlineClient.UserId.HasValue
? new OnlineClientContext(onlineClient.TenantId, onlineClient.UserId.Value)
: null;
}
}
}

111
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClientManager.cs

@ -1,111 +0,0 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Linq.Expressions;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.RealTime.Client
{
public class OnlineClientManager : IOnlineClientManager, ISingletonDependency
{
public event EventHandler<OnlineClientEventArgs> ClientConnected;
public event EventHandler<OnlineClientEventArgs> ClientDisconnected;
public event EventHandler<OnlineUserEventArgs> UserConnected;
public event EventHandler<OnlineUserEventArgs> UserDisconnected;
protected IOnlineClientStore Store { get; }
protected readonly object SyncObj = new object();
public OnlineClientManager(IOnlineClientStore store)
{
Store = store;
}
public virtual void Add(IOnlineClient client)
{
lock (SyncObj)
{
var userWasAlreadyOnline = false;
var context = client.ToClientContextOrNull();
if (context != null)
{
userWasAlreadyOnline = this.IsOnline(context);
}
Store.Add(client);
ClientConnected?.Invoke(this, new OnlineClientEventArgs(client));
if (context != null && !userWasAlreadyOnline)
{
UserConnected?.Invoke(this, new OnlineUserEventArgs(context, client));
}
}
}
public virtual bool Remove(string connectionId)
{
lock (SyncObj)
{
var result = Store.TryRemove(connectionId, out IOnlineClient client);
if (result)
{
if (UserDisconnected != null)
{
var context = client.ToClientContextOrNull();
if (context != null && !this.IsOnline(context))
{
UserDisconnected.Invoke(this, new OnlineUserEventArgs(context, client));
}
}
ClientDisconnected?.Invoke(this, new OnlineClientEventArgs(client));
}
return result;
}
}
public virtual IOnlineClient GetByConnectionIdOrNull(string connectionId)
{
lock (SyncObj)
{
if (Store.TryGet(connectionId, out IOnlineClient client))
{
return client;
}
else
{
return null;
}
}
}
public virtual IReadOnlyList<IOnlineClient> GetAllClients()
{
return Store.GetAll();
}
public virtual IReadOnlyList<IOnlineClient> GetAllClients(Expression<Func<IOnlineClient, bool>> predicate)
{
return Store.GetAll(predicate);
}
[NotNull]
public virtual IReadOnlyList<IOnlineClient> GetAllByContext([NotNull] OnlineClientContext context)
{
Check.NotNull(context, nameof(context));
return GetAllClients()
.Where(c => c.TenantId == context.TenantId && c.UserId.Equals(context.UserId))
.ToImmutableList();
}
}
}

26
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClientManagerExtensions.cs

@ -1,26 +0,0 @@
using JetBrains.Annotations;
using System.Linq;
using Volo.Abp;
namespace LINGYUN.Abp.RealTime.Client
{
public static class OnlineClientManagerExtensions
{
public static bool IsOnline(
[NotNull] this IOnlineClientManager onlineClientManager,
[NotNull] OnlineClientContext context)
{
return onlineClientManager.GetAllByContext(context).Any();
}
public static bool Remove(
[NotNull] this IOnlineClientManager onlineClientManager,
[NotNull] IOnlineClient client)
{
Check.NotNull(onlineClientManager, nameof(onlineClientManager));
Check.NotNull(client, nameof(client));
return onlineClientManager.Remove(client.ConnectionId);
}
}
}

13
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineUserEventArgs.cs

@ -1,13 +0,0 @@
namespace LINGYUN.Abp.RealTime.Client
{
public class OnlineUserEventArgs : OnlineClientEventArgs
{
public OnlineClientContext Context { get; }
public OnlineUserEventArgs(OnlineClientContext context, IOnlineClient client)
: base(client)
{
Context = context;
}
}
}

22
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionPageWrapResultFilter.cs

@ -1,6 +1,7 @@
using LINGYUN.Abp.Wrapper; using LINGYUN.Abp.Wrapper;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -10,6 +11,7 @@ using System.Threading.Tasks;
using Volo.Abp.AspNetCore.ExceptionHandling; using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling; using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.Authorization;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.ExceptionHandling; using Volo.Abp.ExceptionHandling;
using Volo.Abp.Http; using Volo.Abp.Http;
@ -33,7 +35,11 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling
var wrapOptions = context.GetRequiredService<IOptions<AbpWrapperOptions>>().Value; var wrapOptions = context.GetRequiredService<IOptions<AbpWrapperOptions>>().Value;
var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value; var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>(); var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>();
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients); var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, options =>
{
options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients;
options.SendStackTraceToClients = exceptionHandlingOptions.SendStackTraceToClients;
});
var logLevel = context.Exception.GetLogLevel(); var logLevel = context.Exception.GetLogLevel();
@ -48,6 +54,14 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling
await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception)); await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception));
if (context.Exception is AbpAuthorizationException)
{
await context.HttpContext.RequestServices.GetRequiredService<IAbpAuthorizationExceptionHandler>()
.HandleAsync(context.Exception.As<AbpAuthorizationException>(), context.HttpContext);
}
else
{
var statusCodFinder = context.GetRequiredService<IHttpExceptionStatusCodeFinder>(); var statusCodFinder = context.GetRequiredService<IHttpExceptionStatusCodeFinder>();
var exceptionWrapHandler = context.GetRequiredService<IExceptionWrapHandlerFactory>(); var exceptionWrapHandler = context.GetRequiredService<IExceptionWrapHandlerFactory>();
var exceptionWrapContext = new ExceptionWrapContext( var exceptionWrapContext = new ExceptionWrapContext(
@ -56,14 +70,14 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling
context.HttpContext.RequestServices, context.HttpContext.RequestServices,
statusCodFinder.GetStatusCode(context.HttpContext, context.Exception)); statusCodFinder.GetStatusCode(context.HttpContext, context.Exception));
exceptionWrapHandler.CreateFor(exceptionWrapContext).Wrap(exceptionWrapContext); exceptionWrapHandler.CreateFor(exceptionWrapContext).Wrap(exceptionWrapContext);
var wrapResult = new WrapResult( context.Result = new ObjectResult(new WrapResult(
exceptionWrapContext.ErrorInfo.Code, exceptionWrapContext.ErrorInfo.Code,
exceptionWrapContext.ErrorInfo.Message, exceptionWrapContext.ErrorInfo.Message,
exceptionWrapContext.ErrorInfo.Details); exceptionWrapContext.ErrorInfo.Details));
context.Result = new ObjectResult(wrapResult);
context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true"); context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true");
context.HttpContext.Response.StatusCode = (int)wrapOptions.HttpStatusCode; context.HttpContext.Response.StatusCode = (int)wrapOptions.HttpStatusCode;
}
context.Exception = null; //Handled! context.Exception = null; //Handled!
} }

20
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionWrapResultFilter.cs

@ -11,6 +11,7 @@ using System.Threading.Tasks;
using Volo.Abp.AspNetCore.ExceptionHandling; using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling; using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.Authorization;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.ExceptionHandling; using Volo.Abp.ExceptionHandling;
using Volo.Abp.Http; using Volo.Abp.Http;
@ -35,7 +36,11 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling
var wrapOptions = context.GetRequiredService<IOptions<AbpWrapperOptions>>().Value; var wrapOptions = context.GetRequiredService<IOptions<AbpWrapperOptions>>().Value;
var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value; var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>(); var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>();
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients); var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, options =>
{
options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients;
options.SendStackTraceToClients = exceptionHandlingOptions.SendStackTraceToClients;
});
var logLevel = context.Exception.GetLogLevel(); var logLevel = context.Exception.GetLogLevel();
@ -51,6 +56,13 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling
await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception)); await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception));
if (context.Exception is AbpAuthorizationException)
{
await context.GetRequiredService<IAbpAuthorizationExceptionHandler>()
.HandleAsync(context.Exception.As<AbpAuthorizationException>(), context.HttpContext);
}
else
{
var statusCodFinder = context.GetRequiredService<IHttpExceptionStatusCodeFinder>(); var statusCodFinder = context.GetRequiredService<IHttpExceptionStatusCodeFinder>();
var exceptionWrapHandler = context.GetRequiredService<IExceptionWrapHandlerFactory>(); var exceptionWrapHandler = context.GetRequiredService<IExceptionWrapHandlerFactory>();
var exceptionWrapContext = new ExceptionWrapContext( var exceptionWrapContext = new ExceptionWrapContext(
@ -59,14 +71,14 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling
context.HttpContext.RequestServices, context.HttpContext.RequestServices,
statusCodFinder.GetStatusCode(context.HttpContext, context.Exception)); statusCodFinder.GetStatusCode(context.HttpContext, context.Exception));
exceptionWrapHandler.CreateFor(exceptionWrapContext).Wrap(exceptionWrapContext); exceptionWrapHandler.CreateFor(exceptionWrapContext).Wrap(exceptionWrapContext);
var wrapResult = new WrapResult( context.Result = new ObjectResult(new WrapResult(
exceptionWrapContext.ErrorInfo.Code, exceptionWrapContext.ErrorInfo.Code,
exceptionWrapContext.ErrorInfo.Message, exceptionWrapContext.ErrorInfo.Message,
exceptionWrapContext.ErrorInfo.Details); exceptionWrapContext.ErrorInfo.Details));
context.Result = new ObjectResult(wrapResult);
context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true"); context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true");
context.HttpContext.Response.StatusCode = (int)wrapOptions.HttpStatusCode; context.HttpContext.Response.StatusCode = (int)wrapOptions.HttpStatusCode;
}
context.Exception = null; //Handled! context.Exception = null; //Handled!
} }

6
aspnet-core/modules/open-api/LINGYUN.Abp.OpenApi.Authorization/LINGYUN/Abp/OpenApi/Authorization/OpenApiAuthorizationService.cs

@ -175,7 +175,11 @@ namespace LINGYUN.Abp.OpenApi.Authorization
protected virtual async Task Unauthorized(HttpContext context, BusinessException exception) protected virtual async Task Unauthorized(HttpContext context, BusinessException exception)
{ {
var errorInfoConverter = context.RequestServices.GetRequiredService<IExceptionToErrorInfoConverter>(); var errorInfoConverter = context.RequestServices.GetRequiredService<IExceptionToErrorInfoConverter>();
var errorInfo = errorInfoConverter.Convert(exception, false); var errorInfo = errorInfoConverter.Convert(exception, options =>
{
options.SendExceptionsDetailsToClients = false;
options.SendStackTraceToClients = false;
});
var exceptionWrapHandlerFactory = context.RequestServices.GetRequiredService<IExceptionWrapHandlerFactory>(); var exceptionWrapHandlerFactory = context.RequestServices.GetRequiredService<IExceptionWrapHandlerFactory>();
var exceptionWrapContext = new ExceptionWrapContext( var exceptionWrapContext = new ExceptionWrapContext(

1
aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/LY.MicroService.RealtimeMessage.HttpApi.Host.csproj

@ -43,7 +43,6 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\modules\auditing\LINGYUN.Abp.AuditLogging.Elasticsearch\LINGYUN.Abp.AuditLogging.Elasticsearch.csproj" /> <ProjectReference Include="..\..\modules\auditing\LINGYUN.Abp.AuditLogging.Elasticsearch\LINGYUN.Abp.AuditLogging.Elasticsearch.csproj" />
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.AspNetCore.HttpOverrides\LINGYUN.Abp.AspNetCore.HttpOverrides.csproj" /> <ProjectReference Include="..\..\modules\common\LINGYUN.Abp.AspNetCore.HttpOverrides\LINGYUN.Abp.AspNetCore.HttpOverrides.csproj" />
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json\LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json.csproj" />
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.Data.DbMigrator\LINGYUN.Abp.Data.DbMigrator.csproj" /> <ProjectReference Include="..\..\modules\common\LINGYUN.Abp.Data.DbMigrator\LINGYUN.Abp.Data.DbMigrator.csproj" />
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Notifications\LINGYUN.Abp.ExceptionHandling.Notifications.csproj" /> <ProjectReference Include="..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Notifications\LINGYUN.Abp.ExceptionHandling.Notifications.csproj" />
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.Hangfire.Dashboard\LINGYUN.Abp.Hangfire.Dashboard.csproj" /> <ProjectReference Include="..\..\modules\common\LINGYUN.Abp.Hangfire.Dashboard\LINGYUN.Abp.Hangfire.Dashboard.csproj" />

2
aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Properties/launchSettings.json

@ -11,7 +11,7 @@
"LY.MicroService.RealtimeMessage.HttpApi.Host": { "LY.MicroService.RealtimeMessage.HttpApi.Host": {
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true, "dotnetRunMessages": true,
"launchBrowser": true, "launchBrowser": false,
"applicationUrl": "http://127.0.0.1:30020", "applicationUrl": "http://127.0.0.1:30020",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"

16
aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.Configure.cs

@ -20,6 +20,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Text.Unicode; using System.Text.Unicode;
using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.AspNetCore.Auditing; using Volo.Abp.AspNetCore.Auditing;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
@ -273,6 +274,21 @@ public partial class RealtimeMessageHttpApiHostModule
options.Authority = configuration["AuthServer:Authority"]; options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = false; options.RequireHttpsMetadata = false;
options.Audience = configuration["AuthServer:ApiName"]; options.Audience = configuration["AuthServer:ApiName"];
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/signalr-hubs")))
{
// Read the token out of the query string
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
}); });
if (!isDevelopment) if (!isDevelopment)

4
aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.cs

@ -1,6 +1,5 @@
using Hangfire; using Hangfire;
using LINGYUN.Abp.AspNetCore.HttpOverrides; using LINGYUN.Abp.AspNetCore.HttpOverrides;
using LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json;
using LINGYUN.Abp.AuditLogging.Elasticsearch; using LINGYUN.Abp.AuditLogging.Elasticsearch;
using LINGYUN.Abp.BackgroundJobs.Hangfire; using LINGYUN.Abp.BackgroundJobs.Hangfire;
using LINGYUN.Abp.Data.DbMigrator; using LINGYUN.Abp.Data.DbMigrator;
@ -61,7 +60,6 @@ namespace LY.MicroService.RealtimeMessage
typeof(AbpNotificationsSignalRModule), typeof(AbpNotificationsSignalRModule),
typeof(AbpNotificationsWeChatMiniProgramModule), typeof(AbpNotificationsWeChatMiniProgramModule),
typeof(AbpNotificationsExceptionHandlingModule), typeof(AbpNotificationsExceptionHandlingModule),
typeof(AbpAspNetCoreSignalRProtocolJsonModule),
typeof(AbpCAPEventBusModule), typeof(AbpCAPEventBusModule),
typeof(AbpDbFinderMultiTenancyModule), typeof(AbpDbFinderMultiTenancyModule),
typeof(AbpCachingStackExchangeRedisModule), typeof(AbpCachingStackExchangeRedisModule),
@ -112,8 +110,6 @@ namespace LY.MicroService.RealtimeMessage
app.UseRouting(); app.UseRouting();
// 跨域 // 跨域
app.UseCors(DefaultCorsPolicyName); app.UseCors(DefaultCorsPolicyName);
app.UseSignalRJwtToken();
app.UseHangfireAuthorication();
// 认证 // 认证
app.UseAuthentication(); app.UseAuthentication();
app.UseAbpClaimsMap(); app.UseAbpClaimsMap();

2
gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/.gitignore

@ -10,6 +10,8 @@
# User-specific files (MonoDevelop/Xamarin Studio) # User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs *.userprefs
ocelot.Production.json
# Build results # Build results
[Dd]ebug/ [Dd]ebug/
[Dd]ebugPublic/ [Dd]ebugPublic/

2
gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.Internal.ApiGateway/Dockerfile

@ -1,4 +1,4 @@
FROM mcr.microsoft.com/dotnet/aspnet:5.0 FROM mcr.microsoft.com/dotnet/aspnet:6.0
LABEL maintainer="colin.in@foxmail.com" LABEL maintainer="colin.in@foxmail.com"
WORKDIR /app WORKDIR /app

34
gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.Internal.ApiGateway/ocelot.Development.json

@ -1044,7 +1044,7 @@
"Key": "assignables-notifilers" "Key": "assignables-notifilers"
}, },
{ {
"DownstreamPathTemplate": "/api/my-notifilers/{everything}", "DownstreamPathTemplate": "/api/my-notifilers",
"DownstreamScheme": "http", "DownstreamScheme": "http",
"DownstreamHostAndPorts": [ "DownstreamHostAndPorts": [
{ {
@ -1052,7 +1052,37 @@
"Port": 30020 "Port": 30020
} }
], ],
"UpstreamPathTemplate": "/api/my-notifilers/{everything}", "UpstreamPathTemplate": "/api/my-notifilers",
"UpstreamHttpMethod": [ "GET" ],
"LoadBalancerOptions": {
"Type": "RoundRobin"
},
"RateLimitOptions": {
"ClientWhitelist": [],
"EnableRateLimiting": true,
"Period": "1s",
"PeriodTimespan": 1,
"Limit": 5
},
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 10,
"DurationOfBreak": 1000,
"TimeoutValue": 10000
},
"HttpHandlerOptions": {
"UseTracing": true
}
},
{
"DownstreamPathTemplate": "/api/my-notifilers/{id}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "127.0.0.1",
"Port": 30020
}
],
"UpstreamPathTemplate": "/api/my-notifilers/{id}",
"UpstreamHttpMethod": [ "UpstreamHttpMethod": [
"GET", "GET",
"POST", "POST",

61
gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.Internal.ApiGateway/ocelot.messages.json

@ -1,6 +1,6 @@
{ {
"Routes": [ "Routes": [
// // ܶ˵
{ {
"DownstreamPathTemplate": "/api/abp/application-configuration", "DownstreamPathTemplate": "/api/abp/application-configuration",
"DownstreamScheme": "http", "DownstreamScheme": "http",
@ -26,7 +26,7 @@
}, },
"Key": "messages-configuration" "Key": "messages-configuration"
}, },
// API // ̬ܶAPI˵
{ {
"DownstreamPathTemplate": "/api/abp/api-definition", "DownstreamPathTemplate": "/api/abp/api-definition",
"DownstreamScheme": "http", "DownstreamScheme": "http",
@ -52,7 +52,7 @@
}, },
"Key": "messages-api-definition" "Key": "messages-api-definition"
}, },
// // ʱͨѶ
{ {
"DownstreamPathTemplate": "/api/im/{everything}", "DownstreamPathTemplate": "/api/im/{everything}",
"DownstreamScheme": "http", "DownstreamScheme": "http",
@ -83,7 +83,7 @@
"UseTracing": true "UseTracing": true
} }
}, },
// Hangfire // Hangfire DZ
{ {
"DownstreamPathTemplate": "/hangfire/{everything}", "DownstreamPathTemplate": "/hangfire/{everything}",
"DownstreamScheme": "http", "DownstreamScheme": "http",
@ -114,7 +114,7 @@
"UseTracing": true "UseTracing": true
} }
}, },
// // û
{ {
"DownstreamPathTemplate": "/api/my-subscribes/{everything}", "DownstreamPathTemplate": "/api/my-subscribes/{everything}",
"DownstreamScheme": "http", "DownstreamScheme": "http",
@ -145,7 +145,7 @@
"UseTracing": true "UseTracing": true
} }
}, },
// // ûб
{ {
"DownstreamPathTemplate": "/api/my-subscribes/all", "DownstreamPathTemplate": "/api/my-subscribes/all",
"DownstreamScheme": "http", "DownstreamScheme": "http",
@ -178,7 +178,7 @@
"Priority": 99, "Priority": 99,
"Key": "my-subscribes" "Key": "my-subscribes"
}, },
// // û֪ͨ
{ {
"DownstreamPathTemplate": "/api/my-notifilers/assignables", "DownstreamPathTemplate": "/api/my-notifilers/assignables",
"DownstreamScheme": "http", "DownstreamScheme": "http",
@ -211,9 +211,9 @@
"Priority": 99, "Priority": 99,
"Key": "assignables-notifilers" "Key": "assignables-notifilers"
}, },
// // û֪ͨ
{ {
"DownstreamPathTemplate": "/api/my-notifilers/{everything}", "DownstreamPathTemplate": "/api/my-notifilers",
"DownstreamScheme": "http", "DownstreamScheme": "http",
"DownstreamHostAndPorts": [ "DownstreamHostAndPorts": [
{ {
@ -221,8 +221,43 @@
"Port": 30020 "Port": 30020
} }
], ],
"UpstreamPathTemplate": "/api/my-notifilers/{everything}", "UpstreamPathTemplate": "/api/my-notifilers",
"UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE" ], "UpstreamHttpMethod": [ "GET" ],
"LoadBalancerOptions": {
"Type": "RoundRobin"
},
"RateLimitOptions": {
"ClientWhitelist": [],
"EnableRateLimiting": true,
"Period": "1s",
"PeriodTimespan": 1,
"Limit": 5
},
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 10,
"DurationOfBreak": 1000,
"TimeoutValue": 10000
},
"HttpHandlerOptions": {
"UseTracing": true
}
},
{
"DownstreamPathTemplate": "/api/my-notifilers/{id}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "127.0.0.1",
"Port": 30020
}
],
"UpstreamPathTemplate": "/api/my-notifilers/{id}",
"UpstreamHttpMethod": [
"GET",
"POST",
"PUT",
"DELETE"
],
"LoadBalancerOptions": { "LoadBalancerOptions": {
"Type": "RoundRobin" "Type": "RoundRobin"
}, },
@ -242,7 +277,7 @@
"UseTracing": true "UseTracing": true
} }
}, },
// API // API ĵ
{ {
"DownstreamPathTemplate": "/swagger/v1/swagger.json", "DownstreamPathTemplate": "/swagger/v1/swagger.json",
"DownstreamScheme": "http", "DownstreamScheme": "http",
@ -273,7 +308,7 @@
"UseTracing": true "UseTracing": true
} }
}, },
// 线 //
{ {
"DownstreamPathTemplate": "/signalr-hubs/{everything}", "DownstreamPathTemplate": "/signalr-hubs/{everything}",
"DownstreamScheme": "ws", "DownstreamScheme": "ws",

Loading…
Cancel
Save