├── .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(_context, ex); 49 | throw; 50 | } 51 | } 52 | 53 | public async Task ServerStreamingServerHandler(TRequest request, IServerStreamWriter responseStream, ServerStreamingServerMethod continuation) 54 | { 55 | try 56 | { 57 | var tracingResponseStream = new TracingServerStreamWriter(responseStream, _context, _tracer.Response); 58 | _tracer.Request(request, _context); 59 | await continuation(request, tracingResponseStream, _context).ConfigureAwait(false); 60 | _tracer.Finish(_context); 61 | } 62 | catch (Exception ex) 63 | { 64 | _tracer.Exception(_context, ex, request); 65 | throw; 66 | } 67 | } 68 | 69 | public async Task DuplexStreamingServerHandler(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, DuplexStreamingServerMethod continuation) 70 | { 71 | try 72 | { 73 | var tracingRequestStream = new TracingAsyncServerStreamReader(requestStream, _context, _tracer.Request); 74 | var tracingResponseStream = new TracingServerStreamWriter(responseStream, _context, _tracer.Response); 75 | await continuation(tracingRequestStream, tracingResponseStream, _context).ConfigureAwait(false); 76 | _tracer.Finish(_context); 77 | } 78 | catch (Exception ex) 79 | { 80 | _tracer.Exception(_context, ex); 81 | throw; 82 | } 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Intercept/InterceptExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Overt.Core.Grpc.Intercept 2 | { 3 | public static class InterceptExtensions 4 | { 5 | /// 6 | /// ClientIntercept注入 7 | /// 8 | /// 9 | /// 10 | /// 11 | public static ServerCallInvoker ClientIntercept(this ServerCallInvoker callInvoker, IClientTracer tracer) 12 | { 13 | if (callInvoker == null) 14 | return callInvoker; 15 | 16 | return new InterceptedServerCallInvoker(callInvoker.Channel, tracer); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Intercept/Interceptor/ClientTracerInterceptor.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using Grpc.Core.Interceptors; 3 | 4 | namespace Overt.Core.Grpc.Intercept 5 | { 6 | /// 7 | /// 客户端拦截器 8 | /// 9 | internal class ClientTracerInterceptor : Interceptor 10 | { 11 | readonly IClientTracer _tracer; 12 | public ClientTracerInterceptor(IClientTracer tracer) 13 | { 14 | _tracer = tracer; 15 | } 16 | 17 | public override TResponse BlockingUnaryCall(TRequest request, ClientInterceptorContext context, BlockingUnaryCallContinuation continuation) 18 | { 19 | return new InterceptedClientHandler(_tracer, context) 20 | .BlockingUnaryCall(request, continuation); 21 | } 22 | 23 | public override AsyncUnaryCall AsyncUnaryCall(TRequest request, ClientInterceptorContext context, AsyncUnaryCallContinuation continuation) 24 | { 25 | return new InterceptedClientHandler(_tracer, context) 26 | .AsyncUnaryCall(request, continuation); 27 | } 28 | 29 | public override AsyncServerStreamingCall AsyncServerStreamingCall(TRequest request, ClientInterceptorContext context, 30 | AsyncServerStreamingCallContinuation continuation) 31 | { 32 | return new InterceptedClientHandler(_tracer, context) 33 | .AsyncServerStreamingCall(request, continuation); 34 | } 35 | 36 | public override AsyncClientStreamingCall AsyncClientStreamingCall(ClientInterceptorContext context, AsyncClientStreamingCallContinuation continuation) 37 | { 38 | return new InterceptedClientHandler(_tracer, context) 39 | .AsyncClientStreamingCall(continuation); 40 | } 41 | 42 | public override AsyncDuplexStreamingCall AsyncDuplexStreamingCall(ClientInterceptorContext context, AsyncDuplexStreamingCallContinuation continuation) 43 | { 44 | return new InterceptedClientHandler(_tracer, context) 45 | .AsyncDuplexStreamingCall(continuation); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Intercept/Interceptor/ServerTracerInterceptor.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using Grpc.Core.Interceptors; 3 | using System.Threading.Tasks; 4 | 5 | namespace Overt.Core.Grpc.Intercept 6 | { 7 | /// 8 | /// 服务端拦截器 9 | /// 10 | internal class ServerTracerInterceptor : Interceptor 11 | { 12 | readonly IServerTracer _tracer; 13 | public ServerTracerInterceptor(IServerTracer tracer) 14 | { 15 | _tracer = tracer; 16 | } 17 | 18 | public override Task ClientStreamingServerHandler(IAsyncStreamReader requestStream, ServerCallContext context, ClientStreamingServerMethod continuation) 19 | { 20 | return new InterceptedServerHandler(_tracer, context) 21 | .ClientStreamingServerHandler(requestStream, continuation); 22 | } 23 | 24 | public override Task DuplexStreamingServerHandler(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context, DuplexStreamingServerMethod continuation) 25 | { 26 | return new InterceptedServerHandler(_tracer, context) 27 | .DuplexStreamingServerHandler(requestStream, responseStream, continuation); 28 | } 29 | 30 | public override Task ServerStreamingServerHandler(TRequest request, IServerStreamWriter responseStream, ServerCallContext context, ServerStreamingServerMethod continuation) 31 | { 32 | return new InterceptedServerHandler(_tracer, context) 33 | .ServerStreamingServerHandler(request, responseStream, continuation); 34 | } 35 | 36 | public override Task UnaryServerHandler(TRequest request, ServerCallContext context, UnaryServerMethod continuation) 37 | { 38 | return new InterceptedServerHandler(_tracer, context) 39 | .UnaryServerHandler(request, continuation); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Intercept/Streaming/TracingAsyncClientStreamReader.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using Grpc.Core.Interceptors; 3 | using System; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace Overt.Core.Grpc.Intercept 8 | { 9 | internal class TracingAsyncClientStreamReader : IAsyncStreamReader 10 | where TRequest : class 11 | where T : class 12 | { 13 | private readonly IAsyncStreamReader _reader; 14 | private readonly ClientInterceptorContext _context; 15 | private readonly Action> _onMessage; 16 | private readonly Action> _onStreamEnd; 17 | private readonly Action, Exception, TRequest> _onException; 18 | 19 | public TracingAsyncClientStreamReader(IAsyncStreamReader reader, 20 | ClientInterceptorContext context, 21 | Action> onMessage, 22 | Action> onStreamEnd = null, 23 | Action, Exception, TRequest> onException = null) 24 | { 25 | _reader = reader; 26 | _context = context; 27 | _onMessage = onMessage; 28 | _onStreamEnd = onStreamEnd; 29 | _onException = onException; 30 | } 31 | 32 | public T Current => _reader.Current; 33 | 34 | public async Task MoveNext(CancellationToken cancellationToken) 35 | { 36 | try 37 | { 38 | var hasNext = await _reader.MoveNext(cancellationToken).ConfigureAwait(false); 39 | if (hasNext) 40 | { 41 | _onMessage?.Invoke(Current, _context); 42 | } 43 | else 44 | { 45 | _onStreamEnd?.Invoke(_context); 46 | } 47 | 48 | return hasNext; 49 | } 50 | catch (Exception ex) 51 | { 52 | _onException?.Invoke(_context, ex, default(TRequest)); 53 | throw; 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Intercept/Streaming/TracingAsyncServerStreamReader.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using System; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace Overt.Core.Grpc.Intercept 7 | { 8 | internal class TracingAsyncServerStreamReader : IAsyncStreamReader 9 | { 10 | private readonly IAsyncStreamReader _reader; 11 | private readonly ServerCallContext _context; 12 | private readonly Action _onMessage; 13 | private readonly Action _onStreamEnd; 14 | private readonly Action _onException; 15 | 16 | public TracingAsyncServerStreamReader(IAsyncStreamReader reader, ServerCallContext context, Action onMessage, Action onStreamEnd = null, Action onException = null) 17 | { 18 | _reader = reader; 19 | _context = context; 20 | _onMessage = onMessage; 21 | _onStreamEnd = onStreamEnd; 22 | _onException = onException; 23 | } 24 | 25 | public T Current => _reader.Current; 26 | 27 | public async Task MoveNext(CancellationToken cancellationToken) 28 | { 29 | try 30 | { 31 | var hasNext = await _reader.MoveNext(cancellationToken).ConfigureAwait(false); 32 | if (hasNext) 33 | { 34 | _onMessage?.Invoke(Current, _context); 35 | } 36 | else 37 | { 38 | _onStreamEnd?.Invoke(); 39 | } 40 | 41 | return hasNext; 42 | } 43 | catch (Exception ex) 44 | { 45 | _onException?.Invoke(ex); 46 | throw; 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Intercept/Streaming/TracingClientStreamWriter.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using Grpc.Core.Interceptors; 3 | using System; 4 | using System.Threading.Tasks; 5 | 6 | namespace Overt.Core.Grpc.Intercept 7 | { 8 | internal class TracingClientStreamWriter : IClientStreamWriter 9 | where T : class 10 | where TResponse : class 11 | { 12 | private readonly IClientStreamWriter _writer; 13 | private readonly ClientInterceptorContext _context; 14 | private readonly Action> _onWrite; 15 | private readonly Action _onComplete; 16 | 17 | public TracingClientStreamWriter(IClientStreamWriter writer, ClientInterceptorContext context, Action> onWrite, Action onComplete = null) 18 | { 19 | _writer = writer; 20 | _context = context; 21 | _onWrite = onWrite; 22 | _onComplete = onComplete; 23 | } 24 | 25 | public WriteOptions WriteOptions 26 | { 27 | get => _writer.WriteOptions; 28 | set => _writer.WriteOptions = value; 29 | } 30 | 31 | public Task WriteAsync(T message) 32 | { 33 | _onWrite(message, _context); 34 | return _writer.WriteAsync(message); 35 | } 36 | 37 | public Task CompleteAsync() 38 | { 39 | _onComplete?.Invoke(); 40 | return _writer.CompleteAsync(); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Intercept/Streaming/TracingServerStreamWriter.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using System; 3 | using System.Threading.Tasks; 4 | 5 | namespace Overt.Core.Grpc.Intercept 6 | { 7 | internal class TracingServerStreamWriter : IServerStreamWriter 8 | { 9 | private readonly IServerStreamWriter _writer; 10 | private readonly ServerCallContext _context; 11 | private readonly Action _onWrite; 12 | 13 | public TracingServerStreamWriter(IServerStreamWriter writer, ServerCallContext context, Action onWrite) 14 | { 15 | _writer = writer; 16 | _context = context; 17 | _onWrite = onWrite; 18 | } 19 | 20 | public WriteOptions WriteOptions 21 | { 22 | get => _writer.WriteOptions; 23 | set => _writer.WriteOptions = value; 24 | } 25 | 26 | public Task WriteAsync(T message) 27 | { 28 | _onWrite(message, _context); 29 | return _writer.WriteAsync(message); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Intercept/Tracer/ClientMockTracer.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using Grpc.Core.Interceptors; 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace Overt.Core.Grpc.Intercept 7 | { 8 | public class ClientMockTracer : IClientTracer 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 | Console.WriteLine("start request"); 29 | } 30 | 31 | public void Response(TResponse response, ClientInterceptorContext context) 32 | where TRequest : class 33 | where TResponse : class 34 | { 35 | Console.WriteLine("end response"); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Intercept/Tracer/IClientTracer.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core.Interceptors; 2 | using System; 3 | 4 | namespace Overt.Core.Grpc.Intercept 5 | { 6 | public interface IClientTracer 7 | { 8 | void Request(TRequest request, ClientInterceptorContext context) 9 | where TRequest : class 10 | where TResponse : class; 11 | 12 | void Response(TResponse response, ClientInterceptorContext context) 13 | where TRequest : class 14 | where TResponse : class; 15 | 16 | void Finish(ClientInterceptorContext context) 17 | where TRequest : class 18 | where TResponse : class; 19 | 20 | void Exception(ClientInterceptorContext context, Exception exception, TRequest request = null) 21 | where TRequest : class 22 | where TResponse : class; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Intercept/Tracer/IServerTracer.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using System; 3 | 4 | namespace Overt.Core.Grpc.Intercept 5 | { 6 | public interface IServerTracer 7 | { 8 | string ServiceName { get; set; } 9 | 10 | void Request(TRequest request, ServerCallContext context); 11 | 12 | void Response(TResponse response, ServerCallContext context); 13 | 14 | void Finish(ServerCallContext context); 15 | 16 | void Exception(ServerCallContext context, Exception exception, TRequest request = default(TRequest)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Intercept/Tracer/ServerMockTracer.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using System; 3 | 4 | namespace Overt.Core.Grpc.Intercept 5 | { 6 | public class ServerMockTracer : IServerTracer 7 | { 8 | public string ServiceName { get; set; } 9 | 10 | public void Exception(ServerCallContext context, Exception exception, TRequest request = default(TRequest)) 11 | { 12 | Console.WriteLine("some exception"); 13 | } 14 | 15 | public void Finish(ServerCallContext context) 16 | { 17 | Console.WriteLine("finished request"); 18 | } 19 | 20 | public void Request(TRequest request, ServerCallContext context) 21 | { 22 | Console.WriteLine("start request"); 23 | } 24 | 25 | public void Response(TResponse response, ServerCallContext context) 26 | { 27 | Console.WriteLine("end response"); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Manager/GrpcClientManager.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using Grpc.Core.Interceptors; 3 | using Overt.Core.Grpc.Intercept; 4 | using System; 5 | using System.Collections.Concurrent; 6 | using System.Collections.Generic; 7 | 8 | namespace Overt.Core.Grpc 9 | { 10 | #if !ASP_NET_CORE 11 | /// 12 | /// Grpc客户端管理类 13 | /// 14 | public class GrpcClientManager where T : ClientBase 15 | { 16 | static readonly ConcurrentDictionary> _clientFactoryCache = new ConcurrentDictionary>(); 17 | static readonly ConcurrentDictionary _clientCache = new ConcurrentDictionary(); 18 | /// 19 | /// 获取客户端 20 | /// 21 | /// 配置文件路径 22 | /// 配置信息 23 | /// 自定义invoker获取策略 24 | /// 25 | public static T Get(string configPath = "", GrpcClientOptions options = default, Func, ServerCallInvoker> callInvokers = null) 26 | { 27 | options = options ?? new GrpcClientOptions(); 28 | if (!string.IsNullOrWhiteSpace(configPath)) 29 | options.ConfigPath = configPath; 30 | 31 | return Get(options, callInvokers); 32 | } 33 | 34 | /// 35 | /// 获取客户端 36 | /// 37 | /// 配置文件路径 38 | /// tracer拦截器 39 | /// 自定义拦截器 40 | /// 自定义invoker获取策略 41 | /// 42 | public static T Get(string configPath = "", IClientTracer tracer = null, List interceptors = null, Func, ServerCallInvoker> callInvokers = null) 43 | { 44 | var options = new GrpcClientOptions() 45 | { 46 | Tracer = tracer, 47 | ConfigPath = configPath, 48 | }; 49 | if (interceptors?.Count > 0) 50 | options.Interceptors.AddRange(interceptors); 51 | return Get(options, callInvokers); 52 | } 53 | 54 | /// 55 | /// 获取客户端 56 | /// 57 | /// 配置文件路径 58 | /// tracer拦截器 59 | /// 自定义拦截器 60 | /// 自定义invoker获取策略 61 | /// 62 | public static T Get(GrpcClientOptions options, Func, ServerCallInvoker> callInvokers = null) 63 | { 64 | var factory = _clientFactoryCache.GetOrAdd(typeof(T), key => new GrpcClientFactory(options)); 65 | return _clientCache.GetOrAdd(typeof(T), key => factory.Get(callInvokers)); 66 | } 67 | } 68 | #endif 69 | } 70 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Overt.Core.Grpc.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net45;net46;netstandard2.0 4 | Overt.Core.Grpc 5 | 6 | yaofeng 7 | 基于Grpc Consul结合实现的微服务框架 8 | false 9 | 1. Consul支持ACL Token 10 | yaofeng 11 | 12 | true 13 | 1.0.0.0 14 | 1.0.0.0 15 | 1.0.9.1 16 | https://github.com/overtly/core-grpc.git 17 | https://github.com/overtly/core-grpc.git 18 | 19 | 7.1 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | ASP.NET Core 2 integration for Overt.Core.Grpc - .NET Standard 2 34 | $(DefineConstants);ASP_NET_CORE;ASP_NET_CORE2 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 2.0.0 44 | 45 | 46 | 2.0.0 47 | 48 | 49 | 2.0.0 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/Service/ConsulTimespan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Overt.Core.Grpc 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/Service/Entity/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Overt.Core.Grpc 4 | { 5 | /// 6 | /// 注册成功后对象 7 | /// 8 | public sealed class Entry : IDisposable 9 | { 10 | private readonly ServerRegister _serverRegister; 11 | 12 | public Entry(ServerRegister 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/Service/Entity/Exitus.cs: -------------------------------------------------------------------------------- 1 | namespace Overt.Core.Grpc 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/Service/Entity/GrpcOptions.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.Net; 7 | 8 | namespace Overt.Core.Grpc 9 | { 10 | /// 11 | /// Grpc配置信息 12 | /// 13 | public class GrpcOptions 14 | { 15 | /// 16 | /// 配置文件地址 17 | /// default: appsettings.json 18 | /// 19 | public string ConfigPath { get; set; } 20 | 21 | /// 22 | /// 自定义拦截器 23 | /// default: null 24 | /// 25 | public List Interceptors { get; } = new List(); 26 | 27 | /// 28 | /// tracer拦截器 29 | /// default: null 30 | /// 31 | public IServerTracer Tracer { get; set; } 32 | 33 | /// 34 | /// Channel配置 35 | /// 36 | public List ChannelOptions { get; set; } 37 | 38 | /// 39 | /// ServiceId生成 40 | /// 41 | public Func GenServiceId { get; set; } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/dllconfigs/framework/Client.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/dllconfigs/framework/Consul.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/dllconfigs/framework/Server.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/dllconfigs/netstandard20/clientsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "GrpcClient": { 3 | "Service": { 4 | "Name": "grpcservice", 5 | "MaxRetry": 0, 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/dllconfigs/netstandard20/consulsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConsulServer": { 3 | "Service": { 4 | "Address": "http://consul.g.lan", 5 | "Token": "" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Overt.Core.Grpc/dllconfigs/netstandard20/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 | --------------------------------------------------------------------------------