diff --git a/pom.xml b/pom.xml index 532d379df..04b15d7b2 100644 --- a/pom.xml +++ b/pom.xml @@ -69,6 +69,7 @@ spring-boot-demo-elasticsearch-rest-high-level-client spring-boot-demo-https spring-boot-demo-flyway + spring-boot-demo-grpc pom diff --git a/spring-boot-demo-grpc/.gitignore b/spring-boot-demo-grpc/.gitignore new file mode 100644 index 000000000..82eca336e --- /dev/null +++ b/spring-boot-demo-grpc/.gitignore @@ -0,0 +1,25 @@ +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ \ No newline at end of file diff --git a/spring-boot-demo-grpc/README.md b/spring-boot-demo-grpc/README.md new file mode 100644 index 000000000..47b2fa46d --- /dev/null +++ b/spring-boot-demo-grpc/README.md @@ -0,0 +1,87 @@ +# spring-boot-demo-grpc + +> 此 demo 主要演示了如何使用 Spring Boot 集成 RPC并配置开启tls/ssl + +## 项目结构 +根项目(spring-boot-demo-grpc)下有3个子模块: + +- spring-boot-demo-grpc-server:GRPC服务端 +- spring-boot-demo-grpc-protocol:包含原始proto文件,以及其转换的java代码 +- spring-boot-demo-grpc-client : GRPC客户端 + +## 配置指南 +### .proto生成java文件 +1、定义好proto文件放在项目"src\main\proto"目录下 如:spring-boot-demo-grpc-protocol\src\main\proto + +2、生成java代码 +1. 直接在IDE里用proto插件运行compile生成 +2. 直接下载[protobuf-window版](https://github.com/protocolbuffers/protobuf/releases/download/v3.11.4/protoc-3.11.4-win64.zip) 然后执行```./protoc.exe --java_out=./ demo.proto``` + +### 证书生成: +如果没有证书(例如内部测试服务器),可以使用openssl生成证书: + +[openssl下载](http://slproweb.com/download/Win64OpenSSL-1_1_1e.msi) 可以参考这里[配置](https://github.com/kiinlam/kiinlam.github.io/issues/11) + +服务端: +```openssl req -x509 -nodes -subj "/CN=localhost/C=CN" -newkey rsa:4096 -sha256 -keyout server.key -out server.crt -days 3650``` + +客户端: +```openssl req -x509 -nodes -subj "/CN=localhost/C=CN" -newkey rsa:4096 -sha256 -keyout server.key -out server.crt -days 3650``` + +**请注意** 如果没有额外配置,这些证书不受任何应用程序的信任。 我们建议您使用受全球CA或您公司CA信任的证书。 + +最后分别放入server、client的resources/certificates/下 + +### spring-boot-demo-grpc-client: GRPC客户端 +```yaml +server: + port: 8090 +spring: + application: + name: demo-grpc-client +grpc: + client: + demo-grpc-server: + address: 'static://localhost:9090' + # 禁用传输图层安全 请勿在生产环境中这样做 + #negotiationType: plaintext + # gRPC 默认使用 TLS 连接服务端 该配置启用传输图层安全 + negotiationType: TLS + security: + #如果您信任的证书不在常规信任存储区, 或者您想要限制您信任的 证书。您可以使用以下属性 + trustCertCollection: classpath:certificates/trusted-server.crt.list + #要指定证书对哪个名字有效: + authorityOverride: localhost + #如果需要双向证书认证配置如下属性 + clientAuthEnabled: true + certificateChain: classpath:certificates/client.crt + privateKey: classpath:certificates/client.key +``` + +### spring-boot-demo-grpc-server: GRPC服务端 +```yaml +spring: + application: + name: demo-grpc-server +grpc: + server: + port: 9090 + # 开启TLS相关配置 + security: + enabled: true + certificateChain: classpath:certificates/server.crt + privateKey: classpath:certificates/server.key + #指定受信任客户端证书 直接把client.crt复制到该文件即可 + trustCertCollection: classpath:certificates/trusted-clients.crt.list + #REQUIRE:客户端证书必须通过认证 OPTIONAL:对客户端的证书进行身份验证,但不会强制这么做。 + clientAuth: REQUIRE +``` + +### 运行 +client、server直接运行起来之后访问http://localhost:8090/hello 出现Hi~说明你成功了 + +## 详细配置说明 +请参考[文档](https://yidongnan.github.io/grpc-spring-boot-starter/zh-CN/index) + +## 常见问题 +请参考[文档](https://yidongnan.github.io/grpc-spring-boot-starter/en/trouble-shooting.html) diff --git a/spring-boot-demo-grpc/pom.xml b/spring-boot-demo-grpc/pom.xml new file mode 100644 index 000000000..8252950d6 --- /dev/null +++ b/spring-boot-demo-grpc/pom.xml @@ -0,0 +1,48 @@ + + + + com.xkcoding + spring-boot-demo + 1.0.0-SNAPSHOT + + + 4.0.0 + spring-boot-demo-grpc + pom + + + spring-boot-demo-grpc-server + spring-boot-demo-grpc-client + spring-boot-demo-grpc-protocol + + + + UTF-8 + UTF-8 + 1.8 + 1.27.1 + 1.6.2 + 0.6.1 + 3.11.0 + 1.27.1 + 2.7.0.RELEASE + 2.0.25.Final + + + + + + net.devh + grpc-client-spring-boot-starter + ${net-devh-grpc.version} + + + net.devh + grpc-server-spring-boot-starter + ${net-devh-grpc.version} + + + + + diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-client/pom.xml b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/pom.xml new file mode 100644 index 000000000..e726794eb --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/pom.xml @@ -0,0 +1,33 @@ + + + + spring-boot-demo-grpc + com.xkcoding + 1.0.0-SNAPSHOT + + 4.0.0 + + spring-boot-demo-grpc-client + jar + + + + com.xkcoding + spring-boot-demo-grpc-protocol + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + + net.devh + grpc-client-spring-boot-starter + + + + diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/java/com/xkcoding/grpc/client/SpringBootDemoGrpcClientApplication.java b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/java/com/xkcoding/grpc/client/SpringBootDemoGrpcClientApplication.java new file mode 100644 index 000000000..1d34f82c8 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/java/com/xkcoding/grpc/client/SpringBootDemoGrpcClientApplication.java @@ -0,0 +1,17 @@ +package com.xkcoding.grpc.client; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author dengliming + * @date 2020/3/29 + */ +@SpringBootApplication +public class SpringBootDemoGrpcClientApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootDemoGrpcClientApplication.class, args); + } + +} diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/java/com/xkcoding/grpc/client/controller/GrpcClientController.java b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/java/com/xkcoding/grpc/client/controller/GrpcClientController.java new file mode 100644 index 000000000..e6c2165c2 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/java/com/xkcoding/grpc/client/controller/GrpcClientController.java @@ -0,0 +1,26 @@ +package com.xkcoding.grpc.client.controller; + +import com.xkcoding.grpc.client.service.GrpcClientService; +import com.xkcoding.grpc.protocol.DemoResponse; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author dengliming + * @date 2020/3/29 + */ +@RestController +public class GrpcClientController { + + private final GrpcClientService grpcClientService; + + public GrpcClientController(GrpcClientService grpcClientService) { + this.grpcClientService = grpcClientService; + } + + @RequestMapping("/hello") + public String hello() { + DemoResponse rpcResponse = grpcClientService.hello(); + return rpcResponse.getMsg(); + } +} diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/java/com/xkcoding/grpc/client/service/GrpcClientService.java b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/java/com/xkcoding/grpc/client/service/GrpcClientService.java new file mode 100644 index 000000000..a09a4857d --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/java/com/xkcoding/grpc/client/service/GrpcClientService.java @@ -0,0 +1,22 @@ +package com.xkcoding.grpc.client.service; + +import com.xkcoding.grpc.protocol.DemoRequest; +import com.xkcoding.grpc.protocol.DemoResponse; +import com.xkcoding.grpc.protocol.DemoServiceGrpc; +import net.devh.boot.grpc.client.inject.GrpcClient; +import org.springframework.stereotype.Service; + +/** + * @author dengliming + * @date 2020/3/29 + */ +@Service +public class GrpcClientService { + + @GrpcClient("demo-grpc-server") + private DemoServiceGrpc.DemoServiceBlockingStub demoServiceBlockingStub; + + public DemoResponse hello() { + return demoServiceBlockingStub.hello(DemoRequest.newBuilder().build()); + } +} diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/resources/application.yml b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/resources/application.yml new file mode 100644 index 000000000..5ff249671 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/resources/application.yml @@ -0,0 +1,23 @@ +server: + port: 8090 +spring: + application: + name: demo-grpc-client +grpc: + client: + demo-grpc-server: + address: 'static://localhost:9090' + # 禁用传输图层安全 请勿在生产环境中这样做 + #negotiationType: plaintext + # gRPC 默认使用 TLS 连接服务端 该配置启用传输图层安全 + negotiationType: TLS + security: + #如果您信任的证书不在常规信任存储区, 或者您想要限制您信任的 证书。您可以使用以下属性 + trustCertCollection: classpath:certificates/trusted-server.crt.list + #要指定证书对哪个名字有效: + authorityOverride: localhost + #如果需要双向证书认证配置如下属性 + clientAuthEnabled: true + certificateChain: classpath:certificates/client.crt + privateKey: classpath:certificates/client.key + diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/resources/certificates/client.crt b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/resources/certificates/client.crt new file mode 100644 index 000000000..d5d324387 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/resources/certificates/client.crt @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFIzCCAwugAwIBAgIUBbeCJLNMSmJI4X2IHaOpz42GNZowDQYJKoZIhvcNAQEL +BQAwITESMBAGA1UEAwwJbG9jYWxob3N0MQswCQYDVQQGEwJDTjAeFw0yMDAzMjkw +NTE1MDhaFw0zMDAzMjcwNTE1MDhaMCExEjAQBgNVBAMMCWxvY2FsaG9zdDELMAkG +A1UEBhMCQ04wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDPGZ2P0qLb +qxGjt+AhIvAqnE1xIVESy05d9VUYqHCjp/UG3FMFA8YlXXeAjjW4yV6ZOSeAwgMV +DXX4vrQEiH1ZhDyXI4O8wuEvZG63oNWdpzbFCsXvXjZbVfUiaCvybjUzOBUxoNoT +E6YNQ+ELXizruC7NBcT7QfG1iZXbbYRArIJK9KXIS0rHKjiVNZR+8IEN7t0GfH7D +X2CmHmZzmPttLPFhcUfsJX1mNKGy/zFU+etka6BrV0gw4KwC7p8YpR2fXQfD3TxB +HTz9lXb0UvcKghaJDFDpMI4oUGGSqOgdGJvLBQ3SqvE4fDX+C+vGhaLgU1ut+Coh +PUWx1HMtsP7YQuK7/tSmNBdfQObfu9WgADOYx2oOITuA/ziVeOR3rkbA37p3lUhL +vRKfjywU/5tEsQlcdrEK0csO9tPcetqQjlOF8Jlb8VbsKtAC3KLUpPIjJRw5sbtL +r8SCm+aeTqpXtrT0sBVpsb8QBX8/RPHLU8H3UBNrmS5U++8lZ+Z1mQnfexWfPObx +N7M0MJZUKUQqdUTdUGgeV4JSQxLQByEntbuOKiS706VC6PV4C87xXw0qU0hshyip +jyAht31D9vc8eMkAklMqJ3IGFr65n+15O1D79NS3boxF1kLjvE50nlG30k2q3MXF +zTnfH5K7iSBjwVv6Cpt0f/jFgxxnqKRn4QIDAQABo1MwUTAdBgNVHQ4EFgQUpwe5 +lEf4PzqvhKIFdbJQX3umNkQwHwYDVR0jBBgwFoAUpwe5lEf4PzqvhKIFdbJQX3um +NkQwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAivb7EBwXy1QD +hHAbE8w2b+7b3biGug8+aOo12O6+klahUwCqwBYM8ek+G2eO9r9++CO1+Zqu+TGF +34zJBxc23MHzdFMqUaPdhqopB/rL2cnberHyJLbShB5vYG+RnZ7O8pnloxKPNHNu +rFIQMlbHWzBe3jxTJye+4PEi2DqEdqbDu7F/ZWyIxGlJgzPvXn/IfMU/Nbn/lcpS +aZHI8rc0ZzaHeqbkp8O0BnrVdkcs3YXZeQLYw/huj1AjyBBW/lc+U3Dm7wze5/rm +wXTIUzJ5uS3Eg70DTvLAn1ux0CdJJbC5DoZsK+aKL6gEMYhIK1ysfD7g6GZB4ZII +TAHuhv4zRkuZWNHl2jZAI1Zcm4ElUKspPMkEeVz8Ir7LWbRSv/f7gnss2hEy0MK4 +2aZXOmrNIajWHn9+ZESRAKCeZxxBs1cePIcrBDHBZkpt8gesevY9lx9JO14baZNK +POB+30C5BspEUXQOj8QzyyiBWBjGnhLelncDwyPjfcTCKXnr+qdmX63RqyvPgezF +C6O2Z1l38WT9KLQtX9qqlZPFakeMh+t4nXdkKn6qKPaubQWILQiuo0P9F2ANgdoZ +AeVYmpQkcJT+wKVIsYC9BASwiKvf2MGLYcVIZDG4/kfIsQU7J5dLFFNOweDHkhuc +2cWvvicGgDox34LQRs0GNcJnFlZl2Tg= +-----END CERTIFICATE----- diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/resources/certificates/client.key b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/resources/certificates/client.key new file mode 100644 index 000000000..87527443a --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/resources/certificates/client.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +9a1pQp7WUIHq9TJ4CHNkQm68d+UUC1a26A== +-----END PRIVATE KEY----- diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/resources/certificates/trusted-server.crt.list b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/resources/certificates/trusted-server.crt.list new file mode 100644 index 000000000..373f82a75 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-client/src/main/resources/certificates/trusted-server.crt.list @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFIzCCAwugAwIBAgIUfCbsdJCysoJf1n1QNn9czuJyTm4wDQYJKoZIhvcNAQEL +BQAwITESMBAGA1UEAwwJbG9jYWxob3N0MQswCQYDVQQGEwJDTjAeFw0yMDAzMjkw +NDM2NTJaFw0zMDAzMjcwNDM2NTJaMCExEjAQBgNVBAMMCWxvY2FsaG9zdDELMAkG +A1UEBhMCQ04wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG1jMHauqe +3DTt5vwNSYcPVyg+sRArKGGMLw31EuyQzHnFl0N0G5DsYntqcSKAXLMFe9+oveD0 +sHjsnMpjYO1HiyVgYsSYD20RLNQiaqPS1X4TebOB9gGI4dD3u5TmO64Fd3HDk6r+ +AuAmzrcbWB/LXE9uuN4OclAfzYSEUwkIAlfvLDfslF2pqFs/yuxYWrbiy/XWZ6TZ +WSyai8vE1FhhzR1wb8a4SfUmK0hwLvfC765wrzlJKyzh0G+m9fV+S29BKBMDQUDZ +b9cQ4HKkhnv6OAZq54ZK1UXg/q8dR6/hgMqyCQePoxXlKQEhQeYadN7A45hcFhdi +kfqWnhyPo93espy6nnH+6i38Iw5YgzvIzU3R7o6cuo73IukCV5JoauedIep7cdnh +4BcHng72o/PX3x7Ot2tALLGmD7MZk5zO/Trg30mxc9Tbm2R2qRcY6MXZHPciVTMG +ORy4bav/VCUi4mRPhTVFSjwbOf4TUKYmwLIYvBqry7efd9AI2FppTEJC4J29FHp5 +WHLywQuXeyoAnWPaXB/MUYot2RqdBT6yxIJK2zpcqAB7kAlX3784rTm1oRBJUN2I ++Uwlgx6CScpLRkT1SPj+IVsVg+1aG8zwYohlgp8YtKUpHtcoPKi8hQyyYAkI+vok +8Yb0+2kgw25vBYspRK29yA7zMigfF3HzWwIDAQABo1MwUTAdBgNVHQ4EFgQUcW0v +fFsWCeRlc7lX40ePLlU+1C4wHwYDVR0jBBgwFoAUcW0vfFsWCeRlc7lX40ePLlU+ +1C4wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAcIltklIfMUC1 +YCbjnnO9+/2AfsSAM0cuUjUjRnljJ1CfhCLQHZR2mHcK1ofNP6nU+zyf2PC0Cj48 +/PdPdWqVDeEUIJqw9tREsyptpHnEisNBKraaLjS5QOlHQ13gE95xRwr62nvxM3bg +RmmE2TqDwnpfPyVqU+VQA+EIYXX4KIO4eOmsF7yOE0Cxux0W6dvEBkZ3X9v06tmD +5MP60cM19Xl26MnM+8gEhEPcuD99jbu3Rkvwl43tM4xswDJn9Hy0bPc9L9cMmxId +NTNnxV54sHvUYNFGtho3yPDwo8n0kw2t1RegXbJlfJ1DTD2K6QI9eeqAJA2ETV2m +AuQmTAW/ar3+u9OWzNX9inlaySHYMKEhxEFRFJ2DEEXfct2KvZj6K+iQISm2+Um5 +68rX8kcIfJuZ45qdcbsBAXnOy0FaN3Qpj1Q6l/WVHn0KqW50vYt+yyFSyQ574ijY +PG/yHuY0Pqk+vsBU95l906pcLdGZh149GjtB1WQt0NCrv5HNVjt1e09F0giBNa2p +RyG92RN5xEWctmxLdDPezbWiyiCPOkoZS6ueroPY4TXSQGq1XwjVTGWhL5DqyId/ +ZFeucwgNhx69De3AQvM7BnhpOrb+r3XoaYHedBUuwMhX1wPnRJl3Yk93032MiWO/ +x4ibzkbrqJUWZhHEwMr5Nm4DSRDjv90= +-----END CERTIFICATE----- diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/pom.xml b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/pom.xml new file mode 100644 index 000000000..f44213917 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/pom.xml @@ -0,0 +1,69 @@ + + + + spring-boot-demo-grpc + com.xkcoding + 1.0.0-SNAPSHOT + + 4.0.0 + + spring-boot-demo-grpc-protocol + jar + + + + io.grpc + grpc-netty-shaded + ${grpc.version} + + + io.grpc + grpc-protobuf + ${grpc.version} + + + io.grpc + grpc-stub + ${grpc.version} + + + + + + + + kr.motd.maven + os-maven-plugin + ${os-maven-plugin.version} + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + ${protobuf-maven-plugin.version} + + com.google.protobuf:protoc:${com.google.protobuf.protoc.version}:exe:${os.detected.classifier} + grpc-java + io.grpc:protoc-gen-grpc-java:${protoc-gen-grpc-java.version}:exe:${os.detected.classifier} + ${project.basedir}/src/main/java + false + + + + + compile + compile-custom + + + + + + + diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoProto.java b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoProto.java new file mode 100644 index 000000000..8c460838e --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoProto.java @@ -0,0 +1,61 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: demo.proto + +package com.xkcoding.grpc.protocol; + +public final class DemoProto { + private DemoProto() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + static final com.google.protobuf.Descriptors.Descriptor + internal_static_DemoResponse_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_DemoResponse_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_DemoRequest_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_DemoRequest_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\ndemo.proto\"\033\n\014DemoResponse\022\013\n\003msg\030\001 \001(" + + "\t\"\r\n\013DemoRequest25\n\013DemoService\022&\n\005hello" + + "\022\014.DemoRequest\032\r.DemoResponse\"\000B)\n\032com.x" + + "kcoding.grpc.protocolB\tDemoProtoP\001b\006prot" + + "o3" + }; + descriptor = com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }); + internal_static_DemoResponse_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_DemoResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_DemoResponse_descriptor, + new java.lang.String[] { "Msg", }); + internal_static_DemoRequest_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_DemoRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_DemoRequest_descriptor, + new java.lang.String[] { }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoRequest.java b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoRequest.java new file mode 100644 index 000000000..eb2d4ea65 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoRequest.java @@ -0,0 +1,427 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: demo.proto + +package com.xkcoding.grpc.protocol; + +/** + *
+ * 请求实体类
+ * 
+ * + * Protobuf type {@code DemoRequest} + */ +public final class DemoRequest extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:DemoRequest) + DemoRequestOrBuilder { +private static final long serialVersionUID = 0L; + // Use DemoRequest.newBuilder() to construct. + private DemoRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private DemoRequest() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new DemoRequest(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DemoRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.xkcoding.grpc.protocol.DemoProto.internal_static_DemoRequest_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.xkcoding.grpc.protocol.DemoProto.internal_static_DemoRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.xkcoding.grpc.protocol.DemoRequest.class, com.xkcoding.grpc.protocol.DemoRequest.Builder.class); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.xkcoding.grpc.protocol.DemoRequest)) { + return super.equals(obj); + } + com.xkcoding.grpc.protocol.DemoRequest other = (com.xkcoding.grpc.protocol.DemoRequest) obj; + + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.xkcoding.grpc.protocol.DemoRequest parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.xkcoding.grpc.protocol.DemoRequest parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.xkcoding.grpc.protocol.DemoRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.xkcoding.grpc.protocol.DemoRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.xkcoding.grpc.protocol.DemoRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.xkcoding.grpc.protocol.DemoRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.xkcoding.grpc.protocol.DemoRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.xkcoding.grpc.protocol.DemoRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static com.xkcoding.grpc.protocol.DemoRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static com.xkcoding.grpc.protocol.DemoRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static com.xkcoding.grpc.protocol.DemoRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.xkcoding.grpc.protocol.DemoRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(com.xkcoding.grpc.protocol.DemoRequest prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+   * 请求实体类
+   * 
+ * + * Protobuf type {@code DemoRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:DemoRequest) + com.xkcoding.grpc.protocol.DemoRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.xkcoding.grpc.protocol.DemoProto.internal_static_DemoRequest_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.xkcoding.grpc.protocol.DemoProto.internal_static_DemoRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.xkcoding.grpc.protocol.DemoRequest.class, com.xkcoding.grpc.protocol.DemoRequest.Builder.class); + } + + // Construct using com.xkcoding.grpc.protocol.DemoRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.xkcoding.grpc.protocol.DemoProto.internal_static_DemoRequest_descriptor; + } + + @java.lang.Override + public com.xkcoding.grpc.protocol.DemoRequest getDefaultInstanceForType() { + return com.xkcoding.grpc.protocol.DemoRequest.getDefaultInstance(); + } + + @java.lang.Override + public com.xkcoding.grpc.protocol.DemoRequest build() { + com.xkcoding.grpc.protocol.DemoRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.xkcoding.grpc.protocol.DemoRequest buildPartial() { + com.xkcoding.grpc.protocol.DemoRequest result = new com.xkcoding.grpc.protocol.DemoRequest(this); + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.xkcoding.grpc.protocol.DemoRequest) { + return mergeFrom((com.xkcoding.grpc.protocol.DemoRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.xkcoding.grpc.protocol.DemoRequest other) { + if (other == com.xkcoding.grpc.protocol.DemoRequest.getDefaultInstance()) return this; + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.xkcoding.grpc.protocol.DemoRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.xkcoding.grpc.protocol.DemoRequest) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:DemoRequest) + } + + // @@protoc_insertion_point(class_scope:DemoRequest) + private static final com.xkcoding.grpc.protocol.DemoRequest DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new com.xkcoding.grpc.protocol.DemoRequest(); + } + + public static com.xkcoding.grpc.protocol.DemoRequest getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public DemoRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DemoRequest(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.xkcoding.grpc.protocol.DemoRequest getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoRequestOrBuilder.java b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoRequestOrBuilder.java new file mode 100644 index 000000000..0b0dfa8f3 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoRequestOrBuilder.java @@ -0,0 +1,9 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: demo.proto + +package com.xkcoding.grpc.protocol; + +public interface DemoRequestOrBuilder extends + // @@protoc_insertion_point(interface_extends:DemoRequest) + com.google.protobuf.MessageOrBuilder { +} diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoResponse.java b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoResponse.java new file mode 100644 index 000000000..93dd5cfd4 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoResponse.java @@ -0,0 +1,563 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: demo.proto + +package com.xkcoding.grpc.protocol; + +/** + *
+ * 响应实体类
+ * 
+ * + * Protobuf type {@code DemoResponse} + */ +public final class DemoResponse extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:DemoResponse) + DemoResponseOrBuilder { +private static final long serialVersionUID = 0L; + // Use DemoResponse.newBuilder() to construct. + private DemoResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private DemoResponse() { + msg_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new DemoResponse(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DemoResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + + msg_ = s; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.xkcoding.grpc.protocol.DemoProto.internal_static_DemoResponse_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.xkcoding.grpc.protocol.DemoProto.internal_static_DemoResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.xkcoding.grpc.protocol.DemoResponse.class, com.xkcoding.grpc.protocol.DemoResponse.Builder.class); + } + + public static final int MSG_FIELD_NUMBER = 1; + private volatile java.lang.Object msg_; + /** + * string msg = 1; + * @return The msg. + */ + public java.lang.String getMsg() { + java.lang.Object ref = msg_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + msg_ = s; + return s; + } + } + /** + * string msg = 1; + * @return The bytes for msg. + */ + public com.google.protobuf.ByteString + getMsgBytes() { + java.lang.Object ref = msg_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + msg_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getMsgBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, msg_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getMsgBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, msg_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.xkcoding.grpc.protocol.DemoResponse)) { + return super.equals(obj); + } + com.xkcoding.grpc.protocol.DemoResponse other = (com.xkcoding.grpc.protocol.DemoResponse) obj; + + if (!getMsg() + .equals(other.getMsg())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + MSG_FIELD_NUMBER; + hash = (53 * hash) + getMsg().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.xkcoding.grpc.protocol.DemoResponse parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.xkcoding.grpc.protocol.DemoResponse parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.xkcoding.grpc.protocol.DemoResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.xkcoding.grpc.protocol.DemoResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.xkcoding.grpc.protocol.DemoResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.xkcoding.grpc.protocol.DemoResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.xkcoding.grpc.protocol.DemoResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.xkcoding.grpc.protocol.DemoResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static com.xkcoding.grpc.protocol.DemoResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static com.xkcoding.grpc.protocol.DemoResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static com.xkcoding.grpc.protocol.DemoResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.xkcoding.grpc.protocol.DemoResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(com.xkcoding.grpc.protocol.DemoResponse prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+   * 响应实体类
+   * 
+ * + * Protobuf type {@code DemoResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:DemoResponse) + com.xkcoding.grpc.protocol.DemoResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.xkcoding.grpc.protocol.DemoProto.internal_static_DemoResponse_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.xkcoding.grpc.protocol.DemoProto.internal_static_DemoResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.xkcoding.grpc.protocol.DemoResponse.class, com.xkcoding.grpc.protocol.DemoResponse.Builder.class); + } + + // Construct using com.xkcoding.grpc.protocol.DemoResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + msg_ = ""; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.xkcoding.grpc.protocol.DemoProto.internal_static_DemoResponse_descriptor; + } + + @java.lang.Override + public com.xkcoding.grpc.protocol.DemoResponse getDefaultInstanceForType() { + return com.xkcoding.grpc.protocol.DemoResponse.getDefaultInstance(); + } + + @java.lang.Override + public com.xkcoding.grpc.protocol.DemoResponse build() { + com.xkcoding.grpc.protocol.DemoResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.xkcoding.grpc.protocol.DemoResponse buildPartial() { + com.xkcoding.grpc.protocol.DemoResponse result = new com.xkcoding.grpc.protocol.DemoResponse(this); + result.msg_ = msg_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.xkcoding.grpc.protocol.DemoResponse) { + return mergeFrom((com.xkcoding.grpc.protocol.DemoResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.xkcoding.grpc.protocol.DemoResponse other) { + if (other == com.xkcoding.grpc.protocol.DemoResponse.getDefaultInstance()) return this; + if (!other.getMsg().isEmpty()) { + msg_ = other.msg_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.xkcoding.grpc.protocol.DemoResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.xkcoding.grpc.protocol.DemoResponse) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object msg_ = ""; + /** + * string msg = 1; + * @return The msg. + */ + public java.lang.String getMsg() { + java.lang.Object ref = msg_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + msg_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string msg = 1; + * @return The bytes for msg. + */ + public com.google.protobuf.ByteString + getMsgBytes() { + java.lang.Object ref = msg_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + msg_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string msg = 1; + * @param value The msg to set. + * @return This builder for chaining. + */ + public Builder setMsg( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + msg_ = value; + onChanged(); + return this; + } + /** + * string msg = 1; + * @return This builder for chaining. + */ + public Builder clearMsg() { + + msg_ = getDefaultInstance().getMsg(); + onChanged(); + return this; + } + /** + * string msg = 1; + * @param value The bytes for msg to set. + * @return This builder for chaining. + */ + public Builder setMsgBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + msg_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:DemoResponse) + } + + // @@protoc_insertion_point(class_scope:DemoResponse) + private static final com.xkcoding.grpc.protocol.DemoResponse DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new com.xkcoding.grpc.protocol.DemoResponse(); + } + + public static com.xkcoding.grpc.protocol.DemoResponse getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public DemoResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DemoResponse(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.xkcoding.grpc.protocol.DemoResponse getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoResponseOrBuilder.java b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoResponseOrBuilder.java new file mode 100644 index 000000000..673385dab --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoResponseOrBuilder.java @@ -0,0 +1,21 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: demo.proto + +package com.xkcoding.grpc.protocol; + +public interface DemoResponseOrBuilder extends + // @@protoc_insertion_point(interface_extends:DemoResponse) + com.google.protobuf.MessageOrBuilder { + + /** + * string msg = 1; + * @return The msg. + */ + java.lang.String getMsg(); + /** + * string msg = 1; + * @return The bytes for msg. + */ + com.google.protobuf.ByteString + getMsgBytes(); +} diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoServiceGrpc.java b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoServiceGrpc.java new file mode 100644 index 000000000..c85f01e6b --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/java/com/xkcoding/grpc/protocol/DemoServiceGrpc.java @@ -0,0 +1,288 @@ +package com.xkcoding.grpc.protocol; + +import static io.grpc.MethodDescriptor.generateFullMethodName; +import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; +import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; +import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; +import static io.grpc.stub.ClientCalls.asyncUnaryCall; +import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; +import static io.grpc.stub.ClientCalls.blockingUnaryCall; +import static io.grpc.stub.ClientCalls.futureUnaryCall; +import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; +import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; +import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; +import static io.grpc.stub.ServerCalls.asyncUnaryCall; +import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; +import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; + +/** + */ +@javax.annotation.Generated( + value = "by gRPC proto compiler (version 1.27.1)", + comments = "Source: demo.proto") +public final class DemoServiceGrpc { + + private DemoServiceGrpc() {} + + public static final String SERVICE_NAME = "DemoService"; + + // Static method descriptors that strictly reflect the proto. + private static volatile io.grpc.MethodDescriptor getHelloMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "hello", + requestType = com.xkcoding.grpc.protocol.DemoRequest.class, + responseType = com.xkcoding.grpc.protocol.DemoResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getHelloMethod() { + io.grpc.MethodDescriptor getHelloMethod; + if ((getHelloMethod = DemoServiceGrpc.getHelloMethod) == null) { + synchronized (DemoServiceGrpc.class) { + if ((getHelloMethod = DemoServiceGrpc.getHelloMethod) == null) { + DemoServiceGrpc.getHelloMethod = getHelloMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "hello")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + com.xkcoding.grpc.protocol.DemoRequest.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + com.xkcoding.grpc.protocol.DemoResponse.getDefaultInstance())) + .setSchemaDescriptor(new DemoServiceMethodDescriptorSupplier("hello")) + .build(); + } + } + } + return getHelloMethod; + } + + /** + * Creates a new async stub that supports all call types for the service + */ + public static DemoServiceStub newStub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public DemoServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DemoServiceStub(channel, callOptions); + } + }; + return DemoServiceStub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static DemoServiceBlockingStub newBlockingStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public DemoServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DemoServiceBlockingStub(channel, callOptions); + } + }; + return DemoServiceBlockingStub.newStub(factory, channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static DemoServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public DemoServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DemoServiceFutureStub(channel, callOptions); + } + }; + return DemoServiceFutureStub.newStub(factory, channel); + } + + /** + */ + public static abstract class DemoServiceImplBase implements io.grpc.BindableService { + + /** + */ + public void hello(com.xkcoding.grpc.protocol.DemoRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(getHelloMethod(), responseObserver); + } + + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getHelloMethod(), + asyncUnaryCall( + new MethodHandlers< + com.xkcoding.grpc.protocol.DemoRequest, + com.xkcoding.grpc.protocol.DemoResponse>( + this, METHODID_HELLO))) + .build(); + } + } + + /** + */ + public static final class DemoServiceStub extends io.grpc.stub.AbstractAsyncStub { + private DemoServiceStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected DemoServiceStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DemoServiceStub(channel, callOptions); + } + + /** + */ + public void hello(com.xkcoding.grpc.protocol.DemoRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(getHelloMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + */ + public static final class DemoServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + private DemoServiceBlockingStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected DemoServiceBlockingStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DemoServiceBlockingStub(channel, callOptions); + } + + /** + */ + public com.xkcoding.grpc.protocol.DemoResponse hello(com.xkcoding.grpc.protocol.DemoRequest request) { + return blockingUnaryCall( + getChannel(), getHelloMethod(), getCallOptions(), request); + } + } + + /** + */ + public static final class DemoServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + private DemoServiceFutureStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected DemoServiceFutureStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DemoServiceFutureStub(channel, callOptions); + } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture hello( + com.xkcoding.grpc.protocol.DemoRequest request) { + return futureUnaryCall( + getChannel().newCall(getHelloMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_HELLO = 0; + + private static final class MethodHandlers implements + io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final DemoServiceImplBase serviceImpl; + private final int methodId; + + MethodHandlers(DemoServiceImplBase serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_HELLO: + serviceImpl.hello((com.xkcoding.grpc.protocol.DemoRequest) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + default: + throw new AssertionError(); + } + } + } + + private static abstract class DemoServiceBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier { + DemoServiceBaseDescriptorSupplier() {} + + @java.lang.Override + public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { + return com.xkcoding.grpc.protocol.DemoProto.getDescriptor(); + } + + @java.lang.Override + public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() { + return getFileDescriptor().findServiceByName("DemoService"); + } + } + + private static final class DemoServiceFileDescriptorSupplier + extends DemoServiceBaseDescriptorSupplier { + DemoServiceFileDescriptorSupplier() {} + } + + private static final class DemoServiceMethodDescriptorSupplier + extends DemoServiceBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { + private final String methodName; + + DemoServiceMethodDescriptorSupplier(String methodName) { + this.methodName = methodName; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() { + return getServiceDescriptor().findMethodByName(methodName); + } + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (DemoServiceGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .setSchemaDescriptor(new DemoServiceFileDescriptorSupplier()) + .addMethod(getHelloMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/proto/demo.proto b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/proto/demo.proto new file mode 100644 index 000000000..56262eadd --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-protocol/src/main/proto/demo.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "com.xkcoding.grpc.protocol"; +option java_outer_classname = "DemoProto"; + + +// +service DemoService { + rpc hello (DemoRequest) returns (DemoResponse) { + } +} + +// 响应实体类 +message DemoResponse { + string msg = 1; +} + +// 请求实体类 +message DemoRequest { +} diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-server/pom.xml b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/pom.xml new file mode 100644 index 000000000..31b861b13 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/pom.xml @@ -0,0 +1,32 @@ + + + + spring-boot-demo-grpc + com.xkcoding + 1.0.0-SNAPSHOT + + 4.0.0 + + spring-boot-demo-grpc-server + jar + + + + com.xkcoding + spring-boot-demo-grpc-protocol + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + + net.devh + grpc-server-spring-boot-starter + + + diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/java/com/xkcoding/grpc/server/SpringBootDemoGrpcServerApplication.java b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/java/com/xkcoding/grpc/server/SpringBootDemoGrpcServerApplication.java new file mode 100644 index 000000000..7d4eb7807 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/java/com/xkcoding/grpc/server/SpringBootDemoGrpcServerApplication.java @@ -0,0 +1,17 @@ +package com.xkcoding.grpc.server; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author dengliming + * @date 2020/3/29 + */ +@SpringBootApplication +public class SpringBootDemoGrpcServerApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootDemoGrpcServerApplication.class, args); + } + +} diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/java/com/xkcoding/grpc/server/service/GrpcServerService.java b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/java/com/xkcoding/grpc/server/service/GrpcServerService.java new file mode 100644 index 000000000..22b748d99 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/java/com/xkcoding/grpc/server/service/GrpcServerService.java @@ -0,0 +1,22 @@ +package com.xkcoding.grpc.server.service; + +import com.xkcoding.grpc.protocol.DemoRequest; +import com.xkcoding.grpc.protocol.DemoResponse; +import com.xkcoding.grpc.protocol.DemoServiceGrpc; +import io.grpc.stub.StreamObserver; +import net.devh.boot.grpc.server.service.GrpcService; + +/** + * @author dengliming + * @date 2020/3/29 + */ +@GrpcService +public class GrpcServerService extends DemoServiceGrpc.DemoServiceImplBase { + + @Override + public void hello(DemoRequest request, StreamObserver responseObserver) { + DemoResponse response = DemoResponse.newBuilder().setMsg("Hi~").build(); + responseObserver.onNext(response); + responseObserver.onCompleted(); + } +} diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/resources/application.yml b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/resources/application.yml new file mode 100644 index 000000000..2c7ef3316 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/resources/application.yml @@ -0,0 +1,15 @@ +spring: + application: + name: demo-grpc-server +grpc: + server: + port: 9090 + # 开启TLS相关配置 + security: + enabled: true + certificateChain: classpath:certificates/server.crt + privateKey: classpath:certificates/server.key + #如果需要指定受信任客户端证书 直接把client.crt复制到该文件即可 + trustCertCollection: classpath:certificates/trusted-clients.crt.list + #REQUIRE:客户端证书必须通过认证 OPTIONAL:对客户端的证书进行身份验证,但不会强制这么做。 + clientAuth: REQUIRE diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/resources/certificates/server.crt b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/resources/certificates/server.crt new file mode 100644 index 000000000..373f82a75 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/resources/certificates/server.crt @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFIzCCAwugAwIBAgIUfCbsdJCysoJf1n1QNn9czuJyTm4wDQYJKoZIhvcNAQEL +BQAwITESMBAGA1UEAwwJbG9jYWxob3N0MQswCQYDVQQGEwJDTjAeFw0yMDAzMjkw +NDM2NTJaFw0zMDAzMjcwNDM2NTJaMCExEjAQBgNVBAMMCWxvY2FsaG9zdDELMAkG +A1UEBhMCQ04wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG1jMHauqe +3DTt5vwNSYcPVyg+sRArKGGMLw31EuyQzHnFl0N0G5DsYntqcSKAXLMFe9+oveD0 +sHjsnMpjYO1HiyVgYsSYD20RLNQiaqPS1X4TebOB9gGI4dD3u5TmO64Fd3HDk6r+ +AuAmzrcbWB/LXE9uuN4OclAfzYSEUwkIAlfvLDfslF2pqFs/yuxYWrbiy/XWZ6TZ +WSyai8vE1FhhzR1wb8a4SfUmK0hwLvfC765wrzlJKyzh0G+m9fV+S29BKBMDQUDZ +b9cQ4HKkhnv6OAZq54ZK1UXg/q8dR6/hgMqyCQePoxXlKQEhQeYadN7A45hcFhdi +kfqWnhyPo93espy6nnH+6i38Iw5YgzvIzU3R7o6cuo73IukCV5JoauedIep7cdnh +4BcHng72o/PX3x7Ot2tALLGmD7MZk5zO/Trg30mxc9Tbm2R2qRcY6MXZHPciVTMG +ORy4bav/VCUi4mRPhTVFSjwbOf4TUKYmwLIYvBqry7efd9AI2FppTEJC4J29FHp5 +WHLywQuXeyoAnWPaXB/MUYot2RqdBT6yxIJK2zpcqAB7kAlX3784rTm1oRBJUN2I ++Uwlgx6CScpLRkT1SPj+IVsVg+1aG8zwYohlgp8YtKUpHtcoPKi8hQyyYAkI+vok +8Yb0+2kgw25vBYspRK29yA7zMigfF3HzWwIDAQABo1MwUTAdBgNVHQ4EFgQUcW0v +fFsWCeRlc7lX40ePLlU+1C4wHwYDVR0jBBgwFoAUcW0vfFsWCeRlc7lX40ePLlU+ +1C4wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAcIltklIfMUC1 +YCbjnnO9+/2AfsSAM0cuUjUjRnljJ1CfhCLQHZR2mHcK1ofNP6nU+zyf2PC0Cj48 +/PdPdWqVDeEUIJqw9tREsyptpHnEisNBKraaLjS5QOlHQ13gE95xRwr62nvxM3bg +RmmE2TqDwnpfPyVqU+VQA+EIYXX4KIO4eOmsF7yOE0Cxux0W6dvEBkZ3X9v06tmD +5MP60cM19Xl26MnM+8gEhEPcuD99jbu3Rkvwl43tM4xswDJn9Hy0bPc9L9cMmxId +NTNnxV54sHvUYNFGtho3yPDwo8n0kw2t1RegXbJlfJ1DTD2K6QI9eeqAJA2ETV2m +AuQmTAW/ar3+u9OWzNX9inlaySHYMKEhxEFRFJ2DEEXfct2KvZj6K+iQISm2+Um5 +68rX8kcIfJuZ45qdcbsBAXnOy0FaN3Qpj1Q6l/WVHn0KqW50vYt+yyFSyQ574ijY +PG/yHuY0Pqk+vsBU95l906pcLdGZh149GjtB1WQt0NCrv5HNVjt1e09F0giBNa2p +RyG92RN5xEWctmxLdDPezbWiyiCPOkoZS6ueroPY4TXSQGq1XwjVTGWhL5DqyId/ +ZFeucwgNhx69De3AQvM7BnhpOrb+r3XoaYHedBUuwMhX1wPnRJl3Yk93032MiWO/ +x4ibzkbrqJUWZhHEwMr5Nm4DSRDjv90= +-----END CERTIFICATE----- diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/resources/certificates/server.key b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/resources/certificates/server.key new file mode 100644 index 000000000..0d0ffca4a --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/resources/certificates/server.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDG1jMHauqe3DTt +5vwNSYcPVyg+sRArKGGMLw31EuyQzHnFl0N0G5DsYntqcSKAXLMFe9+oveD0sHjs +nMpjYO1HiyVgYsSYD20RLNQiaqPS1X4TebOB9gGI4dD3u5TmO64Fd3HDk6r+AuAm +zrcbWB/LXE9uuN4OclAfzYSEUwkIAlfvLDfslF2pqFs/yuxYWrbiy/XWZ6TZWSya +i8vE1FhhzR1wb8a4SfUmK0hwLvfC765wrzlJKyzh0G+m9fV+S29BKBMDQUDZb9cQ +4HKkhnv6OAZq54ZK1UXg/q8dR6/hgMqyCQePoxXlKQEhQeYadN7A45hcFhdikfqW +nhyPo93espy6nnH+6i38Iw5YgzvIzU3R7o6cuo73IukCV5JoauedIep7cdnh4BcH +ng72o/PX3x7Ot2tALLGmD7MZk5zO/Trg30mxc9Tbm2R2qRcY6MXZHPciVTMGORy4 +bav/VCUi4mRPhTVFSjwbOf4TUKYmwLIYvBqry7efd9AI2FppTEJC4J29FHp5WHLy +wQuXeyoAnWPaXB/MUYot2RqdBT6yxIJK2zpcqAB7kAlX3784rTm1oRBJUN2I+Uwl +gx6CScpLRkT1SPj+IVsVg+1aG8zwYohlgp8YtKUpHtcoPKi8hQyyYAkI+vok8Yb0 ++2kgw25vBYspRK29yA7zMigfF3HzWwIDAQABAoICABcSwicpNAKtQQMeW79a+e5A +ye3EdEDd1bwDtdXrlUIUSEkyjWRK0p1rrDCk4kENAMUxI7ocFp+uXsnuQ9oWZFJ6 +BiNSMsgGejyU/CTmRQ5xMckmxTrehj0RH0OwI843vLDrtGriluQVB1fZgwwMRNw/ +YQRTNYltoHigS7FjRVgFlZiug+rTKK9IVxZnANgb5r8YtfVkX4/NNkzUzheQIJVw +zOrAPcoi4uzD9wr1mFCpqY9v9fDUrsehfWNdhVhbfpSMBvDIwLK6tLVDpmoLJRXb +LHt5VG8YopxCUaXPLMy5OkxAmf0ECsVl5birQf1t9G9juclt0tbgY7jYri3I8TTz +CYTBDrj4Hp1zV/yfNnxzlye5ud2UWKpTSkkkGRgKz0NyifeT1erk3gj2Cks/oBJx +Y6iIEmwbRbjjd3YS+AKkXtPGjKokiVVXz/3RDgKMKUsnPd8rmX7oDouK2VziC12d +871RJu2ztbMvdmZ+bnNftg8X8bTRFGyq2b/yFSK5Up4QfQ22VbxdtLpNMVOMnqF4 +MCdrd5mlSoPkQE6OF8gKjAl5lT3oBmgw36xKZlGZFvmSfcwvqdFMLk3SUAlk1eKK +7shLhzv6p9aQdqURTLmDL5TATeM4Zy05pFqOcqJ9ytDxHFpiXNX9Jmu6FZc3+pd6 +wPmfjAnqafli6zjiBLJxAoIBAQDujqI6y6uyny9llmJ2k+GykPDZE2Nf0fcmXAlu +uyUCcgJAifAZvu6nNqqWpw+N1XEWwM8KL6MB1lMkmqwgA9/pEIOiqtNmVVwGdWZa +i8JcmVgn0R+CroeUtx6N5lgkRk4UuD4GIxpZFsN4ewzcD6zcD+o4qEp0VzqJ/OY2 +8nvj51dLE7AaLX/Oh1ZwGGgFFOodTiHrYSZMPz/C0nROkbT4Acp3wFyLns7AA+QD +MUks3npjg9Oed06pAdNGjmxDCTlb/PmW7ncaSCQ1QaN0Ps1zQ1ulkpWlExhR+8BY +NH7goiTd5uUnB1wUpyW/PsDlAQo7m98hA30WBucMENPn0xoTAoIBAQDVYBHFqFgJ +OBnLQVzHgqZv4eWZP5kmSNfc40RvLaKsyHjsCLdQPs8tZmlYwiyzx/R8BKmLZ2+Z +aKG/oDxbl+/oUlmOEWVmr717PQmbRBbAjq9157BM/cu1rxlOL9UN/36vZd+2vWC/ +AnBS4OkBvBVOLuVMYeTVIUCzCWfHLAyQMxXCVulIak3yxkd08ny3rwWB0HUHLghR +S9UvWnpMBeNuLZ/xVomtwehZ8Hm//Q3Zz5QxjXJh6cfLm51zVfYnGBLdJFxuBqOk +402qdc16sNCRC+HpFBF5qPflemsyraL7/puDo2K33eb9pbaCk2xwdbFbvlUP2XcL +X8+pYt8oBuqZAoIBAQCMV3cTNdy1wbZlgjo83jTqEyDN4/0TUveeJokaDpjwPlga +1ctdqhjGYH+tD200GLxmEVn7+RhhrU/OefwG/aCNgTyfxvWE/3SbDBgB7rSSO1hE +XF+4RqrWj4A3JKr39DBdOiKrA52tiZnHWESxdbtQ30AAwujCVsrGgPSCoNbHtcKC +FXwFenz06GOuoH0ZeDtesCd+TPH160O8fokT695WBN+y4YTQUsX46pEKW8Vb0yqX +PueRE0lAXiWIHaONMHEBL+s5ouKIoKZEenAJpCTDyX2yA3Fr4rbtDDkU6xU1W85q +iTqIYmkGcWrgfq+GSb1WYhW7W00MV1U3oPK5MFTnAoIBAQDO5kTVYJNc/SUlzc9l +Ne6ldmnn259pXCDUcxscoyemWw3F8f2utfi2kSN9iWtHOJB84Rh1sGqqWqbc5Uch +mYZrw85Kz9t/YtFc+qaiA7f8J19D+NEfFsm89niXNBJnbGMvOJ1g2OlCzd6Uvrmx +kOsn0JlPI218rK3L7UbP/oqAGMj0lMnICixjSJhpceg1RGUWp0eTGrO+AMZLEHSd +2ufZIiyBG+SMtAXVkDS+UWZo2btdAUb0Ynf1moNmHuh8p/9Cp8todM+hRzc8HtaM +LX9P5jG8jFUVnx4hSj8/+NadexjY4EkM+QLO2SzMGJ+BvN2plDlvEPM5+EGogdLZ +QTuhAoIBAFkhItecd3+ncq5UEF7UDy9Fkb4W+hmJCe9HpaIMR3GZo4JbUZzifV3V +TFRf59Xxee9XKAidzedR2LIvRi3Dum88L+bVpKM1X5SGQtUNa1lvCqtsH7jCMyn5 +ivo38fNTRXuuVHN9KV2z8BTfRvQv7z+jyl4TGpaWGNvgFBsygb6z8U0tRmyLpiV2 +CB8YfV+dKtlcfAk6NfyXlZLr51Dj/c+9xTa2UKzQmnQ4SPRc3J8NJig1GxphFNQC +NCYAx1mSO4Nsb0u/OVWxMJt/52cQUvlQkzeoJfrjae0B7yTne0fqiRNogQJhF+rF +oVdYlh5VfTVUYd8NYOexMRJ95MZE5Ls= +-----END PRIVATE KEY----- diff --git a/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/resources/certificates/trusted-clients.crt.list b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/resources/certificates/trusted-clients.crt.list new file mode 100644 index 000000000..d5d324387 --- /dev/null +++ b/spring-boot-demo-grpc/spring-boot-demo-grpc-server/src/main/resources/certificates/trusted-clients.crt.list @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFIzCCAwugAwIBAgIUBbeCJLNMSmJI4X2IHaOpz42GNZowDQYJKoZIhvcNAQEL +BQAwITESMBAGA1UEAwwJbG9jYWxob3N0MQswCQYDVQQGEwJDTjAeFw0yMDAzMjkw +NTE1MDhaFw0zMDAzMjcwNTE1MDhaMCExEjAQBgNVBAMMCWxvY2FsaG9zdDELMAkG +A1UEBhMCQ04wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDPGZ2P0qLb +qxGjt+AhIvAqnE1xIVESy05d9VUYqHCjp/UG3FMFA8YlXXeAjjW4yV6ZOSeAwgMV +DXX4vrQEiH1ZhDyXI4O8wuEvZG63oNWdpzbFCsXvXjZbVfUiaCvybjUzOBUxoNoT +E6YNQ+ELXizruC7NBcT7QfG1iZXbbYRArIJK9KXIS0rHKjiVNZR+8IEN7t0GfH7D +X2CmHmZzmPttLPFhcUfsJX1mNKGy/zFU+etka6BrV0gw4KwC7p8YpR2fXQfD3TxB +HTz9lXb0UvcKghaJDFDpMI4oUGGSqOgdGJvLBQ3SqvE4fDX+C+vGhaLgU1ut+Coh +PUWx1HMtsP7YQuK7/tSmNBdfQObfu9WgADOYx2oOITuA/ziVeOR3rkbA37p3lUhL +vRKfjywU/5tEsQlcdrEK0csO9tPcetqQjlOF8Jlb8VbsKtAC3KLUpPIjJRw5sbtL +r8SCm+aeTqpXtrT0sBVpsb8QBX8/RPHLU8H3UBNrmS5U++8lZ+Z1mQnfexWfPObx +N7M0MJZUKUQqdUTdUGgeV4JSQxLQByEntbuOKiS706VC6PV4C87xXw0qU0hshyip +jyAht31D9vc8eMkAklMqJ3IGFr65n+15O1D79NS3boxF1kLjvE50nlG30k2q3MXF +zTnfH5K7iSBjwVv6Cpt0f/jFgxxnqKRn4QIDAQABo1MwUTAdBgNVHQ4EFgQUpwe5 +lEf4PzqvhKIFdbJQX3umNkQwHwYDVR0jBBgwFoAUpwe5lEf4PzqvhKIFdbJQX3um +NkQwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAivb7EBwXy1QD +hHAbE8w2b+7b3biGug8+aOo12O6+klahUwCqwBYM8ek+G2eO9r9++CO1+Zqu+TGF +34zJBxc23MHzdFMqUaPdhqopB/rL2cnberHyJLbShB5vYG+RnZ7O8pnloxKPNHNu +rFIQMlbHWzBe3jxTJye+4PEi2DqEdqbDu7F/ZWyIxGlJgzPvXn/IfMU/Nbn/lcpS +aZHI8rc0ZzaHeqbkp8O0BnrVdkcs3YXZeQLYw/huj1AjyBBW/lc+U3Dm7wze5/rm +wXTIUzJ5uS3Eg70DTvLAn1ux0CdJJbC5DoZsK+aKL6gEMYhIK1ysfD7g6GZB4ZII +TAHuhv4zRkuZWNHl2jZAI1Zcm4ElUKspPMkEeVz8Ir7LWbRSv/f7gnss2hEy0MK4 +2aZXOmrNIajWHn9+ZESRAKCeZxxBs1cePIcrBDHBZkpt8gesevY9lx9JO14baZNK +POB+30C5BspEUXQOj8QzyyiBWBjGnhLelncDwyPjfcTCKXnr+qdmX63RqyvPgezF +C6O2Z1l38WT9KLQtX9qqlZPFakeMh+t4nXdkKn6qKPaubQWILQiuo0P9F2ANgdoZ +AeVYmpQkcJT+wKVIsYC9BASwiKvf2MGLYcVIZDG4/kfIsQU7J5dLFFNOweDHkhuc +2cWvvicGgDox34LQRs0GNcJnFlZl2Tg= +-----END CERTIFICATE-----