├── .dockerignore
├── .gen
├── generate_protos.bat
├── generate_protos_core.bat
├── generate_protos_core_genelib.bat
└── generate_remark.txt
├── .gitattributes
├── .gitignore
├── README.md
├── core-grpc-h2.sln
├── core-grpc.sln
├── docker-compose.ci.build.yml
├── docker-compose.dcproj
├── docker-compose.override.yml
├── docker-compose.yml
├── sample
├── cross
│ ├── Overt.GrpcExampleCrossPlat.Service.Grpc
│ │ ├── ClientManager.cs
│ │ ├── GrpcExample.cs
│ │ ├── GrpcExampleGrpc.cs
│ │ ├── Overt.GrpcExampleCrossPlat.Service.Grpc.csproj
│ │ ├── coreconfigs
│ │ │ ├── clientsettings.json
│ │ │ ├── consulsettings.json
│ │ │ └── grpcsettings.json
│ │ └── fmconfigs
│ │ │ ├── Client.config
│ │ │ ├── Consul.config
│ │ │ └── Server.config
│ └── Overt.GrpcExampleCrossPlat.Service
│ │ ├── Dockerfile
│ │ ├── HostedService
│ │ └── GrpcExampleHostedService.cs
│ │ ├── Impl
│ │ └── GrpcExampleServiceImpl.cs
│ │ ├── Overt.GrpcExampleCrossPlat.Service.csproj
│ │ ├── Program.cs
│ │ ├── Properties
│ │ └── PublishProfiles
│ │ │ └── FolderProfile.pubxml
│ │ ├── Tracer
│ │ └── ConsoleTracer.cs
│ │ ├── appsettings.json
│ │ └── dllconfigs
│ │ └── consulsettings.json
├── grpc.net
│ ├── Overt.GrpcExample.Client
│ │ ├── Overt.GrpcExample.Client.csproj
│ │ ├── Program.cs
│ │ └── dllconfigs
│ │ │ ├── Overt.GrpcExample.Service.Grpc.dll.json
│ │ │ ├── Overt.GrpcExample1.Service.Grpc.dll.json
│ │ │ └── consulsettings.json
│ ├── Overt.GrpcExample.Service.Grpc
│ │ ├── GrpcExample.cs
│ │ ├── GrpcExampleGrpc.cs
│ │ ├── Overt.GrpcExample.Service.Grpc.csproj
│ │ ├── Protos
│ │ │ └── GrpcExample.proto
│ │ ├── coreconfigs
│ │ │ ├── clientsettings.json
│ │ │ ├── consulsettings.json
│ │ │ └── grpcsettings.json
│ │ └── fmconfigs
│ │ │ ├── Client.config
│ │ │ ├── Consul.config
│ │ │ └── Server.config
│ ├── Overt.GrpcExample.Service
│ │ ├── Dockerfile
│ │ ├── Overt.GrpcExample.Service.csproj
│ │ ├── Program.cs
│ │ ├── Properties
│ │ │ └── launchSettings.json
│ │ ├── Services
│ │ │ └── GrpcExampleService.cs
│ │ ├── Startup.cs
│ │ ├── appsettings.Development.json
│ │ ├── appsettings.json
│ │ └── dllconfigs
│ │ │ └── consulsettings.json
│ └── Overt.GrpcExample1.Service.Grpc
│ │ ├── GrpcExample1.cs
│ │ ├── GrpcExample1Grpc.cs
│ │ ├── Overt.GrpcExample1.Service.Grpc.csproj
│ │ ├── Protos
│ │ └── GrpcExample1.proto
│ │ ├── coreconfigs
│ │ ├── clientsettings.json
│ │ ├── consulsettings.json
│ │ └── grpcsettings.json
│ │ └── fmconfigs
│ │ ├── Client.config
│ │ ├── Consul.config
│ │ └── Server.config
├── net45
│ ├── Overt.GrpcExampleNet45.Client
│ │ ├── App.config
│ │ ├── Overt.GrpcExampleNet45.Client.csproj
│ │ ├── Program.cs
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ ├── Tracer
│ │ │ └── ConsoleTracer.cs
│ │ ├── dllconfigs
│ │ │ ├── Consul.config
│ │ │ └── Overt.GrpcExample.Service.Grpc.dll.config
│ │ └── packages.config
│ ├── Overt.GrpcExampleNet45.Service.Grpc
│ │ ├── ClientManager.cs
│ │ ├── GrpcExample.cs
│ │ ├── GrpcExampleGrpc.cs
│ │ ├── Overt.GrpcExampleNet45.Service.Grpc.csproj
│ │ ├── coreconfigs
│ │ │ ├── clientsettings.json
│ │ │ ├── consulsettings.json
│ │ │ └── grpcsettings.json
│ │ └── fmconfigs
│ │ │ ├── Client.config
│ │ │ ├── Consul.config
│ │ │ └── Server.config
│ └── Overt.GrpcExampleNet45.Service
│ │ ├── App.config
│ │ ├── AutofacContainer.cs
│ │ ├── Impl
│ │ └── GrpcExampleServiceImpl.cs
│ │ ├── InstallService.bat
│ │ ├── MainService.cs
│ │ ├── Overt.GrpcExampleNet45.Service.csproj
│ │ ├── Program.cs
│ │ ├── Properties
│ │ └── AssemblyInfo.cs
│ │ ├── Readme.txt
│ │ ├── StartService.bat
│ │ ├── StopService.bat
│ │ ├── Tracer
│ │ └── ConsoleTracer.cs
│ │ ├── UninstallService.bat
│ │ ├── dllconfigs
│ │ ├── Consul.config
│ │ └── Sodao.Log.nlog.config
│ │ └── packages.config
└── netcore
│ ├── Overt.GrpcExample.Application
│ ├── Constracts
│ │ └── IUserService.cs
│ ├── Overt.GrpcExample.Application.csproj
│ ├── ServiceCollectionExtensions.cs
│ └── Services
│ │ └── UserService.cs
│ ├── Overt.GrpcExample.Client
│ ├── ClientLoggerInterceptor.cs
│ ├── Overt.GrpcExample.Client.csproj
│ ├── Program.cs
│ ├── Properties
│ │ └── PublishProfiles
│ │ │ └── FolderProfile.pubxml
│ ├── Tracer
│ │ └── ConsoleTracer.cs
│ ├── appsettings.json
│ └── dllconfigs
│ │ ├── Overt.GrpcExample.Service.Grpc.dll.json
│ │ └── consulsettings.json
│ ├── Overt.GrpcExample.Domain
│ ├── Contracts
│ │ └── IUserRepository.cs
│ ├── Entities
│ │ └── UserEntity.cs
│ ├── Overt.GrpcExample.Domain.csproj
│ ├── Repositories
│ │ └── UserRepository.cs
│ └── ServiceCollectionExtensions.cs
│ ├── Overt.GrpcExample.Service.Grpc
│ ├── GrpcExample.cs
│ ├── GrpcExample.proto
│ ├── GrpcExample.proto.xml
│ ├── GrpcExampleGrpc.cs
│ ├── Overt.GrpcExample.Service.Grpc.csproj
│ ├── coreconfigs
│ │ ├── clientsettings.json
│ │ ├── consulsettings.json
│ │ └── grpcsettings.json
│ └── fmconfigs
│ │ ├── Client.config
│ │ ├── Consul.config
│ │ └── Server.config
│ └── Overt.GrpcExample.Service
│ ├── Dockerfile
│ ├── HostedService
│ └── GrpcExampleHostedService.cs
│ ├── Impl
│ └── GrpcExampleServiceImpl.cs
│ ├── Overt.GrpcExample.Service.csproj
│ ├── Program.cs
│ ├── Properties
│ └── PublishProfiles
│ │ └── FolderProfile.pubxml
│ ├── Tracer
│ └── ConsoleTracer.cs
│ ├── appsettings.json
│ └── dllconfigs
│ └── consulsettings.json
└── src
├── Overt.Core.Grpc.H2
├── Client
│ ├── ClientGenerate
│ │ ├── ChannelWrapper.cs
│ │ ├── GrpcClient.cs
│ │ ├── GrpcClientFactory.cs
│ │ ├── GrpcClientOptions.cs
│ │ └── Interface
│ │ │ ├── IGrpcClient.cs
│ │ │ └── IGrpcClientFactory.cs
│ ├── ClientTimespan.cs
│ ├── EndpointDiscovery
│ │ ├── IEndpointDiscovery.cs
│ │ ├── IPEndpointDiscovery.cs
│ │ └── StickyEndpointDiscovery.cs
│ ├── EndpointStrategy
│ │ ├── EndpointStrategy.cs
│ │ ├── IEndpointStrategy.cs
│ │ ├── IPEndpointStrategy.cs
│ │ ├── StickyEndpointStrategy.cs
│ │ └── StrategyFactory.cs
│ ├── Entity
│ │ └── Exitus.cs
│ ├── NET5_0_OR_GREATER
│ │ ├── Balancer
│ │ │ ├── RandomBalancer.cs
│ │ │ ├── RandomBalancerFactory.cs
│ │ │ └── RandomPicker.cs
│ │ └── Resolver
│ │ │ ├── InternalResolver.cs
│ │ │ └── InternalResolverFactory.cs
│ └── ServicePolicy
│ │ ├── ServiceBlackPolicy.cs
│ │ └── ServicePollingPolicy.cs
├── Config
│ ├── Consul
│ │ ├── ConsulServerSection.cs
│ │ └── ConsulServiceElement.cs
│ ├── Grpc
│ │ ├── Client
│ │ │ ├── GrpcClientSection.cs
│ │ │ ├── GrpcDiscoveryElement.cs
│ │ │ ├── GrpcEndpointElement.cs
│ │ │ └── GrpcServiceElement.cs
│ │ ├── Common
│ │ │ └── ConsulElement.cs
│ │ └── Service
│ │ │ ├── GrpcServerSection.cs
│ │ │ └── ServiceElement.cs
│ └── Util
│ │ ├── ConfigBuilder.cs
│ │ ├── Constants.cs
│ │ └── IPHelper.cs
├── GrpcServiceCollectionExtensions.cs
├── Overt.Core.Grpc.H2.csproj
├── Service
│ ├── ConsulRegister.cs
│ ├── ConsulTimespan.cs
│ ├── Entity
│ │ ├── Entry.cs
│ │ └── GrpcOptions.cs
│ ├── GrpcHostedService.cs
│ └── RegisterFactory.cs
└── dllconfigs
│ ├── clientsettings.json
│ ├── consulsettings.json
│ └── grpcsettings.json
└── Overt.Core.Grpc
├── Client
├── CallInvoker
│ ├── ClientCallInvoker.cs
│ ├── InterceptedServerCallInvoker.cs
│ └── ServerCallInvoker.cs
├── ClientGenerate
│ ├── GrpcClient.cs
│ ├── GrpcClientFactory.cs
│ ├── GrpcClientOptions.cs
│ └── Interface
│ │ ├── IGrpcClient.cs
│ │ └── IGrpcClientFactory.cs
├── ClientTimespan.cs
├── EndpointDiscovery
│ ├── IEndpointDiscovery.cs
│ ├── IPEndpointDiscovery.cs
│ └── StickyEndpointDiscovery.cs
├── EndpointStrategy
│ ├── EndpointStrategy.cs
│ ├── IEndpointStrategy.cs
│ └── StrategyFactory.cs
└── ServicePolicy
│ ├── ServiceBlackPolicy.cs
│ └── ServicePollingPolicy.cs
├── Config
├── Consul
│ ├── ConsulServerSection.cs
│ └── ConsulServiceElement.cs
├── Grpc
│ ├── Client
│ │ ├── GrpcClientSection.cs
│ │ ├── GrpcDiscoveryElement.cs
│ │ ├── GrpcEndpointElement.cs
│ │ ├── GrpcEndpointElementCollection.cs
│ │ └── GrpcServiceElement.cs
│ ├── Common
│ │ └── ConsulElement.cs
│ └── Service
│ │ ├── GrpcRegistryElement.cs
│ │ ├── GrpcServerSection.cs
│ │ └── ServiceElement.cs
└── Util
│ ├── ConfigBuilder.cs
│ ├── GrpcConstants.cs
│ └── IPHelper.cs
├── GrpcServiceCollectionExtensions.cs
├── Intercept
├── Handler
│ ├── InterceptedClientHandler.cs
│ └── InterceptedServerHandler.cs
├── InterceptExtensions.cs
├── Interceptor
│ ├── ClientTracerInterceptor.cs
│ └── ServerTracerInterceptor.cs
├── Streaming
│ ├── TracingAsyncClientStreamReader.cs
│ ├── TracingAsyncServerStreamReader.cs
│ ├── TracingClientStreamWriter.cs
│ └── TracingServerStreamWriter.cs
└── Tracer
│ ├── ClientMockTracer.cs
│ ├── IClientTracer.cs
│ ├── IServerTracer.cs
│ └── ServerMockTracer.cs
├── Manager
├── GrpcClientManager.cs
└── GrpcServiceManager.cs
├── Overt.Core.Grpc.csproj
├── Service
├── ConsulTimespan.cs
├── Entity
│ ├── Entry.cs
│ ├── Exitus.cs
│ └── GrpcOptions.cs
└── ServerRegister.cs
└── dllconfigs
├── framework
├── Client.config
├── Consul.config
└── Server.config
└── netstandard20
├── clientsettings.json
├── consulsettings.json
└── grpcsettings.json
/.dockerignore:
--------------------------------------------------------------------------------
1 | .dockerignore
2 | .env
3 | .git
4 | .gitignore
5 | .vs
6 | .vscode
7 | docker-compose.yml
8 | docker-compose.*.yml
9 | */bin
10 | */obj
11 | !obj/Docker/publish/*
12 | !obj/Docker/empty/
13 |
--------------------------------------------------------------------------------
/.gen/generate_protos.bat:
--------------------------------------------------------------------------------
1 | @rem Copyright 2016 gRPC authors.
2 | @rem
3 | @rem Licensed under the Apache License, Version 2.0 (the "License");
4 | @rem you may not use this file except in compliance with the License.
5 | @rem You may obtain a copy of the License at
6 | @rem
7 | @rem http://www.apache.org/licenses/LICENSE-2.0
8 | @rem
9 | @rem Unless required by applicable law or agreed to in writing, software
10 | @rem distributed under the License is distributed on an "AS IS" BASIS,
11 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | @rem See the License for the specific language governing permissions and
13 | @rem limitations under the License.
14 |
15 | @rem Generate the C# code for .proto files
16 |
17 | setlocal
18 |
19 | @rem enter this directory
20 | cd /d %~dp0
21 |
22 | set TOOLS_PATH=packages\Grpc.Tools.1.6.1\tools\windows_x64
23 |
24 | %TOOLS_PATH%\protoc.exe --csharp_out src/Overt.GrpcService.Library/Generate src/Overt.GrpcService.Library/GrpcService.proto --grpc_out src/Overt.GrpcService.Library/Generate --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe
25 |
26 | endlocal
27 |
--------------------------------------------------------------------------------
/.gen/generate_protos_core.bat:
--------------------------------------------------------------------------------
1 | @rem Copyright 2016 gRPC authors.
2 | @rem
3 | @rem Licensed under the Apache License, Version 2.0 (the "License");
4 | @rem you may not use this file except in compliance with the License.
5 | @rem You may obtain a copy of the License at
6 | @rem
7 | @rem http://www.apache.org/licenses/LICENSE-2.0
8 | @rem
9 | @rem Unless required by applicable law or agreed to in writing, software
10 | @rem distributed under the License is distributed on an "AS IS" BASIS,
11 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | @rem See the License for the specific language governing permissions and
13 | @rem limitations under the License.
14 |
15 | @rem Generate the C# code for .proto files
16 |
17 | setlocal
18 |
19 | @rem enter this directory
20 | cd /d %~dp0
21 |
22 | set TOOLS_PATH=C:\Users\Administrator\.nuget\packages\grpc.tools\1.7.1\tools\windows_x64
23 |
24 | %TOOLS_PATH%\protoc.exe --csharp_out "src/2. DotNetCore/Overt.GrpcService.Library/Generate" "src/2. DotNetCore/Overt.GrpcService.Library/GrpcService.proto" --grpc_out "src/2. DotNetCore/Overt.GrpcService.Library/Generate" --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe
25 |
26 | endlocal
27 |
--------------------------------------------------------------------------------
/.gen/generate_protos_core_genelib.bat:
--------------------------------------------------------------------------------
1 | @rem Copyright 2016 gRPC authors.
2 | @rem
3 | @rem Licensed under the Apache License, Version 2.0 (the "License");
4 | @rem you may not use this file except in compliance with the License.
5 | @rem You may obtain a copy of the License at
6 | @rem
7 | @rem http://www.apache.org/licenses/LICENSE-2.0
8 | @rem
9 | @rem Unless required by applicable law or agreed to in writing, software
10 | @rem distributed under the License is distributed on an "AS IS" BASIS,
11 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | @rem See the License for the specific language governing permissions and
13 | @rem limitations under the License.
14 |
15 | @rem Generate the C# code for .proto files
16 |
17 | setlocal
18 |
19 | @rem enter this directory
20 | cd /d %~dp0
21 |
22 | set TOOLS_PATH=C:\Users\Administrator\.nuget\packages\grpc.tools\1.7.1\tools\windows_x64
23 |
24 | %TOOLS_PATH%\protoc.exe --csharp_out "src/2. DotNetCore/Overt.GrpcService.Generate/Generate" "src/2. DotNetCore/Overt.GrpcService.Generate/GrpcService.proto" --grpc_out "src/2. DotNetCore/Overt.GrpcService.Generate/Generate" --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe
25 |
26 | endlocal
27 |
--------------------------------------------------------------------------------
/.gen/generate_remark.txt:
--------------------------------------------------------------------------------
1 | 工具地址:packages\Grpc.Tools.1.0.0\tools\windows_x86\protoc.exe
2 | csharp模型文件存储目录:--csharp_out [grpc类文件的目录] [Grpc协议文件路径]
3 | csharp服务类文件存储目录:--grpc_out [grpc服务文件的目录]
4 | csharp插件路径:--plugin=protoc-gen-grpc=packages\Grpc.Tools.1.0.0\tools\windows_x86\grpc_csharp_plugin.exe
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/overtly/core-grpc/93049ec3908accda9d9c37d76878fe70a6e1ae10/.gitattributes
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #
2 | #ignore thumbnails created by windows
3 | Thumbs.db
4 | #Ignore files build by Visual Studio
5 | *.obj
6 | *.exe
7 | *.pdb
8 | *.user
9 | *.aps
10 | *.pch
11 | *.vspscc
12 | *_i.c
13 | *_p.c
14 | *.ncb
15 | *.suo
16 | *.tlb
17 | *.tlh
18 | *.bak
19 | *.cache
20 | *.ilk
21 | *.log
22 | [Bb]in
23 | [Dd]ebug*/
24 | *.sbr
25 | obj/
26 |
27 | [Rr]elease*/
28 | _ReSharper*/
29 | [Tt]est[Rr]esult*
30 | packages
31 | /.vs
32 |
--------------------------------------------------------------------------------
/docker-compose.ci.build.yml:
--------------------------------------------------------------------------------
1 | version: '3.4'
2 |
3 | services:
4 | ci-build:
5 | image: microsoft/aspnetcore-build:1.0-2.0
6 | volumes:
7 | - .:/src
8 | working_dir: /src
9 | command: /bin/bash -c "dotnet restore ./Overt.GrpcService.Core.sln && dotnet publish ./Overt.GrpcService.Core.sln -c Release -o ./obj/Docker/publish"
10 |
--------------------------------------------------------------------------------
/docker-compose.dcproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2.1
5 | Linux
6 | 94acf970-0768-4411-9bf4-8ca2efd73a3c
7 |
8 |
9 |
10 | docker-compose.yml
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/docker-compose.override.yml:
--------------------------------------------------------------------------------
1 | version: '3.4'
2 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.4'
2 |
3 | services:
4 | sodao.grpcexample.service:
5 | image: sodao.grpcexample.service
6 | build:
7 | context: .
8 | dockerfile: src/Overt.GrpcExample.Service/Dockerfile
9 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service.Grpc/ClientManager.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Overt.Core.Grpc;
3 | using Overt.Core.Grpc.Intercept;
4 | using System;
5 | using System.Collections.Concurrent;
6 | using System.IO;
7 | using __GrpcService = Overt.GrpcExample.Service.Grpc.GrpcExampleService;
8 | namespace Overt.GrpcExample.Service.Grpc
9 | {
10 | #if NET45 || NET46 || NET47
11 | public class ClientManager
12 | {
13 | public static IClientTracer Tracer { get; set; }
14 | public static string ConfigPath { get; set; } = "dllconfigs/Overt.GrpcExample.Service.Grpc.dll.config";
15 | public static __GrpcService.GrpcExampleServiceClient Instance
16 | {
17 | get
18 | {
19 | var configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigPath);
20 | return GrpcClientManager<__GrpcService.GrpcExampleServiceClient>.Get(configPath, Tracer);
21 | }
22 | }
23 | private static readonly ConcurrentDictionary configMap = new ConcurrentDictionary();
24 | public static void Configure(string configPath) { configMap.AddOrUpdate(typeof(T), configPath, (t, s) => configPath); }
25 | public static string GetConfigure() { if (configMap.TryGetValue(typeof(T), out string configPath)) return configPath; return ConfigPath; }
26 | }
27 | public class ClientManager : ClientManager where T : ClientBase
28 | {
29 | public static new T Instance
30 | {
31 | get
32 | {
33 | var configPath = GetConfigure();
34 | var abConfigPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configPath);
35 | return GrpcClientManager.Get(abConfigPath, Tracer);
36 | }
37 | }
38 | }
39 | #endif
40 | }
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service.Grpc/Overt.GrpcExampleCrossPlat.Service.Grpc.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net45;net46;netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service.Grpc/coreconfigs/clientsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcClient": {
3 | "Service": {
4 | "Name": "",
5 | "MaxRetry": 0,
6 | "Discovery": {
7 | "EndPoints": [
8 | {
9 | "Host": "127.0.0.1",
10 | "Port": 0
11 | }
12 | ],
13 | "Consul": {
14 | "Path": "consulsettings.json"
15 | }
16 | }
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service.Grpc/coreconfigs/consulsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConsulServer": {
3 | "Service": {
4 | "Address": "http://127.0.0.1:8500"
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service.Grpc/coreconfigs/grpcsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcServer": {
3 | "Service": {
4 | "Name": "grpcservice",
5 | "Host": "",
6 | "Port": 10001,
7 | "Consul": {
8 | "Path": "dllconfigs/consulsettings.json"
9 | }
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service.Grpc/fmconfigs/Client.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service.Grpc/fmconfigs/Consul.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service.Grpc/fmconfigs/Server.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM microsoft/dotnet:2.0-runtime AS base
2 | WORKDIR /app
3 |
4 | FROM microsoft/dotnet:2.0-sdk AS build
5 | WORKDIR /src
6 | COPY *.sln ./
7 | COPY src/Overt.GrpcExampleCrossPlat.Service/Overt.GrpcExampleCrossPlat.Service.csproj src/Overt.GrpcExampleCrossPlat.Service/
8 | COPY src/Overt.GrpcExample.Application/Overt.GrpcExample.Application.csproj src/Overt.GrpcExample.Application/
9 | COPY src/Overt.GrpcExample.Domain/Overt.GrpcExample.Domain.csproj src/Overt.GrpcExample.Domain/
10 | COPY src/Overt.GrpcExampleCrossPlat.Service.Grpc/Overt.GrpcExampleCrossPlat.Service.Grpc.csproj src/Overt.GrpcExampleCrossPlat.Service.Grpc/
11 | COPY src/Overt.Core.Grpc/Overt.Core.Grpc.csproj src/Overt.Core.Grpc/
12 | RUN dotnet restore
13 | COPY . .
14 | WORKDIR /src/src/Overt.GrpcExampleCrossPlat.Service
15 | RUN dotnet build -c Release -o /app
16 |
17 | FROM build AS publish
18 | RUN dotnet publish -c Release -o /app
19 |
20 | FROM base AS final
21 | WORKDIR /app
22 | COPY --from=publish /app .
23 | ENTRYPOINT ["dotnet", "Overt.GrpcExampleCrossPlat.Service.dll"]
24 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service/HostedService/GrpcExampleHostedService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Hosting;
2 | using Overt.Core.Grpc;
3 | using Overt.Core.Grpc.Intercept;
4 | using Overt.GrpcExample.Service.Grpc;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace Overt.GrpcExampleCrossPlat.Service
9 | {
10 | public class GrpcExampleHostedService : IHostedService
11 | {
12 | readonly IServerTracer _tracer;
13 | readonly GrpcExampleService.GrpcExampleServiceBase _grpcServiceBase;
14 | public GrpcExampleHostedService(
15 | IServerTracer tracer,
16 | GrpcExampleService.GrpcExampleServiceBase grpcServiceBase)
17 | {
18 | _tracer = tracer;
19 | _grpcServiceBase = grpcServiceBase;
20 | }
21 |
22 | public Task StartAsync(CancellationToken cancellationToken)
23 | {
24 | return Task.Factory.StartNew(() =>
25 | {
26 | GrpcServiceManager.Start(GrpcExampleService.BindService(_grpcServiceBase), (grpcOptions) =>
27 | {
28 | grpcOptions.Tracer = _tracer;
29 | grpcOptions.GenServiceId = null;
30 | });
31 | }, cancellationToken);
32 | }
33 |
34 | public Task StopAsync(CancellationToken cancellationToken)
35 | {
36 | return Task.Factory.StartNew(() =>
37 | {
38 | GrpcServiceManager.Stop();
39 | }, cancellationToken);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service/Impl/GrpcExampleServiceImpl.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Microsoft.Extensions.Configuration;
3 | using Overt.GrpcExample.Service.Grpc;
4 | using System;
5 | using System.Linq;
6 | using System.Net;
7 | using System.Threading.Tasks;
8 |
9 | namespace Overt.GrpcExampleCrossPlat.Service
10 | {
11 | public class GrpcExampleServiceImpl : GrpcExampleService.GrpcExampleServiceBase
12 | {
13 | IServiceProvider _provider;
14 | IConfiguration _configuration;
15 | public GrpcExampleServiceImpl(IServiceProvider provider, IConfiguration configuration)
16 | {
17 | _provider = provider;
18 | _configuration = configuration;
19 | }
20 |
21 | public override Task GetName(RequestModel request, ServerCallContext context)
22 | {
23 | ResponseModel model = null;
24 | if (request == null || request.Key == null)
25 | return Task.FromResult(model);
26 |
27 | model = new ResponseModel() { };
28 | return Task.FromResult(model);
29 | }
30 |
31 | public override Task Ask(AskRequest request, ServerCallContext context)
32 | {
33 | var v = _configuration.GetSection("GrpcServer").GetSection("Service").GetValue("Port");
34 |
35 | var model = new AskResponse() { Content = $"Ask: {request.Key}: {DateTime.Now.ToString()} -- configuration: {v} --- address: {string.Join(",", Dns.GetHostEntry(Dns.GetHostName()).AddressList.Select(oo => oo.ToString()))}" };
36 | return Task.FromResult(model);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service/Overt.GrpcExampleCrossPlat.Service.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Always
20 |
21 |
22 | Always
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Configuration;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using Microsoft.Extensions.Hosting;
4 | using Overt.Core.Grpc;
5 | using Overt.GrpcExample.Service.Grpc;
6 | using Overt.GrpcExampleCrossPlat.Service.Tracer;
7 |
8 | namespace Overt.GrpcExampleCrossPlat.Service
9 | {
10 | class Program
11 | {
12 | static void Main(string[] args)
13 | {
14 | var host = new HostBuilder()
15 | .UseConsoleLifetime() //使用控制台生命周期
16 | .ConfigureAppConfiguration((context, configurationBuilder) =>
17 | {
18 | configurationBuilder
19 | .AddJsonFile("appsettings.json", optional: true); //约定使用appsettings.json作为应用程序配置文件
20 | })
21 | .ConfigureServices(ConfigureServices)
22 | .Build();
23 |
24 | host.Run();
25 | }
26 |
27 | ///
28 | /// 通用DI注入
29 | ///
30 | ///
31 | ///
32 | private static void ConfigureServices(HostBuilderContext context, IServiceCollection services)
33 | {
34 | services.AddTransient();
35 | services.AddTransient();
36 |
37 | // tracer
38 | services.AddGrpcTracer();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service/Properties/PublishProfiles/FolderProfile.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 | FileSystem
9 | Release
10 | netcoreapp2.0
11 | bin\Release\PublishOutput
12 |
13 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service/Tracer/ConsoleTracer.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Overt.Core.Grpc.Intercept;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace Overt.GrpcExampleCrossPlat.Service.Tracer
8 | {
9 | public class ConsoleTracer : IServerTracer
10 | {
11 | public string ServiceName { get; set; }
12 |
13 | public void Exception(ServerCallContext context, Exception exception, TRequest request = default(TRequest))
14 | {
15 | Console.WriteLine("some exception");
16 | }
17 |
18 | public void Finish(ServerCallContext context)
19 | {
20 | Console.WriteLine("finished request");
21 | }
22 |
23 | public void Request(TRequest request, ServerCallContext context)
24 | {
25 | Console.WriteLine("start request");
26 | }
27 |
28 | public void Response(TResponse response, ServerCallContext context)
29 | {
30 | Console.WriteLine("end response");
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConnectionStrings": {
3 | "master": "Server=10.0.17.10;Database=JuketoolCore;uid=juketool;password=abc@123;"
4 | },
5 | "GrpcServer": {
6 | "Service": {
7 | "Name": "OvertGrpcExampleService",
8 | "Port": 10004,
9 | "Consul": {
10 | "Path": ""
11 | }
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/sample/cross/Overt.GrpcExampleCrossPlat.Service/dllconfigs/consulsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConsulServer": {
3 | "Service": {
4 | "Address": "http://consul.g.lan"
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Client/Overt.GrpcExample.Client.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net5.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Always
22 |
23 |
24 | Always
25 |
26 |
27 | Always
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Client/dllconfigs/Overt.GrpcExample.Service.Grpc.dll.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcClient": {
3 | "Service": {
4 | "Name": "OvertGrpcExampleService",
5 | "Scheme": "",
6 | "Discovery": {
7 | "Consul": {
8 | "Path": "dllconfigs/consulsettings.json"
9 | }
10 | //"EndPoints": [
11 | // {
12 | // "Host": "127.0.0.1",
13 | // "Port": 5002
14 | // }
15 | //]
16 | }
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Client/dllconfigs/Overt.GrpcExample1.Service.Grpc.dll.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/overtly/core-grpc/93049ec3908accda9d9c37d76878fe70a6e1ae10/sample/grpc.net/Overt.GrpcExample.Client/dllconfigs/Overt.GrpcExample1.Service.Grpc.dll.json
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Client/dllconfigs/consulsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConsulServer": {
3 | "Service": {
4 | "Address": "http://192.168.10.10:8500"
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service.Grpc/Overt.GrpcExample.Service.Grpc.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service.Grpc/Protos/GrpcExample.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package Overt.GrpcExample.Service.Grpc;
3 |
4 | message RequestModel{
5 | string key = 1;
6 | }
7 |
8 | message ResponseModel{
9 | string name = 1;
10 | }
11 |
12 |
13 | message AskRequest{
14 | int32 Cate = 1;
15 | string Key = 2;
16 | repeated int32 samples = 3;
17 | }
18 |
19 | message AskResponse{
20 | string Content = 1;
21 | }
22 |
23 | service GrpcExampleService {
24 |
25 | rpc GetName(RequestModel) returns (ResponseModel){}
26 |
27 | rpc Ask(AskRequest) returns (AskResponse){}
28 |
29 | }
30 |
31 | service GrpcExampleService1 {
32 |
33 | rpc GetName(RequestModel) returns (ResponseModel){}
34 |
35 | rpc Ask(AskRequest) returns (AskResponse){}
36 |
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service.Grpc/coreconfigs/clientsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcClient": {
3 | "Service": {
4 | "Name": "",
5 | "MaxRetry": 0,
6 | "Discovery": {
7 | "EndPoints": [
8 | {
9 | "Host": "127.0.0.1",
10 | "Port": 0
11 | }
12 | ],
13 | "Consul": {
14 | "Path": "dllconfigs/consulsettings.json"
15 | }
16 | }
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service.Grpc/coreconfigs/consulsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConsulServer": {
3 | "Service": {
4 | "Address": "http://127.0.0.1:8500"
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service.Grpc/coreconfigs/grpcsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcServer": {
3 | "Service": {
4 | "Name": "grpcservice",
5 | "Host": "",
6 | "Port": 10001,
7 | "Consul": {
8 | "Path": "dllconfigs/consulsettings.json"
9 | }
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service.Grpc/fmconfigs/Client.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service.Grpc/fmconfigs/Consul.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service.Grpc/fmconfigs/Server.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service/Dockerfile:
--------------------------------------------------------------------------------
1 | #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
2 |
3 | FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
4 | WORKDIR /app
5 | EXPOSE 80
6 | EXPOSE 443
7 |
8 | FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
9 | WORKDIR /src
10 | COPY ["sample/grpc.net/Overt.GrpcExample.Service/Overt.GrpcExample.Service.csproj", "sample/grpc.net/Overt.GrpcExample.Service/"]
11 | RUN dotnet restore "sample/grpc.net/Overt.GrpcExample.Service/Overt.GrpcExample.Service.csproj"
12 | COPY . .
13 | WORKDIR "/src/sample/grpc.net/Overt.GrpcExample.Service"
14 | RUN dotnet build "Overt.GrpcExample.Service.csproj" -c Release -o /app/build
15 |
16 | FROM build AS publish
17 | RUN dotnet publish "Overt.GrpcExample.Service.csproj" -c Release -o /app/publish
18 |
19 | FROM base AS final
20 | WORKDIR /app
21 | COPY --from=publish /app/publish .
22 | ENTRYPOINT ["dotnet", "Overt.GrpcExample.Service.dll"]
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service/Overt.GrpcExample.Service.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | 17ea2037-572e-4759-ac3a-88073b3db458
6 | Linux
7 | ..\..\..
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Always
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Hosting;
2 | using Microsoft.Extensions.Hosting;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 |
9 | namespace Overt.GrpcExample.Service
10 | {
11 | public class Program
12 | {
13 | public static void Main(string[] args)
14 | {
15 | CreateHostBuilder(args).Build().Run();
16 | }
17 |
18 | // Additional configuration is required to successfully run gRPC on macOS.
19 | // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
20 | public static IHostBuilder CreateHostBuilder(string[] args) =>
21 | Host.CreateDefaultBuilder(args)
22 | .ConfigureWebHostDefaults(webBuilder =>
23 | {
24 | webBuilder.UseStartup().UseUrls("http://*:5002");
25 | });
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Overt.GrpcExample.Service": {
4 | "commandName": "Project",
5 | "environmentVariables": {
6 | "ASPNETCORE_ENVIRONMENT": "Development"
7 | },
8 | "applicationUrl": "https://localhost:5001"
9 | },
10 | "Docker": {
11 | "commandName": "Docker",
12 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
13 | "publishAllPorts": true,
14 | "useSSL": true
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service/Services/GrpcExampleService.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Microsoft.Extensions.Configuration;
3 | using Overt.GrpcExample.Service.Grpc;
4 | using System;
5 | using System.Linq;
6 | using System.Net;
7 | using System.Threading.Tasks;
8 |
9 | namespace Overt.GrpcExample.Service
10 | {
11 | public class GrpcExampleServiceImpl : Grpc.GrpcExampleService.GrpcExampleServiceBase
12 | {
13 | IServiceProvider _provider;
14 | IConfiguration _configuration;
15 | public GrpcExampleServiceImpl(IServiceProvider provider, IConfiguration configuration)
16 | {
17 | _provider = provider;
18 | _configuration = configuration;
19 | }
20 |
21 | public override Task GetName(RequestModel request, ServerCallContext context)
22 | {
23 | ResponseModel model = null;
24 | if (request == null || request.Key == null)
25 | return Task.FromResult(model);
26 |
27 | model = new ResponseModel() { };
28 | return Task.FromResult(model);
29 | }
30 |
31 | public override Task Ask(Grpc.AskRequest request, ServerCallContext context)
32 | {
33 | var v = _configuration.GetSection("GrpcServer").GetSection("Service").GetValue("Port");
34 |
35 | var model = new AskResponse() { Content = $"Ask: {request.Key}: {DateTime.Now.ToString()} -- configuration: {v} --- address: {string.Join(",", Dns.GetHostEntry(Dns.GetHostName()).AddressList.Select(oo => oo.ToString()))}" };
36 | return Task.FromResult(model);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.AspNetCore.Http;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using Microsoft.Extensions.Hosting;
6 | using Overt.Core.Grpc.H2;
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Linq;
10 | using System.Threading.Tasks;
11 |
12 | namespace Overt.GrpcExample.Service
13 | {
14 | public class Startup
15 | {
16 | // This method gets called by the runtime. Use this method to add services to the container.
17 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
18 | public void ConfigureServices(IServiceCollection services)
19 | {
20 | services.AddGrpc();
21 |
22 | services.AddGrpcService();
23 | }
24 |
25 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
26 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
27 | {
28 | if (env.IsDevelopment())
29 | {
30 | app.UseDeveloperExceptionPage();
31 | }
32 |
33 | app.UseRouting();
34 |
35 | app.UseEndpoints(endpoints =>
36 | {
37 | endpoints.MapGrpcService();
38 |
39 | endpoints.MapGet("/", async context =>
40 | {
41 | await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
42 | });
43 | });
44 |
45 | app.UseGrpcRegister();
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Grpc": "Information",
7 | "Microsoft": "Information"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*",
10 | "Kestrel": {
11 | "EndpointDefaults": {
12 | "Protocols": "Http2"
13 | }
14 | },
15 | "GrpcServer": {
16 | "Service": {
17 | "Name": "OvertGrpcExampleService",
18 | "Scheme": "",
19 | "Host": "192.168.10.66",
20 | "Port": 5002,
21 | "Consul": {
22 | "Path": "dllconfigs/consulsettings.json"
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample.Service/dllconfigs/consulsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConsulServer": {
3 | "Service": {
4 | "Address": "http://192.168.10.10:8500"
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample1.Service.Grpc/Overt.GrpcExample1.Service.Grpc.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample1.Service.Grpc/Protos/GrpcExample1.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package Overt.GrpcExample1.Service.Grpc;
3 |
4 | message RequestModel{
5 | string key = 1;
6 | }
7 |
8 | message ResponseModel{
9 | string name = 1;
10 | }
11 |
12 |
13 | message AskRequest{
14 | int32 Cate = 1;
15 | string Key = 2;
16 | repeated int32 samples = 3;
17 | }
18 |
19 | message AskResponse{
20 | string Content = 1;
21 | }
22 |
23 | service GrpcExampleService {
24 |
25 | rpc GetName(RequestModel) returns (ResponseModel){}
26 |
27 | rpc Ask(AskRequest) returns (AskResponse){}
28 |
29 | }
30 |
31 | service GrpcExampleService1 {
32 |
33 | rpc GetName(RequestModel) returns (ResponseModel){}
34 |
35 | rpc Ask(AskRequest) returns (AskResponse){}
36 |
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample1.Service.Grpc/coreconfigs/clientsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcClient": {
3 | "Service": {
4 | "Name": "",
5 | "MaxRetry": 0,
6 | "Discovery": {
7 | "EndPoints": [
8 | {
9 | "Host": "127.0.0.1",
10 | "Port": 0
11 | }
12 | ],
13 | "Consul": {
14 | "Path": "dllconfigs/consulsettings.json"
15 | }
16 | }
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample1.Service.Grpc/coreconfigs/consulsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConsulServer": {
3 | "Service": {
4 | "Address": "http://127.0.0.1:8500"
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample1.Service.Grpc/coreconfigs/grpcsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcServer": {
3 | "Service": {
4 | "Name": "grpcservice",
5 | "Host": "",
6 | "Port": 10001,
7 | "Consul": {
8 | "Path": "dllconfigs/consulsettings.json"
9 | }
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample1.Service.Grpc/fmconfigs/Client.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample1.Service.Grpc/fmconfigs/Consul.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/grpc.net/Overt.GrpcExample1.Service.Grpc/fmconfigs/Server.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Client/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Client/Program.cs:
--------------------------------------------------------------------------------
1 | //using Overt.GrpcExampleNet45.Client.Tracer;
2 | using Overt.GrpcExampleNet45.Client.Tracer;
3 | using System;
4 |
5 | namespace Overt.GrpcExampleNet45.Client
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 | do
12 | {
13 | var key = Console.ReadKey();
14 | if (key.Key == ConsoleKey.A)
15 | break;
16 |
17 | try
18 | {
19 | var client = GrpcExample.Service.Grpc.ClientManager.CreateInstance((invokers) =>
20 | {
21 | return invokers[0];
22 | });
23 | GrpcExample.Service.Grpc.ClientManager.Tracer = new ConsoleTracer();
24 | //var client = GrpcExample.Service.Grpc.ClientManager.Instance;
25 | var res = client.Ask(new GrpcExample.Service.Grpc.AskRequest() { Key = "abc" });
26 | Console.WriteLine("例子:" + res?.Content ?? "abc");
27 |
28 |
29 | var client1 = GrpcExample.Service.Grpc.ClientManager.Instance;
30 | var res1 = client1.Ask(new GrpcExample.Service.Grpc.AskRequest() { Key = "abc" });
31 | Console.WriteLine("例子:" + res1?.Content ?? "abc");
32 | }
33 | catch (Exception ex)
34 | {
35 | Console.WriteLine("异常");
36 | }
37 | } while (true);
38 |
39 | Console.WriteLine("结束...");
40 | Console.ReadLine();
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Client/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("Overt.GrpcExampleNet45.Client")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("Overt.GrpcExampleNet45.Client")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2018")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 会使此程序集中的类型
18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
19 | //请将此类型的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("da35362d-ae25-4d26-96fe-1c2ca471e802")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
33 | // 方法是按如下所示使用“*”: :
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Client/Tracer/ConsoleTracer.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Grpc.Core.Interceptors;
3 | using Overt.Core.Grpc.Intercept;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Text;
7 |
8 | namespace Overt.GrpcExampleNet45.Client.Tracer
9 | {
10 | public class ConsoleTracer : IClientTracer
11 | {
12 | public string ServiceName { get; set; }
13 |
14 | public void Exception(ClientInterceptorContext context, Exception exception, TRequest request = null)
15 | where TRequest : class
16 | where TResponse : class
17 | {
18 | Console.WriteLine("some exception");
19 | }
20 |
21 | public void Finish(ClientInterceptorContext context)
22 | where TRequest : class
23 | where TResponse : class
24 | {
25 | Console.WriteLine("finished request");
26 | }
27 |
28 | public void Request(TRequest request, ClientInterceptorContext context)
29 | where TRequest : class
30 | where TResponse : class
31 | {
32 | Console.WriteLine("start request");
33 | }
34 |
35 | public void Response(TResponse response, ClientInterceptorContext context)
36 | where TRequest : class
37 | where TResponse : class
38 | {
39 | Console.WriteLine("end response");
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Client/dllconfigs/Consul.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Client/dllconfigs/Overt.GrpcExample.Service.Grpc.dll.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Client/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service.Grpc/ClientManager.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Grpc.Core.Interceptors;
3 | using Overt.Core.Grpc;
4 | using Overt.Core.Grpc.Intercept;
5 | using System;
6 | using System.Collections.Concurrent;
7 | using System.Collections.Generic;
8 | using System.IO;
9 | using __GrpcService = Overt.GrpcExample.Service.Grpc.GrpcExampleService;
10 | namespace Overt.GrpcExample.Service.Grpc
11 | {
12 | #if NET45 || NET46 || NET47
13 | public class ClientManager {
14 | public static IClientTracer Tracer { get; set; } = default(IClientTracer);
15 | public static List Interceptors { get; } = new List();
16 | private static string DefaultConfigPath { get; set; } = "dllconfigs/Overt.GrpcExample.Service.Grpc.dll.config";
17 | public static __GrpcService.GrpcExampleServiceClient Instance{get{
18 | return ClientManager<__GrpcService.GrpcExampleServiceClient>.Instance;
19 | } }
20 | public static __GrpcService.GrpcExampleServiceClient CreateInstance(Func, ServerCallInvoker> getInvoker = null){
21 | return ClientManager<__GrpcService.GrpcExampleServiceClient>.CreateInstance(getInvoker);
22 | }
23 | private static readonly ConcurrentDictionary configMap = new ConcurrentDictionary();
24 | public static void Configure(string configPath) { configMap.AddOrUpdate(typeof(T), configPath, (t, s) => configPath); }
25 | public static string GetConfigure() { if (configMap.TryGetValue(typeof(T), out string configPath)) return configPath; return DefaultConfigPath;}
26 | }
27 | public class ClientManager : ClientManager where T : ClientBase
28 | {
29 | public static new T Instance => CreateInstance();
30 | public static new T CreateInstance(Func, ServerCallInvoker> getInvoker = null) {
31 | var configPath = GetConfigure();
32 | var options = new GrpcClientOptions() { Tracer = Tracer };
33 | if (Interceptors?.Count > 0) options.Interceptors.AddRange(Interceptors);
34 | return GrpcClientManager.Get(configPath, options, getInvoker);
35 | }
36 | }
37 | #endif
38 | }
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service.Grpc/Overt.GrpcExampleNet45.Service.Grpc.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net45
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service.Grpc/coreconfigs/clientsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcClient": {
3 | "Service": {
4 | "Name": "",
5 | "MaxRetry": 0,
6 | "Discovery": {
7 | "EndPoints": [
8 | {
9 | "Host": "127.0.0.1",
10 | "Port": 0
11 | }
12 | ],
13 | "Consul": {
14 | "Path": "dllconfigs/consulsettings.json"
15 | }
16 | }
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service.Grpc/coreconfigs/consulsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConsulServer": {
3 | "Service": {
4 | "Address": "http://127.0.0.1:8500"
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service.Grpc/coreconfigs/grpcsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcServer": {
3 | "Service": {
4 | "Name": "grpcservice",
5 | "Host": "",
6 | "Port": 10001,
7 | "Consul": {
8 | "Path": "dllconfigs/consulsettings.json"
9 | }
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service.Grpc/fmconfigs/Client.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service.Grpc/fmconfigs/Consul.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service.Grpc/fmconfigs/Server.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/AutofacContainer.cs:
--------------------------------------------------------------------------------
1 | using Autofac;
2 | using Overt.Core.Grpc.Intercept;
3 | using Overt.GrpcExampleNet45.Service.Tracer;
4 |
5 | namespace Overt.GrpcExampleNet45.Service
6 | {
7 | public class AutofacContainer
8 | {
9 | public static IContainer Register()
10 | {
11 | var builder = new ContainerBuilder();
12 | var container = builder.Build(Autofac.Builder.ContainerBuildOptions.None);
13 | return container;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/Impl/GrpcExampleServiceImpl.cs:
--------------------------------------------------------------------------------
1 | using Autofac;
2 | using Grpc.Core;
3 | using Overt.GrpcExample.Service.Grpc;
4 | using System;
5 | using System.Linq;
6 | using System.Net;
7 | using System.Threading.Tasks;
8 |
9 | namespace Overt.GrpcExampleNet45.Service
10 | {
11 | public class GrpcExampleServiceImpl : GrpcExampleService.GrpcExampleServiceBase
12 | {
13 | #region Private Fields
14 | private readonly IContainer _container;
15 | #endregion
16 |
17 | #region Constructor
18 |
19 | public GrpcExampleServiceImpl(IContainer container)
20 | {
21 | _container = container;
22 | }
23 | #endregion
24 |
25 | public override Task GetName(RequestModel request, ServerCallContext context)
26 | {
27 | ResponseModel model = null;
28 | if (request == null || request.Key == null)
29 | return Task.FromResult(model);
30 |
31 | model = new ResponseModel() { };
32 | return Task.FromResult(model);
33 | }
34 |
35 | public override Task Ask(AskRequest request, ServerCallContext context)
36 | {
37 | var model = new AskResponse() { Content = $"Ask: {request.Key}: {DateTime.Now.ToString()} --- address: {string.Join(",", Dns.GetHostEntry(Dns.GetHostName()).AddressList.Select(oo => oo.ToString()))}" };
38 | return Task.FromResult(model);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/InstallService.bat:
--------------------------------------------------------------------------------
1 | Overt.GrpcExampleNet45.Service.exe install
2 | pause
3 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/MainService.cs:
--------------------------------------------------------------------------------
1 | using Autofac;
2 | using Overt.Core.Grpc;
3 | using Overt.GrpcExample.Service.Grpc;
4 | using Overt.GrpcExampleNet45.Service.Tracer;
5 | using System;
6 |
7 | namespace Overt.GrpcExampleNet45.Service
8 | {
9 | public class MainService
10 | {
11 | public MainService()
12 | {
13 | System.Threading.ThreadPool.SetMinThreads(30, 30);
14 | AppDomain.CurrentDomain.UnhandledException += (obj, e) =>
15 | {
16 | var ex = e.ExceptionObject as Exception;
17 | if (ex != null)
18 | {
19 | //LogHelper.LogError(ex.Message, ex);
20 | }
21 | };
22 | System.Threading.Tasks.TaskScheduler.UnobservedTaskException += (obj, e) =>
23 | {
24 | e.SetObserved();
25 | e.Exception.Flatten().Handle(c =>
26 | {
27 | //LogHelper.LogError(c.Message, c);
28 | return true;
29 | });
30 | };
31 | }
32 | public void Start(string serviceName)
33 | {
34 | // LogHelper.LogInfo($"{serviceName}服务启动");
35 | // autofac
36 | var container = AutofacContainer.Register();
37 | // grpc
38 | GrpcServiceManager.Start(GrpcExampleService.BindService(new GrpcExampleServiceImpl(container)), (options) =>
39 | {
40 | options.Tracer = new ConsoleTracer();
41 | },
42 | whenException: (ex) =>
43 | {
44 |
45 | });
46 | }
47 |
48 | public void Stop(string serviceName)
49 | {
50 | GrpcServiceManager.Stop();
51 | // LogHelper.LogInfo($"{serviceName}服务停止");
52 | }
53 | public void ShutDown(string serviceName)
54 | {
55 | GrpcServiceManager.Stop();
56 | // LogHelper.LogInfo($"{serviceName}服务停止");
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Configuration;
3 | using Topshelf;
4 |
5 | namespace Overt.GrpcExampleNet45.Service
6 | {
7 | static class Program
8 | {
9 | ///
10 | /// 应用程序的主入口点。
11 | ///
12 | static void Main()
13 | {
14 | var serviceName = ConfigurationManager.AppSettings["ServiceName"];
15 | var serviceDescription = ConfigurationManager.AppSettings["ServiceDescription"];
16 | var serviceDisplayName = ConfigurationManager.AppSettings["ServiceDisplayName"];
17 | if (string.IsNullOrEmpty(serviceName)
18 | || string.IsNullOrEmpty(serviceDisplayName)
19 | || string.IsNullOrEmpty(serviceDescription))
20 | throw new ArgumentNullException();
21 | HostFactory.Run(x =>
22 | {
23 | x.Service(s =>
24 | {
25 | s.ConstructUsing(service => new MainService());
26 | s.WhenStarted(ts => ts.Start(serviceName));
27 | s.WhenShutdown(ts => ts.ShutDown(serviceName));
28 | s.WhenStopped(ts => ts.Stop(serviceName));
29 | });
30 | x.SetServiceName(serviceName);
31 | x.SetDisplayName(serviceDisplayName);
32 | x.SetDescription(serviceDescription);
33 | // 启动方式
34 | x.StartAutomatically();
35 | //x.StartAutomaticallyDelayed();
36 | //x.StartManually();
37 | //x.Disabled();
38 |
39 | // 服务运行账户
40 | x.RunAsLocalSystem();
41 | //x.RunAsLocalSystem();
42 | //x.RunAsNetworkService();
43 | //x.RunAsPrompt();
44 |
45 | // 服务依赖项
46 | //x.DependsOn(servicenames);
47 |
48 | // 自动恢复(服务重启)设置
49 | x.EnableServiceRecovery(r =>
50 | {
51 | var delay = 0;
52 | // 第一次失败
53 | // 重启服务
54 | r.RestartService(delay);
55 |
56 | // 第二次失败
57 | //// 运行指定外部程序
58 | //r.RunProgram(delay, "command");
59 |
60 | // 第三次失败
61 | //// 重启计算机
62 | //r.RestartComputer(delay, string.Format("Service {0} crashed!", serviceName));
63 |
64 | // 仅服务崩溃时重启服务
65 | r.OnCrashOnly();
66 |
67 | // 恢复计算周期
68 | r.SetResetPeriod(1);
69 | });
70 | });
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("Overt.GrpcExampleNet45.Service")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("Overt.GrpcExampleNet45.Service")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2018")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 会使此程序集中的类型
18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
19 | //请将此类型的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("348bf984-bf6c-4020-86a8-f9866d85ff6f")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
33 | // 方法是按如下所示使用“*”: :
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/Readme.txt:
--------------------------------------------------------------------------------
1 | 请修改掉项目中对应的占位信息,切记切记
2 |
3 | Overt.GrpcExampleNet45.Service 创建的项目的命名空间名称
4 | Overt.GrpcExampleNet45.Service 自定义服务名称
5 | [ThriftServiceName] 自定义Thrift模板中的ServiceName
6 | [ServicePort] 由运维提供的服务端口
7 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/StartService.bat:
--------------------------------------------------------------------------------
1 | net start Overt.GrpcExampleNet45.Service
2 | pause
3 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/StopService.bat:
--------------------------------------------------------------------------------
1 | net stop Overt.GrpcExampleNet45.Service
2 | pause
3 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/Tracer/ConsoleTracer.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Overt.Core.Grpc.Intercept;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace Overt.GrpcExampleNet45.Service.Tracer
8 | {
9 | public class ConsoleTracer : IServerTracer
10 | {
11 | public string ServiceName { get; set; }
12 |
13 | public void Exception(ServerCallContext context, Exception exception, TRequest request = default(TRequest))
14 | {
15 | Console.WriteLine("some exception");
16 | }
17 |
18 | public void Finish(ServerCallContext context)
19 | {
20 | Console.WriteLine("finished request");
21 | }
22 |
23 | public void Request(TRequest request, ServerCallContext context)
24 | {
25 | Console.WriteLine("start request");
26 | }
27 |
28 | public void Response(TResponse response, ServerCallContext context)
29 | {
30 | Console.WriteLine("end response");
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/UninstallService.bat:
--------------------------------------------------------------------------------
1 | Overt.GrpcExampleNet45.Service.exe uninstall
2 | pause
3 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/dllconfigs/Consul.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/dllconfigs/Sodao.Log.nlog.config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
24 | INSERT INTO log4net(log_site, log_datetime, log_thread, log_level, log_logger, log_message, exception, ip, stacktrace) VALUES (@log_site, @log_date, @log_thread, @log_level, @log_logger, @message, @exception, @ip, @stacktrace)
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/sample/net45/Overt.GrpcExampleNet45.Service/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Application/Constracts/IUserService.cs:
--------------------------------------------------------------------------------
1 | using Overt.GrpcExample.Domain.Entities;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace Overt.GrpcExample.Application.Constracts
7 | {
8 | public interface IUserService
9 | {
10 | UserEntity DoSomething();
11 |
12 | bool DoSomethingWithTrans();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Application/Overt.GrpcExample.Application.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Application/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using Overt.GrpcExample.Application.Constracts;
3 | using Overt.GrpcExample.Application.Services;
4 | using Overt.GrpcExample.Domain;
5 |
6 | namespace Overt.GrpcExample.Application
7 | {
8 | public static class ServiceCollectionExtensions
9 | {
10 | public static void AddApplicationDI(this IServiceCollection services)
11 | {
12 | services.AddTransient();
13 |
14 | services.AddDomainDI();
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Application/Services/UserService.cs:
--------------------------------------------------------------------------------
1 | using Overt.GrpcExample.Application.Constracts;
2 | using Overt.GrpcExample.Domain.Contracts;
3 | using Overt.GrpcExample.Domain.Entities;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Text;
7 |
8 | namespace Overt.GrpcExample.Application.Services
9 | {
10 | public class UserService : IUserService
11 | {
12 | IUserRepository _userRepository;
13 | public UserService(IUserRepository userRepository)
14 | {
15 | _userRepository = userRepository;
16 | }
17 |
18 | public UserEntity DoSomething()
19 | {
20 | return _userRepository.DoSomething();
21 | }
22 |
23 | public bool DoSomethingWithTrans()
24 | {
25 | using (var transaction = _userRepository.BeginTransaction())
26 | {
27 | var entity = new UserEntity()
28 | {
29 | AddTime = DateTime.Now,
30 | IsSex = false,
31 | UserName = DateTime.Now.ToString("yyyyMMddHHmmss")
32 | };
33 | var addRes = _userRepository.Add(entity, true);
34 | _userRepository.Set(() => new { RealName = $"R_{DateTime.Now.ToString("yyyyMMddHHmmss")}" }, oo => oo.UserId == entity.UserId);
35 | transaction.Commit();
36 | }
37 | return true;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Client/Overt.GrpcExample.Client.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Always
21 |
22 |
23 | Always
24 |
25 |
26 | Always
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Client/Program.cs:
--------------------------------------------------------------------------------
1 | using Com.Ctrip.Framework.Apollo;
2 | using Microsoft.Extensions.Configuration;
3 | using Microsoft.Extensions.DependencyInjection;
4 | using Overt.Core.Grpc;
5 | using Overt.GrpcExample.Client.Tracer;
6 | using System;
7 | using System.Threading;
8 | using static Overt.GrpcExample.Service.Grpc.GrpcExampleService;
9 |
10 | namespace Overt.GrpcExample.Client
11 | {
12 | class Program
13 | {
14 | static IServiceProvider provider;
15 | static Program()
16 | {
17 | var builder = new ConfigurationBuilder()
18 | .SetBasePath(AppContext.BaseDirectory)
19 | .AddJsonFile("appsettings.json", true);
20 |
21 | var configuration = builder.Build();
22 |
23 | var services = new ServiceCollection();
24 | services.AddSingleton(configuration);
25 | services.AddOptions();
26 |
27 | // 注入GrpcClient
28 | services.AddGrpcClient();
29 | services.Configure>(options =>
30 | {
31 | options.Tracer = new ConsoleTracer();
32 | options.Interceptors.Add(new ClientLoggerInterceptor());
33 | });
34 | // 第三方配置,启动可用
35 | //services.AddGrpcConfig(config =>
36 | //{
37 | // config.AddApollo(configuration.GetSection("apollo")).AddDefault();
38 | //});
39 | //services.Configure>(cfg =>
40 | //{
41 | // cfg.ConfigPath = "";
42 | //});
43 |
44 | provider = services.BuildServiceProvider();
45 | }
46 |
47 | static void Main(string[] args)
48 | {
49 | do
50 | {
51 | var key = Console.ReadKey();
52 | if (key.Key == ConsoleKey.A)
53 | break;
54 |
55 | try
56 | {
57 | var service = provider.GetService>();
58 | var client = service.CreateClient((invokers) =>
59 | {
60 | return invokers[0];
61 | });
62 | var res = client.Ask(new Service.Grpc.AskRequest() { Key = "abc" });
63 | Console.WriteLine(DateTime.Now + " - " + res.Content ?? "abc");
64 | }
65 | catch (Exception ex)
66 | {
67 | Console.WriteLine($"{DateTime.Now} - 异常");
68 | }
69 |
70 | Thread.Sleep(200);
71 |
72 | } while (true);
73 |
74 | Console.WriteLine("over");
75 | Console.ReadLine();
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Client/Properties/PublishProfiles/FolderProfile.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 | FileSystem
9 | Release
10 | netcoreapp2.0
11 | bin\Release\PublishOutput
12 |
13 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Client/Tracer/ConsoleTracer.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core.Interceptors;
2 | using Overt.Core.Grpc.Intercept;
3 | using System;
4 |
5 | namespace Overt.GrpcExample.Client.Tracer
6 | {
7 | public class ConsoleTracer : IClientTracer
8 | {
9 |
10 | public void Exception(ClientInterceptorContext context, Exception exception, TRequest request = null)
11 | where TRequest : class
12 | where TResponse : class
13 | {
14 | Console.WriteLine("some exception");
15 | }
16 |
17 | public void Finish(ClientInterceptorContext context)
18 | where TRequest : class
19 | where TResponse : class
20 | {
21 | Console.WriteLine("finished request");
22 | }
23 |
24 | public void Request(TRequest request, ClientInterceptorContext context)
25 | where TRequest : class
26 | where TResponse : class
27 | {
28 | // 修改Channel
29 | //context.Options.Headers.Add(Constants.MetadataKey_ChannelTarget, "127.0.0.1:10003");
30 |
31 | Console.WriteLine("start request");
32 | }
33 |
34 | public void Response(TResponse response, ClientInterceptorContext context)
35 | where TRequest : class
36 | where TResponse : class
37 | {
38 | Console.WriteLine("end response");
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Client/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "noImplicitAny": false,
4 | "noEmitOnError": true,
5 | "removeComments": false,
6 | "sourceMap": true,
7 | "target": "es5"
8 | },
9 | "exclude": [
10 | "node_modules",
11 | "wwwroot"
12 | ]
13 | //, "apollo": {
14 | // "AppId": "overtcoregrpc",
15 | // "MetaServer": "http://106.54.227.205:8080/",
16 | // "Env": "DEV"
17 | //}
18 | }
19 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Client/dllconfigs/Overt.GrpcExample.Service.Grpc.dll.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcClient": {
3 | "Service": {
4 | "Name": "OvertGrpcExampleService",
5 | "MaxRetry": 0,
6 | "Discovery": {
7 | "Consul": {
8 | "Path": "dllconfigs/consulsettings.json"
9 | }
10 | //"EndPoints": [
11 | // {
12 | // "Host": "127.0.0.1",
13 | // "Port": 10004
14 | // }
15 | //]
16 | }
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Client/dllconfigs/consulsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConsulServer": {
3 | "Service": {
4 | "Address": "http://127.0.0.1:8500",
5 | "Token": "123123123"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Domain/Contracts/IUserRepository.cs:
--------------------------------------------------------------------------------
1 | using Overt.Core.Data;
2 | using Overt.GrpcExample.Domain.Entities;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace Overt.GrpcExample.Domain.Contracts
8 | {
9 | public interface IUserRepository : IBaseRepository
10 | {
11 | ///
12 | /// 做什么东西
13 | ///
14 | ///
15 | UserEntity DoSomething();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Domain/Entities/UserEntity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations;
4 | using System.ComponentModel.DataAnnotations.Schema;
5 | using System.Text;
6 |
7 | namespace Overt.GrpcExample.Domain.Entities
8 | {
9 | [Table("User")]
10 | public class UserEntity
11 | {
12 | [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
13 | //[Submeter(Bit = 2)]
14 | public int UserId { get; set; }
15 | public string UserName { get; set; }
16 | public string RealName { get; set; }
17 | public string Password { get; set; }
18 | public DateTime AddTime { get; set; }
19 | public bool IsSex { get; set; }
20 | ///
21 | /// Json类型
22 | ///
23 | public string JsonValue { get; set; }
24 | ///
25 | /// Json类型
26 | ///
27 | public string Join { get; set; }
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Domain/Overt.GrpcExample.Domain.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Domain/Repositories/UserRepository.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Configuration;
2 | using Overt.Core.Data;
3 | using Overt.GrpcExample.Domain.Contracts;
4 | using Overt.GrpcExample.Domain.Entities;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 |
8 | namespace Overt.GrpcExample.Domain.Repositories
9 | {
10 | public class UserRepository : BaseRepository, IUserRepository
11 | {
12 | public UserRepository(IConfiguration configuration) : base(configuration)
13 | {
14 | }
15 |
16 | public UserEntity DoSomething()
17 | {
18 | var testModel = new TestValue();
19 |
20 | var abc = new int[] { 3, 4, 5 };
21 | var count = GetList(1, 10, oo => abc.Contains(oo.UserId));
22 |
23 | return null;
24 |
25 | #region 增
26 | var model = new UserEntity()
27 | {
28 | UserName = "abc",
29 | RealName = "abc",
30 | Password = "123456",
31 | };
32 | var addResult = Add(model, true);
33 | #endregion
34 |
35 | #region 查
36 | var getResult = Get(oo => oo.UserId == model.UserId, oo => new { oo.UserId, oo.UserName });
37 |
38 | var countResult = Count(oo => oo.UserName.Contains("test"));
39 | #endregion
40 |
41 | #region 改
42 | var setResult = Set(() => new { RealName = "abc" }, oo => oo.UserId == model.UserId);
43 | #endregion
44 |
45 | #region 删
46 | var delResult = Delete(oo => oo.UserId == model.UserId);
47 | #endregion
48 |
49 | return null;
50 | }
51 | }
52 |
53 | public class TestValue
54 | {
55 | public List Ids { get; set; } = new List() { 3, 4, 5 };
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Domain/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using Overt.GrpcExample.Domain.Contracts;
3 | using Overt.GrpcExample.Domain.Repositories;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Text;
7 |
8 | namespace Overt.GrpcExample.Domain
9 | {
10 | public static class ServiceCollectionExtensions
11 | {
12 | public static void AddDomainDI(this IServiceCollection services)
13 | {
14 | services.AddTransient();
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service.Grpc/GrpcExample.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package Overt.GrpcExample.Service.Grpc;
3 |
4 | message RequestModel{
5 | string key = 1;
6 | }
7 |
8 | message ResponseModel{
9 | string name = 1;
10 | }
11 |
12 |
13 | message AskRequest{
14 | int32 Cate = 1;
15 | string Key = 2;
16 | repeated int32 samples = 3;
17 | }
18 |
19 | message AskResponse{
20 | string Content = 1;
21 | }
22 |
23 | service GrpcExampleService {
24 |
25 | rpc GetName(RequestModel) returns (ResponseModel){}
26 |
27 | rpc Ask(AskRequest) returns (AskResponse){}
28 |
29 | }
30 |
31 | service GrpcExampleService1 {
32 |
33 | rpc GetName(RequestModel) returns (ResponseModel){}
34 |
35 | rpc Ask(AskRequest) returns (AskResponse){}
36 |
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service.Grpc/GrpcExample.proto.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | GrpcExample.proto
4 | SodaoGrpcExampleService
5 | 10004
6 | false
7 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service.Grpc/Overt.GrpcExample.Service.Grpc.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service.Grpc/coreconfigs/clientsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcClient": {
3 | "Service": {
4 | "Name": "",
5 | "MaxRetry": 0,
6 | "Discovery": {
7 | "EndPoints": [
8 | {
9 | "Host": "127.0.0.1",
10 | "Port": 0
11 | }
12 | ],
13 | "Consul": {
14 | "Path": "dllconfigs/consulsettings.json"
15 | }
16 | }
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service.Grpc/coreconfigs/consulsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConsulServer": {
3 | "Service": {
4 | "Address": "http://127.0.0.1:8500"
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service.Grpc/coreconfigs/grpcsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcServer": {
3 | "Service": {
4 | "Name": "grpcservice",
5 | "Host": "",
6 | "Port": 10001,
7 | "Consul": {
8 | "Path": "dllconfigs/consulsettings.json"
9 | }
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service.Grpc/fmconfigs/Client.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service.Grpc/fmconfigs/Consul.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service.Grpc/fmconfigs/Server.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM microsoft/dotnet:2.0-runtime AS base
2 | WORKDIR /app
3 |
4 | FROM microsoft/dotnet:2.0-sdk AS build
5 | WORKDIR /src
6 | COPY *.sln ./
7 | COPY src/Overt.GrpcExample.Service/Overt.GrpcExample.Service.csproj src/Overt.GrpcExample.Service/
8 | COPY src/Overt.GrpcExample.Application/Overt.GrpcExample.Application.csproj src/Overt.GrpcExample.Application/
9 | COPY src/Overt.GrpcExample.Domain/Overt.GrpcExample.Domain.csproj src/Overt.GrpcExample.Domain/
10 | COPY src/Overt.GrpcExample.Service.Grpc/Overt.GrpcExample.Service.Grpc.csproj src/Overt.GrpcExample.Service.Grpc/
11 | COPY src/Overt.Core.Grpc/Overt.Core.Grpc.csproj src/Overt.Core.Grpc/
12 | RUN dotnet restore
13 | COPY . .
14 | WORKDIR /src/src/Overt.GrpcExample.Service
15 | RUN dotnet build -c Release -o /app
16 |
17 | FROM build AS publish
18 | RUN dotnet publish -c Release -o /app
19 |
20 | FROM base AS final
21 | WORKDIR /app
22 | COPY --from=publish /app .
23 | ENTRYPOINT ["dotnet", "Overt.GrpcExample.Service.dll"]
24 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service/HostedService/GrpcExampleHostedService.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Microsoft.Extensions.Configuration;
3 | using Microsoft.Extensions.Hosting;
4 | using Overt.Core.Grpc;
5 | using Overt.Core.Grpc.Intercept;
6 | using Overt.GrpcExample.Service.Grpc;
7 | using System.Collections.Generic;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 |
11 | namespace Overt.GrpcExample.Service
12 | {
13 | public class GrpcExampleHostedService : IHostedService
14 | {
15 | readonly IServerTracer _tracer;
16 | readonly GrpcExampleService.GrpcExampleServiceBase _grpcServiceBase;
17 | IConfiguration _configuration;
18 | public GrpcExampleHostedService(
19 | IServerTracer tracer,
20 | GrpcExampleService.GrpcExampleServiceBase grpcServiceBase,
21 | IConfiguration configuration)
22 | {
23 | _tracer = tracer;
24 | _grpcServiceBase = grpcServiceBase;
25 | _configuration = configuration;
26 | }
27 |
28 | public Task StartAsync(CancellationToken cancellationToken)
29 | {
30 | return Task.Factory.StartNew(() =>
31 | {
32 | GrpcServiceManager.Start(GrpcExampleService.BindService(_grpcServiceBase), (options) =>
33 | {
34 | options.ChannelOptions = new List();
35 | });
36 | }, cancellationToken);
37 | }
38 |
39 | public Task StopAsync(CancellationToken cancellationToken)
40 | {
41 | return Task.Factory.StartNew(() =>
42 | {
43 | GrpcServiceManager.Stop();
44 | }, cancellationToken);
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service/Impl/GrpcExampleServiceImpl.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Microsoft.Extensions.Configuration;
3 | using Microsoft.Extensions.DependencyInjection;
4 | using Overt.GrpcExample.Service.Grpc;
5 | using System;
6 | using System.Linq;
7 | using System.Net;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 |
11 | namespace Overt.GrpcExample.Service
12 | {
13 | public class GrpcExampleServiceImpl : GrpcExampleService.GrpcExampleServiceBase
14 | {
15 | IServiceProvider _provider;
16 | IConfiguration _configuration;
17 | public GrpcExampleServiceImpl(IServiceProvider provider, IConfiguration configuration)
18 | {
19 | _provider = provider;
20 | _configuration = configuration;
21 | }
22 |
23 | public override Task GetName(RequestModel request, ServerCallContext context)
24 | {
25 | ResponseModel model = null;
26 | if (request == null || request.Key == null)
27 | return Task.FromResult(model);
28 |
29 | model = new ResponseModel() { };
30 | return Task.FromResult(model);
31 | }
32 |
33 | public override Task Ask(AskRequest request, ServerCallContext context)
34 | {
35 | var v = _configuration.GetSection("GrpcServer").GetSection("Service").GetValue("Port");
36 |
37 | var model = new AskResponse() { Content = $"Ask: {request.Key}: {DateTime.Now.ToString()} -- configuration: {v} --- address: {string.Join(",", Dns.GetHostEntry(Dns.GetHostName()).AddressList.Select(oo => oo.ToString()))}" };
38 | return Task.FromResult(model);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service/Overt.GrpcExample.Service.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Always
24 |
25 |
26 | Always
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service/Program.cs:
--------------------------------------------------------------------------------
1 | using Com.Ctrip.Framework.Apollo;
2 | using Microsoft.Extensions.Configuration;
3 | using Microsoft.Extensions.DependencyInjection;
4 | using Microsoft.Extensions.Hosting;
5 | using Overt.Core.Grpc;
6 | using Overt.GrpcExample.Service.Grpc;
7 | using Overt.GrpcExample.Service.Tracer;
8 |
9 | namespace Overt.GrpcExample.Service
10 | {
11 | class Program
12 | {
13 | static void Main(string[] args)
14 | {
15 | var host = new HostBuilder()
16 | .UseConsoleLifetime() //使用控制台生命周期
17 | .ConfigureAppConfiguration((context, configurationBuilder) =>
18 | {
19 | configurationBuilder
20 | .AddJsonFile("appsettings.json", optional: true); //约定使用appsettings.json作为应用程序配置文件
21 |
22 | // apollo 启动可用
23 | //configurationBuilder.AddApollo(configurationBuilder.Build().GetSection("apollo")).AddDefault();
24 | })
25 | .ConfigureServices(ConfigureServices)
26 | .Build();
27 |
28 | host.Run();
29 | }
30 |
31 | ///
32 | /// 通用DI注入
33 | ///
34 | ///
35 | ///
36 | private static void ConfigureServices(HostBuilderContext context, IServiceCollection services)
37 | {
38 | services.AddTransient();
39 | services.AddTransient();
40 |
41 | // tracer
42 | services.AddGrpcTracer();
43 |
44 | // apollo 第三方配置启动可用
45 | //services.AddGrpcConfig(config =>
46 | //{
47 | // config.AddApollo(context.Configuration.GetSection("apollo")).AddDefault();
48 | //});
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service/Properties/PublishProfiles/FolderProfile.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 | FileSystem
9 | Release
10 | netcoreapp2.0
11 | bin\Release\PublishOutput
12 |
13 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service/Tracer/ConsoleTracer.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Overt.Core.Grpc.Intercept;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace Overt.GrpcExample.Service.Tracer
8 | {
9 | public class ConsoleTracer : IServerTracer
10 | {
11 | public string ServiceName { get; set; }
12 |
13 | public void Exception(ServerCallContext context, Exception exception, TRequest request = default(TRequest))
14 | {
15 | Console.WriteLine("some exception");
16 | }
17 |
18 | public void Finish(ServerCallContext context)
19 | {
20 | Console.WriteLine("finished request");
21 | }
22 |
23 | public void Request(TRequest request, ServerCallContext context)
24 | {
25 | Console.WriteLine("start request");
26 | }
27 |
28 | public void Response(TResponse response, ServerCallContext context)
29 | {
30 | Console.WriteLine("end response");
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service/appsettings.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/overtly/core-grpc/93049ec3908accda9d9c37d76878fe70a6e1ae10/sample/netcore/Overt.GrpcExample.Service/appsettings.json
--------------------------------------------------------------------------------
/sample/netcore/Overt.GrpcExample.Service/dllconfigs/consulsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConsulServer": {
3 | "Service": {
4 | "Address": "http://192.168.10.10:8500",
5 | "Token": ""
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/ClientGenerate/ChannelWrapper.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using System.Threading.Tasks;
3 |
4 | namespace Overt.Core.Grpc.H2
5 | {
6 | public class ChannelWrapper
7 | {
8 | public ChannelWrapper(string serviceId, ChannelBase channel)
9 | {
10 | ServiceId = serviceId;
11 | Channel = channel;
12 | }
13 |
14 | ///
15 | ///
16 | ///
17 | public string ServiceId { get; set; }
18 |
19 | ///
20 | ///
21 | ///
22 | public ChannelBase Channel { get; set; }
23 |
24 | ///
25 | ///
26 | ///
27 | public string Target { get { return Channel?.Target; } }
28 |
29 | ///
30 | ///
31 | ///
32 | ///
33 | public Task ShutdownAsync()
34 | {
35 | return Channel?.ShutdownAsync();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/ClientGenerate/GrpcClient.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | namespace Overt.Core.Grpc.H2
6 | {
7 | ///
8 | /// GrpcClient管理类
9 | ///
10 | public class GrpcClient : IGrpcClient where T : ClientBase
11 | {
12 | readonly IGrpcClientFactory _factory;
13 | public GrpcClient(IGrpcClientFactory factory)
14 | {
15 | _factory = factory;
16 | }
17 |
18 | ///
19 | /// 获取
20 | ///
21 | public T Client
22 | {
23 | get
24 | {
25 | return _factory.Get();
26 | }
27 | }
28 |
29 | #if NET5_0_OR_GREATER
30 | #else
31 | ///
32 | /// 构造一个新的对象
33 | ///
34 | ///
35 | ///
36 | public T CreateClient(Func, ChannelWrapper> channelWrapperInvoker)
37 | {
38 | return _factory.Get(channelWrapperInvoker);
39 | }
40 | #endif
41 | }
42 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/ClientGenerate/GrpcClientFactory.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Microsoft.Extensions.Options;
3 | using System;
4 | using System.Collections.Generic;
5 |
6 | namespace Overt.Core.Grpc.H2
7 | {
8 | ///
9 | /// 客户端工厂
10 | ///
11 | public class GrpcClientFactory : IGrpcClientFactory where T : ClientBase
12 | {
13 | private readonly GrpcClientOptions _options;
14 | private readonly StrategyFactory _strategyFactory;
15 | public GrpcClientFactory(IOptions> options,
16 | StrategyFactory strategyFactory)
17 | {
18 | _options = options?.Value ?? new GrpcClientOptions();
19 | _options.ConfigPath = GetConfigPath(_options.ConfigPath);
20 | _strategyFactory = strategyFactory;
21 | }
22 |
23 | #if NET5_0_OR_GREATER
24 | ///
25 | /// 构造实例
26 | ///
27 | ///
28 | ///
29 | public T Get()
30 | {
31 | var channel = _strategyFactory.Get(_options);
32 | var client = (T)Activator.CreateInstance(typeof(T), channel);
33 | return client;
34 | }
35 | #else
36 | ///
37 | /// 构造实例
38 | ///
39 | ///
40 | ///
41 | public T Get(Func, ChannelWrapper> channelWrapperInvoker = null)
42 | {
43 | var exitus = _strategyFactory.Get(_options);
44 |
45 | ChannelWrapper channelWrapper;
46 | if (channelWrapperInvoker != null)
47 | channelWrapper = channelWrapperInvoker(exitus.EndpointStrategy.GetChannelWrappers(exitus.ServiceName));
48 | else
49 | channelWrapper = exitus.EndpointStrategy.GetChannelWrapper(exitus.ServiceName);
50 |
51 |
52 | var client = (T)Activator.CreateInstance(typeof(T), channelWrapper.Channel);
53 | return client;
54 | }
55 | #endif
56 |
57 | #region Private Method
58 | ///
59 | /// 获取命名空间
60 | ///
61 | ///
62 | private string GetConfigPath(string configPath)
63 | {
64 | if (string.IsNullOrWhiteSpace(configPath))
65 | configPath = $"dllconfigs/{typeof(T).Namespace}.dll.json";
66 |
67 | return configPath;
68 | }
69 | #endregion
70 | }
71 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/ClientGenerate/GrpcClientOptions.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Grpc.Net.Client;
3 |
4 | namespace Overt.Core.Grpc.H2
5 | {
6 | ///
7 | /// 单服务客户端配置
8 | ///
9 | public class GrpcClientOptions
10 | {
11 | ///
12 | /// Json文件
13 | /// defaultValue: dllconfigs/{namespace}.dll.json
14 | ///
15 | public string ConfigPath { get; set; }
16 |
17 | ///
18 | /// 服务名称
19 | /// 手动配置优先
20 | ///
21 | public string ServiceName { get; set; }
22 |
23 | ///
24 | /// http / https
25 | /// 手动配置优先
26 | ///
27 | public string Scheme { get; set; }
28 |
29 | ///
30 | /// 配置GrpcChannelOptions
31 | /// 手动配置优先
32 | ///
33 | public GrpcChannelOptions GrpcChannelOptions { set; get; }
34 | }
35 |
36 | ///
37 | /// 单服务客户端配置
38 | ///
39 | public class GrpcClientOptions : GrpcClientOptions where T : ClientBase
40 | {
41 |
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/ClientGenerate/Interface/IGrpcClient.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | namespace Overt.Core.Grpc.H2
6 | {
7 | ///
8 | /// 接口类
9 | ///
10 | public interface IGrpcClient where T : ClientBase
11 | {
12 | ///
13 | /// 单例对象
14 | ///
15 | T Client { get; }
16 |
17 | #if NET5_0_OR_GREATER
18 | #else
19 | ///
20 | /// 每次构造一个新的对象
21 | ///
22 | ///
23 | ///
24 | T CreateClient(Func, ChannelWrapper> getChannel);
25 | #endif
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/ClientGenerate/Interface/IGrpcClientFactory.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | namespace Overt.Core.Grpc.H2
6 | {
7 | ///
8 | /// 工厂类接口
9 | ///
10 | ///
11 | public interface IGrpcClientFactory where T : ClientBase
12 | {
13 | #if NET5_0_OR_GREATER
14 | ///
15 | ///
16 | ///
17 | ///
18 | T Get();
19 | #else
20 | ///
21 | /// 获取Client对象
22 | ///
23 | ///
24 | T Get(Func, ChannelWrapper> channelWrapperInvoker = null);
25 | #endif
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/ClientTimespan.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Overt.Core.Grpc.H2
4 | {
5 | internal static class ClientTimespan
6 | {
7 | ///
8 | /// 重置服务时间 30s
9 | ///
10 | public static readonly TimeSpan ResetInterval = TimeSpan.FromSeconds(30);
11 |
12 | ///
13 | /// 黑名单时效 2m
14 | ///
15 | public static readonly TimeSpan BlacklistPeriod = TimeSpan.FromMinutes(2);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/EndpointDiscovery/IEndpointDiscovery.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Overt.Core.Grpc.H2
5 | {
6 | ///
7 | /// 重点服务发现接口
8 | ///
9 | public interface IEndpointDiscovery
10 | {
11 | ///
12 | ///
13 | ///
14 | GrpcClientOptions Options { get; set; }
15 |
16 | ///
17 | /// 监听变动的方法
18 | ///
19 | Action Watched { get; set; }
20 |
21 | ///
22 | /// 获取服务可连接终结点
23 | ///
24 | ///
25 | List<(string serviceId, string target)> FindServiceEndpoints(bool filterBlack = true);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/EndpointDiscovery/IPEndpointDiscovery.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace Overt.Core.Grpc.H2
6 | {
7 | ///
8 | /// IP服务发现
9 | ///
10 | internal class IPEndpointDiscovery : IEndpointDiscovery
11 | {
12 | #region Constructor
13 | private readonly List> _ipEndPoints;
14 | public IPEndpointDiscovery(GrpcClientOptions options, List> ipEndPoints)
15 | {
16 | if ((ipEndPoints?.Count ?? 0) <= 0)
17 | throw new ArgumentNullException("no ip endpoints availble");
18 |
19 | _ipEndPoints = ipEndPoints;
20 |
21 | Options = options;
22 | }
23 | #endregion
24 |
25 | #region Public Property
26 | public GrpcClientOptions Options { get; set; }
27 |
28 | public Action Watched { get; set; }
29 | #endregion
30 |
31 | #region Public Method
32 | public List<(string serviceId, string target)> FindServiceEndpoints(bool filterBlack = true)
33 | {
34 | if ((_ipEndPoints?.Count ?? 0) <= 0)
35 | throw new ArgumentOutOfRangeException("endpoint not provide");
36 |
37 | var targets = _ipEndPoints.Select(x => ("", $"{x.Item1}:{x.Item2}"))
38 | .Where(target => !ServiceBlackPolicy.In(Options.ServiceName, target.Item2) || !filterBlack)
39 | .ToList();
40 | return targets;
41 | }
42 | #endregion
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/EndpointDiscovery/StickyEndpointDiscovery.cs:
--------------------------------------------------------------------------------
1 | using Consul;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Threading.Tasks;
7 |
8 | namespace Overt.Core.Grpc.H2
9 | {
10 | ///
11 | /// 注册中心服务发现
12 | ///
13 | internal sealed class StickyEndpointDiscovery : IEndpointDiscovery
14 | {
15 | #region 构造函数
16 | private readonly ConsulClient _client;
17 | public StickyEndpointDiscovery(GrpcClientOptions options, string address, bool startWatch = true)
18 | {
19 | if (string.IsNullOrWhiteSpace(address))
20 | throw new ArgumentNullException("consul address");
21 |
22 | _client = new ConsulClient((cfg) =>
23 | {
24 | var uriBuilder = new UriBuilder(address);
25 | cfg.Address = uriBuilder.Uri;
26 | });
27 |
28 | Options = options;
29 |
30 | if (startWatch)
31 | StartWatchService();
32 | }
33 | #endregion
34 |
35 | #region Public Property
36 | public GrpcClientOptions Options { get; set; }
37 |
38 | public Action Watched { get; set; }
39 | #endregion
40 |
41 | #region Public Method
42 | public List<(string serviceId, string target)> FindServiceEndpoints(bool filterBlack = true)
43 | {
44 | if (_client == null)
45 | throw new ArgumentNullException("consul client");
46 |
47 | var targets = new List<(string, string)>();
48 | try
49 | {
50 | var r = _client.Health.Service(Options.ServiceName, "", true).Result;
51 | if (r.StatusCode != HttpStatusCode.OK)
52 | throw new ApplicationException($"failed to query consul server");
53 |
54 | targets = r.Response
55 | .Select(x => (x.Service.ID, $"{x.Service.Address}:{x.Service.Port}"))
56 | .Where(target => !ServiceBlackPolicy.In(Options.ServiceName, target.Item2) || !filterBlack)
57 | .ToList();
58 | }
59 | catch { }
60 | return targets;
61 | }
62 | #endregion
63 |
64 | #region Private Method
65 | ///
66 | /// 开始监听服务变动
67 | ///
68 | private void StartWatchService()
69 | {
70 | Task.Factory.StartNew(async () =>
71 | {
72 | ulong lastWaitIndex = 0;
73 | do
74 | {
75 | try
76 | {
77 | var serviceQueryResult = await _client.Catalog.Service(Options.ServiceName, "", new QueryOptions()
78 | {
79 | WaitTime = TimeSpan.FromSeconds(30),
80 | WaitIndex = lastWaitIndex
81 | });
82 | var waitIndex = serviceQueryResult.LastIndex;
83 | if (lastWaitIndex <= 0)
84 | {
85 | lastWaitIndex = waitIndex;
86 | continue;
87 | }
88 | if (waitIndex == lastWaitIndex)
89 | continue;
90 |
91 | // 重置服务
92 | lastWaitIndex = waitIndex;
93 | if (Watched != null)
94 | Watched.Invoke();
95 | }
96 | catch { }
97 |
98 | } while (true);
99 | });
100 | }
101 | #endregion
102 | }
103 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/EndpointStrategy/IEndpointStrategy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Overt.Core.Grpc.H2
5 | {
6 | ///
7 | /// 单例使用
8 | ///
9 | public interface IEndpointStrategy
10 | {
11 | ///
12 | /// 添加服务发现
13 | ///
14 | ///
15 | void AddServiceDiscovery(IEndpointDiscovery serviceDiscovery);
16 |
17 | ///
18 | /// 获取所有可用节点
19 | ///
20 | ///
21 | ///
22 | List GetChannelWrappers(string serviceName);
23 |
24 | ///
25 | /// 获取所有可用节点
26 | ///
27 | ///
28 | ///
29 | List GetTargets(string serviceName);
30 |
31 | ///
32 | /// 获取
33 | ///
34 | ///
35 | ///
36 | ChannelWrapper GetChannelWrapper(string serviceName);
37 |
38 | ///
39 | /// 移除
40 | ///
41 | ///
42 | ///
43 | void Revoke(string serviceName, ChannelWrapper channel);
44 |
45 | ///
46 | /// 定时检测
47 | ///
48 | void InitCheckTimer();
49 |
50 | ///
51 | /// 节点有变动
52 | ///
53 | Action NodeChanged { get; set; }
54 | }
55 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/Entity/Exitus.cs:
--------------------------------------------------------------------------------
1 | namespace Overt.Core.Grpc.H2
2 | {
3 | ///
4 | /// 出口类
5 | ///
6 | public class Exitus
7 | {
8 | ///
9 | /// 构造函数
10 | ///
11 | ///
12 | ///
13 | public Exitus(string serviceName, IEndpointStrategy endpointStrategy)
14 | {
15 | ServiceName = serviceName;
16 | EndpointStrategy = endpointStrategy;
17 | }
18 |
19 | ///
20 | /// 服务名称
21 | ///
22 | public string ServiceName { get; set; }
23 | ///
24 | /// 策略
25 | ///
26 | public IEndpointStrategy EndpointStrategy { get; set; }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/NET5_0_OR_GREATER/Balancer/RandomBalancer.cs:
--------------------------------------------------------------------------------
1 | #if NET5_0_OR_GREATER
2 | using Grpc.Net.Client.Balancer;
3 | using Microsoft.Extensions.Logging;
4 | using System.Collections.Generic;
5 |
6 | namespace Overt.Core.Grpc.H2
7 | {
8 | public class RandomBalancer : SubchannelsLoadBalancer
9 | {
10 | public RandomBalancer(IChannelControlHelper controller, ILoggerFactory loggerFactory)
11 | : base(controller, loggerFactory)
12 | {
13 | }
14 |
15 | protected override SubchannelPicker CreatePicker(IReadOnlyList readySubchannels)
16 | {
17 | return new RandomPicker(readySubchannels);
18 | }
19 | }
20 | }
21 | #endif
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/NET5_0_OR_GREATER/Balancer/RandomBalancerFactory.cs:
--------------------------------------------------------------------------------
1 | #if NET5_0_OR_GREATER
2 | using Grpc.Net.Client.Balancer;
3 |
4 | namespace Overt.Core.Grpc.H2
5 | {
6 | public class RandomBalancerFactory : LoadBalancerFactory
7 | {
8 | public override string Name => "random";
9 |
10 | public override LoadBalancer Create(LoadBalancerOptions options)
11 | {
12 | return new RandomBalancer(options.Controller, options.LoggerFactory);
13 | }
14 | }
15 | }
16 | #endif
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/NET5_0_OR_GREATER/Balancer/RandomPicker.cs:
--------------------------------------------------------------------------------
1 | #if NET5_0_OR_GREATER
2 | using Grpc.Net.Client.Balancer;
3 | using System.Collections.Generic;
4 | using System.Threading;
5 |
6 | namespace Overt.Core.Grpc.H2
7 | {
8 | public class RandomPicker : SubchannelPicker
9 | {
10 | static private long _times = 0;
11 | private readonly IReadOnlyList _subchannels;
12 |
13 | public RandomPicker(IReadOnlyList subchannels)
14 | {
15 | _subchannels = subchannels;
16 | }
17 |
18 | public override PickResult Pick(PickContext context)
19 | {
20 | var subChannels = _subchannels[(int)(Interlocked.Increment(ref _times) % _subchannels.Count)];
21 | return PickResult.ForSubchannel(subChannels);
22 | }
23 | }
24 | }
25 | #endif
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/NET5_0_OR_GREATER/Resolver/InternalResolver.cs:
--------------------------------------------------------------------------------
1 | #if NET5_0_OR_GREATER
2 | using Grpc.Net.Client.Balancer;
3 | using Microsoft.Extensions.Logging;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace Overt.Core.Grpc.H2
10 | {
11 | ///
12 | /// 静态注入
13 | ///
14 | public class InternalResolver : PollingResolver
15 | {
16 | private readonly Uri _address;
17 | private readonly Exitus _exitus;
18 | private readonly StrategyFactory _strategyFactory;
19 |
20 | public InternalResolver(Uri address, ILoggerFactory loggerFactory, StrategyFactory strategyFactory) : base(loggerFactory)
21 | {
22 | _address = address;
23 | _strategyFactory = strategyFactory;
24 |
25 | var serviceName = _address.LocalPath.Replace("/", "");
26 | _exitus = _strategyFactory.GetExitus(serviceName);
27 | if (_exitus == null)
28 | throw new Exception($"{serviceName} 配置异常");
29 |
30 | _exitus.EndpointStrategy.NodeChanged = () =>
31 | {
32 | Refresh();
33 | };
34 | }
35 |
36 | protected override Task ResolveAsync(CancellationToken cancellationToken)
37 | {
38 | var targets = _exitus.EndpointStrategy.GetTargets(_exitus.ServiceName);
39 | if ((targets?.Count ?? 0) <= 0)
40 | {
41 | Listener(ResolverResult.ForResult(null));
42 | return Task.CompletedTask;
43 | }
44 |
45 | var addresses = new List();
46 | foreach (var target in targets ?? new List())
47 | {
48 | var arr = target.Split(':');
49 | var host = arr[0];
50 | var port = 80;
51 | if (arr.Length == 2 && int.TryParse(arr[1], out int p) && p > 0)
52 | port = p;
53 |
54 | addresses.Add(new BalancerAddress(host, port));
55 | }
56 | Listener(ResolverResult.ForResult(addresses));
57 | return Task.CompletedTask;
58 | }
59 | }
60 | }
61 | #endif
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/NET5_0_OR_GREATER/Resolver/InternalResolverFactory.cs:
--------------------------------------------------------------------------------
1 | #if NET5_0_OR_GREATER
2 | using Grpc.Net.Client.Balancer;
3 |
4 | namespace Overt.Core.Grpc.H2
5 | {
6 | public class InternalResolverFactory : ResolverFactory
7 | {
8 | StrategyFactory _strategyFactory;
9 | public InternalResolverFactory(StrategyFactory strategyFactory)
10 | {
11 | _strategyFactory = strategyFactory;
12 | }
13 |
14 | public override string Name => "internal";
15 |
16 | public override Resolver Create(ResolverOptions options)
17 | {
18 | return new InternalResolver(options.Address, options.LoggerFactory, _strategyFactory);
19 | }
20 | }
21 | }
22 | #endif
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/ServicePolicy/ServiceBlackPolicy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Linq;
4 |
5 | namespace Overt.Core.Grpc.H2
6 | {
7 | ///
8 | /// 服务黑名单策略
9 | ///
10 | public class ServiceBlackPolicy
11 | {
12 | public readonly static ConcurrentDictionary _blacklist = new ConcurrentDictionary();
13 |
14 | ///
15 | /// 黑名单
16 | ///
17 | ///
18 | public static void Add(string serviceName, string target)
19 | {
20 | var key = $"{serviceName}_{target}";
21 | var now = DateTime.UtcNow;
22 | _blacklist.AddOrUpdate(key, k => now, (k, old) => now);
23 | }
24 |
25 | ///
26 | /// 是否在黑名单
27 | ///
28 | ///
29 | ///
30 | public static bool In(string serviceName, string target)
31 | {
32 | var key = $"{serviceName}_{target}";
33 | if (_blacklist.TryGetValue(key, out DateTime lastFailure))
34 | {
35 | if (DateTime.UtcNow - lastFailure < ClientTimespan.BlacklistPeriod)
36 | return true;
37 |
38 | _blacklist.TryRemove(key, out lastFailure);
39 | }
40 | return false;
41 | }
42 |
43 | ///
44 | /// 服务是否有节点存在黑名单
45 | ///
46 | ///
47 | ///
48 | public static bool Exist(string serviceName)
49 | {
50 | return _blacklist.Keys.Any(oo => oo.StartsWith(serviceName));
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Client/ServicePolicy/ServicePollingPolicy.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Net.Client;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading;
5 |
6 | namespace Overt.Core.Grpc.H2
7 | {
8 | internal class ServicePollingPolicy
9 | {
10 | static private long _times = 0;
11 |
12 | ///
13 | /// 轮询策略
14 | ///
15 | ///
16 | ///
17 | public static ChannelWrapper Random(List channels)
18 | {
19 | if ((channels?.Count ?? 0) <= 0)
20 | return null;
21 |
22 | return channels[(int)(Interlocked.Increment(ref _times) % channels.Count)];
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Config/Consul/ConsulServerSection.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Overt.Core.Grpc.H2
3 | {
4 | ///
5 | ///
6 | ///
7 | ///
8 | ///
9 | public class ConsulServerSection
10 | {
11 | ///
12 | /// grpc配置
13 | ///
14 | public ConsulServiceElement Service
15 | {
16 | get; set;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Config/Consul/ConsulServiceElement.cs:
--------------------------------------------------------------------------------
1 | namespace Overt.Core.Grpc.H2
2 | {
3 | ///
4 | ///
5 | ///
6 | public class ConsulServiceElement
7 | {
8 | ///
9 | /// consul地址
10 | ///
11 | public string Address
12 | {
13 | get; set;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Config/Grpc/Client/GrpcClientSection.cs:
--------------------------------------------------------------------------------
1 | namespace Overt.Core.Grpc.H2
2 | {
3 | ///
4 | /// Grpc配置
5 | ///
6 | ///
7 | ///
8 | ///
9 | ///
10 | ///
11 | ///
12 | ///
13 | public class GrpcClientSection
14 | {
15 | ///
16 | /// grpc配置
17 | ///
18 | public GrpcServiceElement Service { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Config/Grpc/Client/GrpcDiscoveryElement.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Overt.Core.Grpc.H2
4 | {
5 | ///
6 | /// 服务发现
7 | ///
8 | public class GrpcDiscoveryElement
9 | {
10 | ///
11 | /// 服务器集合。
12 | ///
13 | public List EndPoints { get; set; }
14 |
15 | ///
16 | /// 注册配置
17 | ///
18 | public ConsulElement Consul { get; set; }
19 | }
20 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Config/Grpc/Client/GrpcEndpointElement.cs:
--------------------------------------------------------------------------------
1 | namespace Overt.Core.Grpc.H2
2 | {
3 | ///
4 | /// IP地址
5 | ///
6 | public class GrpcEndpointElement
7 | {
8 | ///
9 | /// 服务IP
10 | ///
11 | public string Host
12 | {
13 | get; set;
14 | }
15 | ///
16 | /// 端口
17 | ///
18 | public int Port
19 | {
20 | get; set;
21 | }
22 |
23 | ///
24 | /// to string.
25 | ///
26 | ///
27 | public override string ToString()
28 | {
29 | return string.Concat(this.Host, ":", this.Port.ToString());
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Config/Grpc/Client/GrpcServiceElement.cs:
--------------------------------------------------------------------------------
1 | namespace Overt.Core.Grpc.H2
2 | {
3 | public class GrpcServiceElement
4 | {
5 | ///
6 | /// 服务名称
7 | ///
8 | public string Name { get; set; }
9 |
10 | ///
11 | /// 服务名称
12 | ///
13 | public string Scheme { get; set; } = "http";
14 |
15 | ///
16 | /// 服务发现
17 | ///
18 | public GrpcDiscoveryElement Discovery { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Config/Grpc/Common/ConsulElement.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Overt.Core.Grpc.H2
3 | {
4 | ///
5 | /// Consul
6 | ///
7 | public class ConsulElement
8 | {
9 | ///
10 | /// 路径
11 | ///
12 | public string Path { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Config/Grpc/Service/GrpcServerSection.cs:
--------------------------------------------------------------------------------
1 | namespace Overt.Core.Grpc.H2
2 | {
3 | ///
4 | /// Grpc配置
5 | ///
6 | ///
7 | ///
8 | ///
9 | ///
10 | ///
11 | ///
12 | ///
13 | public class GrpcServerSection
14 | {
15 | ///
16 | ///
17 | ///
18 | public ServiceElement Service { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Config/Grpc/Service/ServiceElement.cs:
--------------------------------------------------------------------------------
1 | namespace Overt.Core.Grpc.H2
2 | {
3 | public class ServiceElement
4 | {
5 | ///
6 | /// 服务名称
7 | ///
8 | public string Name { get; set; }
9 |
10 | ///
11 | /// Host 默认 0.0.0.0
12 | /// 优先级1
13 | ///
14 | public string Host { get; set; }
15 |
16 | ///
17 | /// 端口号
18 | ///
19 | public int Port { get; set; }
20 |
21 | ///
22 | /// host环境变量名称
23 | /// 优先级2
24 | ///
25 | public string HostEnv { get; set; }
26 |
27 | ///
28 | /// 注册配置
29 | ///
30 | public ConsulElement Consul { get; set; }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Config/Util/ConfigBuilder.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Configuration;
2 | using System;
3 | using System.IO;
4 |
5 | namespace Overt.Core.Grpc.H2
6 | {
7 | ///
8 | /// 配置文件读取
9 | ///
10 | internal class ConfigBuilder
11 | {
12 | public static Action ConfigureDelegate;
13 |
14 | ///
15 | /// 获取Server配置对象
16 | ///
17 | /// 节点名称
18 | ///
19 | ///
20 | public static T Build(string sectionName, string configPath = "") where T : class, new()
21 | {
22 | if (string.IsNullOrWhiteSpace(configPath) || !configPath.EndsWith(".json"))
23 | configPath = "appsettings.json";
24 |
25 | configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configPath);
26 | if (!File.Exists(configPath))
27 | throw new Exception($"overt: when resolve configpath, configpath file is not exist... [{configPath}]");
28 |
29 | var section = new T();
30 | var builder = new ConfigurationBuilder()
31 | .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
32 | .AddJsonFile(configPath)
33 | .AddEnvironmentVariables();
34 | ConfigureDelegate?.Invoke(builder);
35 | var configuration = builder.Build();
36 | configuration.GetSection(sectionName).Bind(section);
37 | return section;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Config/Util/Constants.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Grpc.Net.Client;
3 |
4 | namespace Overt.Core.Grpc.H2
5 | {
6 | public class Constants
7 | {
8 | ///
9 | /// Grpc Server 节点名称
10 | ///
11 | internal const string GrpcServerSectionName = "GrpcServer";
12 | ///
13 | /// Grpc Consul 节点名称
14 | ///
15 | internal const string ConsulServerSectionName = "ConsulServer";
16 | ///
17 | /// Grpc Client 节点名称
18 | ///
19 | internal const string GrpcClientSectionName = "GrpcClient";
20 |
21 | ///
22 | /// 默认的通道配置
23 | ///
24 | public static GrpcChannelOptions DefaultChannelOptions = new GrpcChannelOptions()
25 | {
26 | Credentials = ChannelCredentials.Insecure,
27 | MaxReceiveMessageSize = int.MaxValue,
28 | MaxSendMessageSize = int.MaxValue,
29 | };
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Overt.Core.Grpc.H2.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.1;netcoreapp3.0;net5.0;net6.0
5 | true
6 | 2.0.2
7 | 基于grpc.net驱动结合consul实现微服务注册与发现
8 | https://github.com/overtly/core-grpc.git
9 | 增加停止服务的HostedService
10 | 9.0
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Service/ConsulTimespan.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Overt.Core.Grpc.H2
4 | {
5 | internal static class ConsulTimespan
6 | {
7 | ///
8 | /// 健康检测时间 10s
9 | ///
10 | public static readonly TimeSpan CheckInterval = TimeSpan.FromSeconds(10);
11 |
12 | ///
13 | /// 定时上报时间 30s
14 | ///
15 | public static readonly TimeSpan SelfCheckInterval = TimeSpan.FromSeconds(30);
16 |
17 | ///
18 | /// 移除服务的时效 15s
19 | ///
20 | public static readonly TimeSpan CriticalInterval = TimeSpan.FromSeconds(20);
21 | }
22 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Service/Entity/Entry.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Overt.Core.Grpc.H2
4 | {
5 | ///
6 | /// 注册成功后对象
7 | ///
8 | public sealed class Entry : IDisposable
9 | {
10 | private readonly ConsulRegister _serverRegister;
11 |
12 | public Entry(ConsulRegister serverRegister, string serviceId)
13 | {
14 | ServiceId = serviceId;
15 | _serverRegister = serverRegister;
16 | }
17 |
18 | public string ServiceId { get; }
19 |
20 | public void Dispose()
21 | {
22 | _serverRegister.Deregister(ServiceId);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Service/Entity/GrpcOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 |
4 | namespace Overt.Core.Grpc.H2
5 | {
6 | ///
7 | /// Grpc配置信息
8 | ///
9 | public class GrpcOptions
10 | {
11 | ///
12 | /// 监听地址
13 | ///
14 | internal string ListenAddress { get; set; }
15 |
16 | ///
17 | /// 配置文件地址
18 | /// default: appsettings.json
19 | ///
20 | public string ConfigPath { get; set; }
21 |
22 | ///
23 | /// ServiceId生成
24 | ///
25 | public Func GenServiceId { get; set; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/Service/GrpcHostedService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Hosting;
2 | using Microsoft.Extensions.Logging;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 |
6 | namespace Overt.Core.Grpc.H2
7 | {
8 | public class GrpcHostedService : IHostedService
9 | {
10 | ILogger _logger;
11 | public GrpcHostedService(ILogger logger)
12 | {
13 | _logger = logger;
14 | }
15 |
16 | public Task StartAsync(CancellationToken cancellationToken)
17 | {
18 | return Task.FromResult(true);
19 | }
20 |
21 | public Task StopAsync(CancellationToken cancellationToken)
22 | {
23 | return Task.Factory.StartNew(() =>
24 | {
25 | RegisterFactory.RemoveConsul(ex =>
26 | {
27 | _logger.LogError(ex, $"Overt.Core.Grpc.H2 移除注册异常");
28 | });
29 | });
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/dllconfigs/clientsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcClient": {
3 | "Service": {
4 | "Name": "grpcservice",
5 | "Scheme": "http",
6 | "Discovery": {
7 | "EndPoints": [
8 | {
9 | "Host": "",
10 | "Port": 0
11 | }
12 | ],
13 | "Consul": {
14 | "Path": "dllconfigs/consulsettings.json"
15 | }
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/dllconfigs/consulsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConsulServer": {
3 | "Service": {
4 | "Address": "http://consul.g.lan"
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc.H2/dllconfigs/grpcsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "GrpcServer": {
3 | "Service": {
4 | "Name": "grpcservice",
5 | "HostEnv": "serviceaddress", // HostEnv > Host:Port > InternetHost:Port
6 | "Host": "",
7 | "Port": 10001,
8 | "Consul": {
9 | "Path": "dllconfigs/consulsettings.json"
10 | }
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/CallInvoker/ServerCallInvoker.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Grpc.Core.Utils;
3 |
4 | namespace Overt.Core.Grpc
5 | {
6 | public class ServerCallInvoker : CallInvoker
7 | {
8 | public string ServiceId;
9 | public Channel Channel;
10 | public ServerCallInvoker(string serviceId, Channel channel)
11 | {
12 | ServiceId = serviceId;
13 | Channel = GrpcPreconditions.CheckNotNull(channel);
14 | }
15 |
16 | public override TResponse BlockingUnaryCall(Method method, string host, CallOptions options, TRequest request)
17 | {
18 | return Calls.BlockingUnaryCall(CreateCall(method, host, options), request);
19 | }
20 |
21 | public override AsyncUnaryCall AsyncUnaryCall(Method method, string host, CallOptions options, TRequest request)
22 | {
23 | return Calls.AsyncUnaryCall(CreateCall(method, host, options), request);
24 | }
25 |
26 | public override AsyncServerStreamingCall AsyncServerStreamingCall(Method method, string host, CallOptions options, TRequest request)
27 | {
28 | return Calls.AsyncServerStreamingCall(CreateCall(method, host, options), request);
29 | }
30 |
31 | public override AsyncClientStreamingCall AsyncClientStreamingCall(Method method, string host, CallOptions options)
32 | {
33 | return Calls.AsyncClientStreamingCall(CreateCall(method, host, options));
34 | }
35 |
36 | public override AsyncDuplexStreamingCall AsyncDuplexStreamingCall(Method method, string host, CallOptions options)
37 | {
38 | return Calls.AsyncDuplexStreamingCall(CreateCall(method, host, options));
39 | }
40 |
41 | protected virtual CallInvocationDetails CreateCall(Method method, string host, CallOptions options)
42 | where TRequest : class
43 | where TResponse : class
44 | {
45 | //if (options.Headers?.Any(oo => oo.Key == Constants.MetadataKey_ChannelTarget) ?? false)
46 | //{
47 | // var entry = options.Headers.First(oo => oo.Key == Constants.MetadataKey_ChannelTarget);
48 | // Channel = new Channel(entry.Value, ChannelCredentials.Insecure, Constants.DefaultChannelOptions);
49 | //}
50 | return new CallInvocationDetails(Channel, method, host, options);
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/ClientGenerate/GrpcClient.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using System;
3 | using System.Collections.Concurrent;
4 | using System.Collections.Generic;
5 |
6 | namespace Overt.Core.Grpc
7 | {
8 | ///
9 | /// GrpcClient管理类
10 | ///
11 | public class GrpcClient : IGrpcClient where T : ClientBase
12 | {
13 | readonly IGrpcClientFactory _factory;
14 | readonly ConcurrentDictionary _clientCache = new ConcurrentDictionary();
15 | public GrpcClient(IGrpcClientFactory factory)
16 | {
17 | _factory = factory;
18 | }
19 |
20 | ///
21 | /// 获取
22 | ///
23 | public T Client
24 | {
25 | get
26 | {
27 | return _clientCache.GetOrAdd(typeof(T), key => _factory.Get());
28 | }
29 | }
30 |
31 | ///
32 | /// 构造一个新的对象
33 | ///
34 | ///
35 | ///
36 | public T CreateClient(Func, ServerCallInvoker> callInvokers)
37 | {
38 | return _factory.Get(callInvokers);
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/ClientGenerate/GrpcClientFactory.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using System.Collections.Generic;
3 | using Overt.Core.Grpc.Intercept;
4 | #if ASP_NET_CORE
5 | using Microsoft.Extensions.Options;
6 | #endif
7 | using System;
8 |
9 | namespace Overt.Core.Grpc
10 | {
11 | ///
12 | /// 客户端工厂
13 | ///
14 | public class GrpcClientFactory : IGrpcClientFactory where T : ClientBase
15 | {
16 | private GrpcClientOptions _options;
17 |
18 | #if ASP_NET_CORE
19 | public GrpcClientFactory(IOptions> options)
20 | {
21 | _options = options?.Value;
22 | InitOptions();
23 | }
24 | #else
25 | public GrpcClientFactory(GrpcClientOptions options)
26 | {
27 | _options = new GrpcClientOptions(options);
28 | InitOptions();
29 | }
30 | #endif
31 |
32 | ///
33 | /// 构造实例
34 | ///
35 | ///
36 | ///
37 | public T Get(Func, ServerCallInvoker> callInvokers = null)
38 | {
39 | var exitus = StrategyFactory.Get(_options);
40 | var callInvoker = new ClientCallInvoker(_options, exitus.EndpointStrategy, callInvokers);
41 | var client = (T)Activator.CreateInstance(typeof(T), callInvoker);
42 | return client;
43 | }
44 |
45 | #region Private Method
46 | ///
47 | /// 初始化配置
48 | ///
49 | private void InitOptions()
50 | {
51 | _options = _options ?? new GrpcClientOptions();
52 | _options.ConfigPath = GetConfigPath(_options.ConfigPath);
53 | if (_options.Tracer != null)
54 | _options.Interceptors.Add(new ClientTracerInterceptor(_options.Tracer));
55 | }
56 |
57 | ///
58 | /// 获取命名空间
59 | ///
60 | ///
61 | private string GetConfigPath(string configPath)
62 | {
63 | #if ASP_NET_CORE
64 | if (string.IsNullOrEmpty(configPath))
65 | configPath = $"dllconfigs/{typeof(T).Namespace}.dll.json";
66 | #else
67 | if (string.IsNullOrEmpty(configPath))
68 | configPath = $"dllconfigs/{typeof(T).Namespace}.dll.config";
69 | #endif
70 |
71 | return configPath;
72 | }
73 | #endregion
74 | }
75 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/ClientGenerate/GrpcClientOptions.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Grpc.Core.Interceptors;
3 | using Overt.Core.Grpc.Intercept;
4 | using System.Collections.Generic;
5 |
6 | namespace Overt.Core.Grpc
7 | {
8 | ///
9 | /// 全局客户端配置模型
10 | ///
11 | public class GrpcClientOptions
12 | {
13 | ///
14 | /// Json文件
15 | /// defaultValue: dllconfigs/clientsettings.json
16 | ///
17 | public string ConfigPath { get; set; }
18 |
19 | ///
20 | /// tracer拦截器
21 | ///
22 | public IClientTracer Tracer { get; set; }
23 |
24 | ///
25 | /// 服务名称
26 | ///
27 | public string ServiceName { get; set; }
28 |
29 | ///
30 | /// 最大重试次数
31 | ///
32 | public int MaxRetry { get; set; }
33 |
34 | ///
35 | /// Gets a list of instances used to configure a gRPC client pipeline.
36 | ///
37 | public List Interceptors { get; } = new List();
38 |
39 | ///
40 | /// 配置ChannelOptions
41 | ///
42 | public List ChannelOptions { get; set; }
43 | }
44 |
45 | ///
46 | /// 单服务客户端配置
47 | ///
48 | public class GrpcClientOptions : GrpcClientOptions where T : ClientBase
49 | {
50 | public GrpcClientOptions()
51 | {
52 |
53 | }
54 |
55 | public GrpcClientOptions(GrpcClientOptions options)
56 | {
57 | if (options == null)
58 | return;
59 |
60 | ConfigPath = options.ConfigPath;
61 | Tracer = options.Tracer;
62 | ServiceName = options.ServiceName;
63 | MaxRetry = options.MaxRetry;
64 | ChannelOptions = options.ChannelOptions;
65 | if (options.Interceptors?.Count > 0)
66 | Interceptors.AddRange(options.Interceptors);
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/ClientGenerate/Interface/IGrpcClient.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | namespace Overt.Core.Grpc
6 | {
7 | ///
8 | /// 接口类
9 | ///
10 | public interface IGrpcClient where T : ClientBase
11 | {
12 | ///
13 | /// 单例对象
14 | ///
15 | T Client { get; }
16 |
17 | ///
18 | /// 每次构造一个新的对象
19 | ///
20 | ///
21 | ///
22 | T CreateClient(Func, ServerCallInvoker> callInvokers);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/ClientGenerate/Interface/IGrpcClientFactory.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Overt.Core.Grpc.Intercept;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace Overt.Core.Grpc
8 | {
9 | ///
10 | /// 工厂类接口
11 | ///
12 | ///
13 | public interface IGrpcClientFactory where T : ClientBase
14 | {
15 | ///
16 | /// 获取Client对象
17 | ///
18 | ///
19 | T Get(Func, ServerCallInvoker> callInvokers = null);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/ClientTimespan.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Overt.Core.Grpc
4 | {
5 | internal static class ClientTimespan
6 | {
7 | ///
8 | /// 重置服务时间 30s
9 | ///
10 | public static readonly TimeSpan ResetInterval = TimeSpan.FromSeconds(30);
11 |
12 | ///
13 | /// 黑名单时效 2m
14 | ///
15 | public static readonly TimeSpan BlacklistPeriod = TimeSpan.FromMinutes(2);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/EndpointDiscovery/IEndpointDiscovery.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Overt.Core.Grpc
5 | {
6 | ///
7 | /// 重点服务发现接口
8 | ///
9 | public interface IEndpointDiscovery
10 | {
11 | ///
12 | /// 配置信息
13 | ///
14 | GrpcClientOptions Options { get; set; }
15 |
16 | ///
17 | /// 监听变动的方法
18 | ///
19 | Action Watched { get; set; }
20 |
21 | ///
22 | /// 获取服务可连接终结点
23 | ///
24 | ///
25 | List> FindServiceEndpoints(bool filterBlack = true);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/EndpointDiscovery/IPEndpointDiscovery.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace Overt.Core.Grpc
6 | {
7 | ///
8 | /// IP服务发现
9 | ///
10 | internal class IPEndpointDiscovery : IEndpointDiscovery
11 | {
12 | #region Constructor
13 | private readonly List> _ipEndPoints;
14 | public IPEndpointDiscovery(GrpcClientOptions options, List> ipEndPoints)
15 | {
16 | if ((ipEndPoints?.Count ?? 0) <= 0)
17 | throw new ArgumentNullException("no ip endpoints availble");
18 |
19 | _ipEndPoints = ipEndPoints;
20 |
21 | Options = options;
22 | }
23 | #endregion
24 |
25 | #region Public Property
26 | public GrpcClientOptions Options { get; set; }
27 |
28 | public Action Watched { get; set; }
29 | #endregion
30 |
31 | #region Public Method
32 | public List> FindServiceEndpoints(bool filterBlack = true)
33 | {
34 | if ((_ipEndPoints?.Count ?? 0) <= 0)
35 | throw new ArgumentOutOfRangeException("endpoint not provide");
36 |
37 | var targets = _ipEndPoints.Select(x => Tuple.Create("", $"{x.Item1}:{x.Item2}"))
38 | .Where(target => !ServiceBlackPolicy.In(Options.ServiceName, target.Item2) || !filterBlack)
39 | .ToList();
40 | return targets;
41 | }
42 | #endregion
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/EndpointDiscovery/StickyEndpointDiscovery.cs:
--------------------------------------------------------------------------------
1 | using Consul;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Threading.Tasks;
7 |
8 | namespace Overt.Core.Grpc
9 | {
10 | ///
11 | /// 注册中心服务发现
12 | ///
13 | internal sealed class StickyEndpointDiscovery : IEndpointDiscovery
14 | {
15 | #region 构造函数
16 | private readonly ConsulClient _client;
17 | public StickyEndpointDiscovery(GrpcClientOptions options, ConsulServiceElement consulOption, bool startWatch = true)
18 | {
19 | if (string.IsNullOrEmpty(consulOption?.Address))
20 | throw new ArgumentNullException("consul address");
21 |
22 | _client = new ConsulClient((cfg) =>
23 | {
24 | var uriBuilder = new UriBuilder(consulOption.Address);
25 |
26 | cfg.Address = uriBuilder.Uri;
27 | cfg.Token = consulOption.Token;
28 | });
29 |
30 | Options = options;
31 |
32 | if (startWatch)
33 | StartWatchService();
34 | }
35 | #endregion
36 |
37 | #region Public Property
38 | public GrpcClientOptions Options { get; set; }
39 |
40 | public Action Watched { get; set; }
41 | #endregion
42 |
43 | #region Public Method
44 | public List> FindServiceEndpoints(bool filterBlack = true)
45 | {
46 | if (_client == null)
47 | throw new ArgumentNullException("consul client");
48 |
49 | var targets = new List>();
50 | try
51 | {
52 | var r = _client.Health.Service(Options.ServiceName, "", true).Result;
53 | if (r.StatusCode != HttpStatusCode.OK)
54 | throw new ApplicationException($"failed to query consul server");
55 |
56 | targets = r.Response
57 | .Select(x => Tuple.Create(x.Service.ID, $"{x.Service.Address}:{x.Service.Port}"))
58 | .Where(target => !ServiceBlackPolicy.In(Options.ServiceName, target.Item2) || !filterBlack)
59 | .ToList();
60 | }
61 | catch { }
62 | return targets;
63 | }
64 | #endregion
65 |
66 | #region Private Method
67 | ///
68 | /// 开始监听服务变动
69 | ///
70 | private void StartWatchService()
71 | {
72 | Task.Factory.StartNew(async () =>
73 | {
74 | ulong lastWaitIndex = 0;
75 | do
76 | {
77 | try
78 | {
79 | var serviceQueryResult = await _client.Catalog.Service(Options.ServiceName, "", new QueryOptions()
80 | {
81 | WaitTime = TimeSpan.FromSeconds(30),
82 | WaitIndex = lastWaitIndex
83 | });
84 | var waitIndex = serviceQueryResult.LastIndex;
85 | if (lastWaitIndex <= 0)
86 | {
87 | lastWaitIndex = waitIndex;
88 | continue;
89 | }
90 | if (waitIndex == lastWaitIndex)
91 | continue;
92 |
93 | // 重置服务
94 | lastWaitIndex = waitIndex;
95 | if (Watched != null)
96 | Watched.Invoke();
97 | }
98 | catch { }
99 |
100 | } while (true);
101 | });
102 | }
103 | #endregion
104 | }
105 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/EndpointStrategy/IEndpointStrategy.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using System.Collections.Generic;
3 |
4 | namespace Overt.Core.Grpc
5 | {
6 | ///
7 | /// 单例使用
8 | ///
9 | public interface IEndpointStrategy
10 | {
11 | ///
12 | /// 添加服务发现
13 | ///
14 | ///
15 | void AddServiceDiscovery(IEndpointDiscovery serviceDiscovery);
16 |
17 | ///
18 | /// 获取所有可用节点
19 | ///
20 | ///
21 | ///
22 | List GetCallInvokers(string serviceName);
23 |
24 | ///
25 | /// 获取
26 | ///
27 | ///
28 | ///
29 | ServerCallInvoker GetCallInvoker(string serviceName);
30 |
31 | ///
32 | /// 移除
33 | ///
34 | ///
35 | ///
36 | void Revoke(string serviceName, ServerCallInvoker failedCallInvoker);
37 |
38 | ///
39 | /// 定时检测
40 | ///
41 | void InitCheckTimer();
42 | }
43 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/ServicePolicy/ServiceBlackPolicy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Linq;
4 |
5 | namespace Overt.Core.Grpc
6 | {
7 | ///
8 | /// 服务黑名单策略
9 | ///
10 | public class ServiceBlackPolicy
11 | {
12 | public readonly static ConcurrentDictionary _blacklist = new ConcurrentDictionary();
13 |
14 | ///
15 | /// 黑名单
16 | ///
17 | ///
18 | public static void Add(string serviceName, string target)
19 | {
20 | var key = $"{serviceName}_{target}";
21 | var now = DateTime.UtcNow;
22 | _blacklist.AddOrUpdate(key, k => now, (k, old) => now);
23 | }
24 |
25 | ///
26 | /// 是否在黑名单
27 | ///
28 | ///
29 | ///
30 | public static bool In(string serviceName, string target)
31 | {
32 | var key = $"{serviceName}_{target}";
33 | if (_blacklist.TryGetValue(key, out DateTime lastFailure))
34 | {
35 | if (DateTime.UtcNow - lastFailure < ClientTimespan.BlacklistPeriod)
36 | return true;
37 |
38 | _blacklist.TryRemove(key, out lastFailure);
39 | }
40 | return false;
41 | }
42 |
43 | ///
44 | /// 服务是否有节点存在黑名单
45 | ///
46 | ///
47 | ///
48 | public static bool Exist(string serviceName)
49 | {
50 | return _blacklist.Keys.Any(oo => oo.StartsWith(serviceName));
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Client/ServicePolicy/ServicePollingPolicy.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Threading;
4 |
5 | namespace Overt.Core.Grpc
6 | {
7 | internal class ServicePollingPolicy
8 | {
9 | static private long _times = 0;
10 |
11 | ///
12 | /// 轮询策略
13 | ///
14 | ///
15 | ///
16 | public static ServerCallInvoker Random(List callInvokers)
17 | {
18 | if ((callInvokers?.Count ?? 0) <= 0)
19 | return null;
20 |
21 | return callInvokers[(int)(Interlocked.Increment(ref _times) % callInvokers.Count)];
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Consul/ConsulServerSection.cs:
--------------------------------------------------------------------------------
1 | #if !ASP_NET_CORE
2 | using System.Configuration;
3 | #endif
4 |
5 | namespace Overt.Core.Grpc
6 | {
7 | ///
8 | ///
9 | ///
10 | ///
11 | ///
12 | public class ConsulServerSection
13 | #if !ASP_NET_CORE
14 | : ConfigurationSection
15 | #endif
16 | {
17 | ///
18 | /// grpc配置
19 | ///
20 | #if !ASP_NET_CORE
21 | [ConfigurationProperty("service", IsRequired = true)]
22 | #endif
23 | public ConsulServiceElement Service
24 | {
25 | #if !ASP_NET_CORE
26 | get { return this["service"] as ConsulServiceElement; }
27 | #else
28 | get; set;
29 | #endif
30 |
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Consul/ConsulServiceElement.cs:
--------------------------------------------------------------------------------
1 | #if !ASP_NET_CORE
2 | using System.Configuration;
3 | #endif
4 |
5 | namespace Overt.Core.Grpc
6 | {
7 | ///
8 | ///
9 | ///
10 | public class ConsulServiceElement
11 | #if !ASP_NET_CORE
12 | : ConfigurationElement
13 | #endif
14 | {
15 | ///
16 | /// consul地址
17 | ///
18 | #if !ASP_NET_CORE
19 | [ConfigurationProperty("address", IsRequired = true)]
20 | #endif
21 | public string Address
22 | {
23 | #if !ASP_NET_CORE
24 | get { return (string)this["address"]; }
25 | #else
26 | get;set;
27 | #endif
28 | }
29 | ///
30 | /// consul token
31 | ///
32 | #if !ASP_NET_CORE
33 | [ConfigurationProperty("token", IsRequired = false)]
34 | #endif
35 | public string Token
36 | {
37 | #if !ASP_NET_CORE
38 | get { return (string)this["token"]; }
39 | #else
40 | get;set;
41 | #endif
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Grpc/Client/GrpcClientSection.cs:
--------------------------------------------------------------------------------
1 | using Overt.Core.Grpc.Client;
2 | #if !ASP_NET_CORE
3 | using System.Configuration;
4 | #endif
5 |
6 | namespace Overt.Core.Grpc
7 | {
8 | ///
9 | /// Grpc配置
10 | ///
11 | ///
12 | ///
13 | ///
14 | ///
15 | ///
16 | ///
17 | ///
18 | public class GrpcClientSection
19 | #if !ASP_NET_CORE
20 | : ConfigurationSection
21 | #endif
22 | { ///
23 | /// grpc配置
24 | ///
25 | #if !ASP_NET_CORE
26 | [ConfigurationProperty("service", IsRequired = true)]
27 | #endif
28 | public GrpcServiceElement Service
29 | {
30 | #if !ASP_NET_CORE
31 | get { return this["service"] as GrpcServiceElement; }
32 | #else
33 | get; set;
34 | #endif
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Grpc/Client/GrpcDiscoveryElement.cs:
--------------------------------------------------------------------------------
1 | #if !ASP_NET_CORE
2 | using System.Configuration;
3 | #endif
4 | using System.Collections.Generic;
5 |
6 | namespace Overt.Core.Grpc
7 | {
8 | ///
9 | /// 服务发现
10 | ///
11 | public class GrpcDiscoveryElement
12 | #if !ASP_NET_CORE
13 | : ConfigurationElement
14 | #endif
15 | {
16 | ///
17 | /// 服务器集合。
18 | ///
19 | #if !ASP_NET_CORE
20 | [ConfigurationProperty("server", IsRequired = false)]
21 | public GrpcEndpointElementCollection EndPoints { get { return this["server"] as GrpcEndpointElementCollection; } }
22 | #else
23 | public List EndPoints { get; set; }
24 | #endif
25 |
26 | ///
27 | /// 注册配置
28 | ///
29 | #if !ASP_NET_CORE
30 | [ConfigurationProperty("consul", IsRequired = false)]
31 | #endif
32 | public ConsulElement Consul
33 | {
34 | #if !ASP_NET_CORE
35 | get { return this["consul"] as ConsulElement; }
36 | #else
37 | get; set;
38 | #endif
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Grpc/Client/GrpcEndpointElement.cs:
--------------------------------------------------------------------------------
1 | #if !ASP_NET_CORE
2 | using System.Configuration;
3 | #endif
4 |
5 | namespace Overt.Core.Grpc
6 | {
7 | ///
8 | /// IP地址
9 | ///
10 | public class GrpcEndpointElement
11 | #if !ASP_NET_CORE
12 | : ConfigurationElement
13 | #endif
14 | {
15 | ///
16 | /// 服务IP
17 | ///
18 | #if !ASP_NET_CORE
19 | [ConfigurationProperty("host", IsRequired = true)]
20 | #endif
21 | public string Host
22 | {
23 | #if !ASP_NET_CORE
24 | get { return (string)this["host"]; }
25 | #else
26 | get; set;
27 | #endif
28 | }
29 | ///
30 | /// 端口
31 | ///
32 | #if !ASP_NET_CORE
33 | [ConfigurationProperty("port", IsRequired = true)]
34 | #endif
35 | public int Port
36 | {
37 | #if !ASP_NET_CORE
38 | get { return (int)this["port"]; }
39 | #else
40 | get; set;
41 | #endif
42 | }
43 |
44 | ///
45 | /// to string.
46 | ///
47 | ///
48 | public override string ToString()
49 | {
50 | return string.Concat(this.Host, ":", this.Port.ToString());
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Grpc/Client/GrpcEndpointElementCollection.cs:
--------------------------------------------------------------------------------
1 | #if !ASP_NET_CORE
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Configuration;
5 | using System.Linq;
6 | using System.Net;
7 | #endif
8 |
9 | namespace Overt.Core.Grpc
10 | {
11 | #if !ASP_NET_CORE
12 | ///
13 | /// GrpcEndpoint
14 | ///
15 | [ConfigurationCollection(typeof(GrpcEndpointElement), AddItemName = "endpoint")]
16 | public class GrpcEndpointElementCollection : ConfigurationElementCollection
17 | {
18 | ///
19 | /// 新节点
20 | ///
21 | ///
22 | protected override ConfigurationElement CreateNewElement()
23 | {
24 | return new GrpcEndpointElement();
25 | }
26 |
27 | protected override object GetElementKey(ConfigurationElement element)
28 | {
29 | return (element as GrpcEndpointElement).ToString();
30 | }
31 |
32 | ///
33 | /// 获取指定位置的对象。
34 | ///
35 | ///
36 | ///
37 | public GrpcEndpointElement this[int i]
38 | {
39 | get { return BaseGet(i) as GrpcEndpointElement; }
40 | }
41 |
42 | ///
43 | /// to array
44 | ///
45 | ///
46 | public Tuple[] ToArray()
47 | {
48 | var endpoints = new Tuple[base.Count];
49 | for (int i = 0, l = this.Count; i < l; i++)
50 | {
51 | var child = this[i];
52 | endpoints[i] = new Tuple(child.Host, child.Port);
53 | }
54 | return endpoints;
55 | }
56 |
57 | public List> ToList()
58 | {
59 | return this.ToArray().ToList();
60 | }
61 | }
62 | #endif
63 | }
64 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Grpc/Client/GrpcServiceElement.cs:
--------------------------------------------------------------------------------
1 | #if !ASP_NET_CORE
2 | using System.Configuration;
3 | #endif
4 |
5 | namespace Overt.Core.Grpc.Client
6 | {
7 | public class GrpcServiceElement
8 | #if !ASP_NET_CORE
9 | : ConfigurationElement
10 | #endif
11 | {
12 | ///
13 | /// 服务名称
14 | ///
15 | #if !ASP_NET_CORE
16 | [ConfigurationProperty("name", IsRequired = true)]
17 | #endif
18 | public string Name
19 | {
20 | #if !ASP_NET_CORE
21 | get { return (string)this["name"]; }
22 | #else
23 | get; set;
24 | #endif
25 | }
26 |
27 | ///
28 | /// 服务名称
29 | ///
30 | #if !ASP_NET_CORE
31 | [ConfigurationProperty("maxRetry", IsRequired = false)]
32 | #endif
33 | public int MaxRetry
34 | {
35 | #if !ASP_NET_CORE
36 | get { return (int)this["maxRetry"]; }
37 | #else
38 | get; set;
39 | #endif
40 | }
41 |
42 | ///
43 | /// 服务发现
44 | ///
45 | #if !ASP_NET_CORE
46 | [ConfigurationProperty("discovery", IsRequired = true)]
47 | #endif
48 | public GrpcDiscoveryElement Discovery
49 | {
50 | #if !ASP_NET_CORE
51 | get { return this["discovery"] as GrpcDiscoveryElement; }
52 | #else
53 | get; set;
54 | #endif
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Grpc/Common/ConsulElement.cs:
--------------------------------------------------------------------------------
1 | #if !ASP_NET_CORE
2 | using System.Configuration;
3 | #endif
4 |
5 | namespace Overt.Core.Grpc
6 | {
7 | ///
8 | /// Consul
9 | ///
10 | public class ConsulElement
11 | #if !ASP_NET_CORE
12 | : ConfigurationElement
13 | #endif
14 | {
15 | ///
16 | /// 服务地址
17 | ///
18 | #if !ASP_NET_CORE
19 | [ConfigurationProperty("path", IsRequired = false)]
20 | #endif
21 | public string Path
22 | {
23 | #if !ASP_NET_CORE
24 | get { return (string)this["path"]; }
25 | #else
26 | get; set;
27 | #endif
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Grpc/Service/GrpcRegistryElement.cs:
--------------------------------------------------------------------------------
1 | #if !ASP_NET_CORE
2 | using System.Configuration;
3 |
4 | namespace Overt.Core.Grpc.Service
5 | {
6 | ///
7 | /// 服务注册
8 | ///
9 | public class GrpcRegistryElement : ConfigurationElement
10 | {
11 | ///
12 | /// 注册配置
13 | ///
14 | [ConfigurationProperty("consul", IsRequired = false)]
15 | public ConsulElement Consul { get { return this["consul"] as ConsulElement; } }
16 | }
17 | }
18 | #endif
19 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Grpc/Service/GrpcServerSection.cs:
--------------------------------------------------------------------------------
1 | using Overt.Core.Grpc.Service;
2 | #if !ASP_NET_CORE
3 | using System.Configuration;
4 | #endif
5 |
6 | namespace Overt.Core.Grpc
7 | {
8 | ///
9 | /// Grpc配置
10 | ///
11 | ///
12 | ///
13 | ///
14 | ///
15 | ///
16 | ///
17 | ///
18 | public class GrpcServerSection
19 | #if !ASP_NET_CORE
20 | : ConfigurationSection
21 | #endif
22 | {
23 | #if !ASP_NET_CORE
24 | ///
25 | /// grpc配置
26 | ///
27 | [ConfigurationProperty("service", IsRequired = true)]
28 | #endif
29 | public ServiceElement Service
30 | {
31 | #if !ASP_NET_CORE
32 | get { return this["service"] as ServiceElement; }
33 | #else
34 | get; set;
35 | #endif
36 |
37 | }
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Grpc/Service/ServiceElement.cs:
--------------------------------------------------------------------------------
1 | #if !ASP_NET_CORE
2 | using System.Configuration;
3 | #endif
4 |
5 | namespace Overt.Core.Grpc.Service
6 | {
7 | public class ServiceElement
8 | #if !ASP_NET_CORE
9 | : ConfigurationElement
10 | #endif
11 | {
12 | ///
13 | /// 服务名称
14 | ///
15 | #if !ASP_NET_CORE
16 | [ConfigurationProperty("name", IsRequired = true)]
17 | #endif
18 | public string Name
19 | {
20 | #if !ASP_NET_CORE
21 | get { return (string)this["name"]; }
22 | #else
23 | get; set;
24 | #endif
25 |
26 | }
27 | ///
28 | /// Host 默认 0.0.0.0
29 | /// 优先级1
30 | ///
31 |
32 | #if !ASP_NET_CORE
33 | [ConfigurationProperty("host", IsRequired = false, DefaultValue = "")]
34 | #else
35 | public string _Host;
36 | #endif
37 | public string Host
38 | {
39 | #if !ASP_NET_CORE
40 | get { return (string)this["host"]; }
41 | #else
42 | get { return _Host; }
43 | set { _Host = value; }
44 | #endif
45 | }
46 |
47 | ///
48 | /// 端口号
49 | ///
50 | #if !ASP_NET_CORE
51 | [ConfigurationProperty("port", IsRequired = true)]
52 | #endif
53 | public int Port
54 | {
55 | #if !ASP_NET_CORE
56 | get { return (int)this["port"]; }
57 | #else
58 | get; set;
59 | #endif
60 | }
61 |
62 | ///
63 | /// host环境变量名称
64 | /// 优先级2
65 | ///
66 | #if !ASP_NET_CORE
67 | [ConfigurationProperty("hostEnv", IsRequired = false, DefaultValue = "")]
68 | #else
69 | public string _HostEnv;
70 | #endif
71 | public string HostEnv
72 | {
73 | #if !ASP_NET_CORE
74 | get { return (string)this["hostEnv"]; }
75 | #else
76 | get { return _HostEnv; }
77 | set { _HostEnv = value; }
78 | #endif
79 | }
80 |
81 | ///
82 | /// 注册配置
83 | ///
84 | #if !ASP_NET_CORE
85 | [ConfigurationProperty("registry", IsRequired = false)]
86 | public GrpcRegistryElement Registry { get { return this["registry"] as GrpcRegistryElement; } }
87 | #else
88 | public ConsulElement Consul { get; set; }
89 | #endif
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Util/ConfigBuilder.cs:
--------------------------------------------------------------------------------
1 | #if !ASP_NET_CORE
2 | using System.Configuration;
3 | #else
4 | using Microsoft.Extensions.Configuration;
5 | #endif
6 | using System;
7 | using System.IO;
8 |
9 | namespace Overt.Core.Grpc
10 | {
11 | ///
12 | /// 配置文件读取
13 | ///
14 | internal class ConfigBuilder
15 | {
16 | #if ASP_NET_CORE
17 | public static Action ConfigureDelegate;
18 | #endif
19 |
20 | ///
21 | /// 获取Server配置对象
22 | ///
23 | /// 节点名称
24 | ///
25 | ///
26 | public static T Build(string sectionName, string configPath = "") where T :
27 | #if !ASP_NET_CORE
28 | ConfigurationSection
29 | #else
30 | class, new()
31 | #endif
32 | {
33 | T section = null;
34 | #if !ASP_NET_CORE
35 | if (string.IsNullOrEmpty(configPath))
36 | section = ConfigurationManager.GetSection(sectionName) as T;
37 |
38 | else
39 | {
40 | configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configPath);
41 | if (!File.Exists(configPath))
42 | throw new ConfigurationErrorsException($"overt: when resolve configpath, configpath file is not exist...[{configPath}]");
43 |
44 | section = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap
45 | {
46 | ExeConfigFilename = configPath
47 | }, ConfigurationUserLevel.None).GetSection(sectionName) as T;
48 | }
49 | #else
50 | if (string.IsNullOrEmpty(configPath) || !configPath.EndsWith(".json"))
51 | configPath = "appsettings.json";
52 |
53 | configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configPath);
54 | if (!File.Exists(configPath))
55 | throw new Exception($"overt: when resolve configpath, configpath file is not exist... [{configPath}]");
56 |
57 | section = new T();
58 | var builder = new ConfigurationBuilder()
59 | .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
60 | .AddJsonFile(configPath)
61 | .AddEnvironmentVariables();
62 | ConfigureDelegate?.Invoke(builder);
63 | var configuration = builder.Build();
64 | configuration.GetSection(sectionName).Bind(section);
65 | #endif
66 | return section;
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Config/Util/GrpcConstants.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using System.Collections.Generic;
3 |
4 | namespace Overt.Core.Grpc
5 | {
6 | public class GrpcConstants
7 | {
8 | #if !ASP_NET_CORE
9 | ///
10 | /// Grpc Server 节点名称
11 | ///
12 | internal const string GrpcServerSectionName = "grpcServer";
13 | ///
14 | /// Grpc Consul 节点名称
15 | ///
16 | internal const string ConsulServerSectionName = "consulServer";
17 | ///
18 | /// Grpc Client 节点名称
19 | ///
20 | internal const string GrpcClientSectionName = "grpcClient";
21 | #else
22 | ///
23 | /// Grpc Server 节点名称
24 | ///
25 | internal const string GrpcServerSectionName = "GrpcServer";
26 | ///
27 | /// Grpc Consul 节点名称
28 | ///
29 | internal const string ConsulServerSectionName = "ConsulServer";
30 | ///
31 | /// Grpc Client 节点名称
32 | ///
33 | internal const string GrpcClientSectionName = "GrpcClient";
34 | #endif
35 |
36 | ///
37 | ///
38 | ///
39 | //public const string MetadataKey_ChannelTarget = "channel_target";
40 |
41 | ///
42 | /// 默认的通道配置
43 | ///
44 | public static List DefaultChannelOptions = new List()
45 | {
46 | new ChannelOption(ChannelOptions.MaxReceiveMessageLength, int.MaxValue),
47 | new ChannelOption(ChannelOptions.MaxSendMessageLength, int.MaxValue),
48 | };
49 |
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/GrpcServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | #if ASP_NET_CORE
2 | using Microsoft.Extensions.Configuration;
3 | using Microsoft.Extensions.DependencyInjection;
4 | using Microsoft.Extensions.DependencyInjection.Extensions;
5 | using Overt.Core.Grpc.Intercept;
6 | using System;
7 | #endif
8 |
9 | namespace Overt.Core.Grpc
10 | {
11 | #if ASP_NET_CORE
12 | ///
13 | /// Grpc服务注入
14 | ///
15 | public static class GrpcServiceCollectionExtensions
16 | {
17 | ///
18 | ///
19 | ///
20 | ///
21 | ///
22 | public static IServiceCollection AddGrpcClient(this IServiceCollection services)
23 | {
24 | if (services == null)
25 | {
26 | throw new ArgumentNullException(nameof(services));
27 | }
28 |
29 | services.TryAdd(ServiceDescriptor.Singleton(typeof(IGrpcClient<>), typeof(GrpcClient<>)));
30 | services.TryAdd(ServiceDescriptor.Singleton(typeof(IGrpcClientFactory<>), typeof(GrpcClientFactory<>)));
31 | return services;
32 | }
33 |
34 | ///
35 | ///
36 | ///
37 | ///
38 | ///
39 | public static IServiceCollection AddGrpcTracer(this IServiceCollection services) where T : IServerTracer
40 | {
41 | if (services == null)
42 | {
43 | throw new ArgumentNullException(nameof(services));
44 | }
45 |
46 | services.TryAddTransient(typeof(IServerTracer), typeof(T));
47 | return services;
48 | }
49 |
50 | ///
51 | /// 配置 可用于第三方配置
52 | ///
53 | ///
54 | ///
55 | public static void AddGrpcConfig(this IServiceCollection services, Action configureDelegate)
56 | {
57 | ConfigBuilder.ConfigureDelegate = configureDelegate;
58 | }
59 | }
60 | #endif
61 | }
--------------------------------------------------------------------------------
/src/Overt.Core.Grpc/Intercept/Handler/InterceptedServerHandler.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using System;
3 | using System.Threading.Tasks;
4 |
5 | namespace Overt.Core.Grpc.Intercept
6 | {
7 | internal class InterceptedServerHandler
8 | where TRequest : class
9 | where TResponse : class
10 | {
11 | readonly IServerTracer _tracer;
12 | readonly ServerCallContext _context;
13 | public InterceptedServerHandler(IServerTracer tracer, ServerCallContext context)
14 | {
15 | _tracer = tracer;
16 | _context = context;
17 | }
18 |
19 | public async Task UnaryServerHandler(TRequest request, UnaryServerMethod continuation)
20 | {
21 | try
22 | {
23 | _tracer.Request(request, _context);
24 | var response = await continuation(request, _context).ConfigureAwait(false);
25 | _tracer.Response(response, _context);
26 | _tracer.Finish(_context);
27 | return response;
28 | }
29 | catch (Exception ex)
30 | {
31 | _tracer.Exception(_context, ex, request);
32 | throw;
33 | }
34 | }
35 |
36 | public async Task ClientStreamingServerHandler(IAsyncStreamReader requestStream, ClientStreamingServerMethod continuation)
37 | {
38 | try
39 | {
40 | var tracingRequestStream = new TracingAsyncServerStreamReader(requestStream, _context, _tracer.Request);
41 | var response = await continuation(tracingRequestStream, _context).ConfigureAwait(false);
42 | _tracer.Response(response, _context);
43 | _tracer.Finish(_context);
44 | return response;
45 | }
46 | catch (Exception ex)
47 | {
48 | _tracer.Exception