diff --git a/docs/guide/python/grpc-support.md b/docs/guide/python/grpc-support.md index 946602be308..cdcff922430 100644 --- a/docs/guide/python/grpc-support.md +++ b/docs/guide/python/grpc-support.md @@ -29,11 +29,13 @@ encoding. Use standard protobuf gRPC code generation when clients or tools must consume protobuf message bytes directly. Generated Python companions currently target the synchronous `grpcio` API. Use -regular `def` servicer methods, `grpc.server(...)`, `grpc.insecure_channel(...)`, -and Python iterators or generators for streaming RPCs. The compiler does not +regular `def` servicer methods, `grpc.server(...)`, standard `grpc.Channel` +instances, and Python iterators or generators for streaming RPCs. The generated +stub accepts any channel configured by your application. The compiler does not generate `grpc.aio` stubs or service bases, so do not implement generated servicer methods as `async def` unless you add a custom adapter outside the -generated companion. +generated companion. Python gRPC async support based on `grpc.aio` will be +available in the next Fory release. ## Install Dependencies @@ -119,7 +121,8 @@ so service implementations do not perform manual Fory registration. ## Create a Client -Use the generated stub with a normal `grpcio` channel: +Use the generated stub with a normal `grpcio` channel. Production clients +usually pass a TLS/auth-configured channel: ```python import grpc @@ -129,7 +132,8 @@ import demo_greeter_grpc def main(): - with grpc.insecure_channel("localhost:50051") as channel: + credentials = grpc.ssl_channel_credentials() + with grpc.secure_channel("api.example.com:443", credentials) as channel: stub = demo_greeter_grpc.GreeterStub(channel) reply = stub.say_hello(demo_greeter.HelloRequest(name="Fory")) print(reply.reply) @@ -139,6 +143,14 @@ if __name__ == "__main__": main() ``` +For local tests and development, an insecure channel can be used explicitly: + +```python +# Test-only channel. Use a TLS/auth-configured grpc.Channel in production. +with grpc.insecure_channel("localhost:50051") as channel: + stub = demo_greeter_grpc.GreeterStub(channel) +``` + `grpcio` still owns channel options, credentials, deadlines, metadata, retries, and interceptors. @@ -158,12 +170,12 @@ service Greeter { Generated Python code follows `grpcio` conventions: -| IDL shape | Servicer method shape | Stub method shape | -| ----------------------------------------- | ------------------------------------------- | ---------------------------------- | -| `rpc A (Req) returns (Res)` | returns one response object | returns one response object | -| `rpc A (Req) returns (stream Res)` | yields response objects | returns an iterator of responses | -| `rpc A (stream Req) returns (Res)` | consumes an iterator and returns a response | accepts an iterator of requests | -| `rpc A (stream Req) returns (stream Res)` | consumes and yields iterators | accepts and returns iterators | +| IDL shape | Servicer method shape | Stub method shape | +| ----------------------------------------- | ------------------------------------------- | -------------------------------- | +| `rpc A (Req) returns (Res)` | returns one response object | returns one response object | +| `rpc A (Req) returns (stream Res)` | yields response objects | returns an iterator of responses | +| `rpc A (stream Req) returns (Res)` | consumes an iterator and returns a response | accepts an iterator of requests | +| `rpc A (stream Req) returns (stream Res)` | consumes and yields iterators | accepts and returns iterators | Servicer methods use snake_case names, while generated descriptors preserve the exact IDL service and method names for the gRPC path. @@ -188,7 +200,8 @@ class Greeter(demo_greeter_grpc.GreeterServicer): Generated clients use the standard `grpcio` streaming call shapes: ```python -with grpc.insecure_channel("localhost:50051") as channel: +credentials = grpc.ssl_channel_credentials() +with grpc.secure_channel("api.example.com:443", credentials) as channel: stub = demo_greeter_grpc.GreeterStub(channel) for reply in stub.lots_of_replies( diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/go/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/go/grpc-support.md index 16a4422639a..d8cdd580bbf 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/go/grpc-support.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/go/grpc-support.md @@ -68,9 +68,9 @@ foryc service.fdl --go_out=./generated/go --grpc 输出包含: -| 文件 | 用途 | -| ------------------------------ | ------------------------------------ | -| `greeter/demo_greeter.go` | Fory model 类型和注册辅助逻辑 | +| 文件 | 用途 | +| ------------------------------ | ----------------------------------------- | +| `greeter/demo_greeter.go` | Fory model 类型和注册辅助逻辑 | | `greeter/demo_greeter_grpc.go` | grpc-go client、server interface 和 codec | 生成的 Go 方法使用导出的 PascalCase 名称,例如 `SayHello`。底层 gRPC method path 保留 @@ -175,10 +175,10 @@ Fory service 支持 unary、server-streaming、client-streaming 和 bidirectiona - Bidirectional streaming 使用生成的 stream client/server interface。 - 每个 message frame 都使用生成 codec。 -## 运维语义 +## Service 行为 生成的 service companion 只提供 Fory 序列化。deadline、取消、TLS、credential、unary/stream -interceptor、status code、metadata、名称解析、负载均衡、连接生命周期和 backoff 都保持标准 grpc-go 行为。 +interceptor、status code、metadata、名称解析、负载均衡、连接生命周期和 backoff 等 Service 行为都遵循标准 grpc-go。 ## 故障排查 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/java/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/java/grpc-support.md index 77ac4ff649c..23ede2278f2 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/java/grpc-support.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/java/grpc-support.md @@ -190,12 +190,12 @@ service Greeter { 生成 Java service 方法遵循 grpc-java 约定: -| IDL shape | Server 方法形态 | Client 方法形态 | -| ----------------------------------------- | ------------------------------------------------------- | ---------------------------------- | -| `rpc A (Req) returns (Res)` | `void a(Req request, StreamObserver responses)` | blocking、async、future unary stub | -| `rpc A (Req) returns (stream Res)` | `void a(Req request, StreamObserver responses)` | blocking iterator 或 async observer | -| `rpc A (stream Req) returns (Res)` | `StreamObserver a(StreamObserver responses)` | async request observer | -| `rpc A (stream Req) returns (stream Res)` | `StreamObserver a(StreamObserver responses)` | async request observer | +| IDL shape | Server 方法形态 | Client 方法形态 | +| ----------------------------------------- | ------------------------------------------------------ | ----------------------------------- | +| `rpc A (Req) returns (Res)` | `void a(Req request, StreamObserver responses)` | blocking、async、future unary stub | +| `rpc A (Req) returns (stream Res)` | `void a(Req request, StreamObserver responses)` | blocking iterator 或 async observer | +| `rpc A (stream Req) returns (Res)` | `StreamObserver a(StreamObserver responses)` | async request observer | +| `rpc A (stream Req) returns (stream Res)` | `StreamObserver a(StreamObserver responses)` | async request observer | Server 可以直接实现生成的 streaming 方法: @@ -354,9 +354,9 @@ final class StreamingClient { 生成 descriptor 会保留 IDL 中的 service 和 method 名称作为 gRPC path。 -## 运维语义 +## Service 行为 -生成的 service code 只替换 request/response 序列化。常规 gRPC 运维能力仍由 grpc-java 提供: +生成的 service code 只替换 request/response 序列化。常规 gRPC service 行为仍由 grpc-java 提供: - Deadline 和取消 - TLS 和认证 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/javascript/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/javascript/grpc-support.md index 261f310900c..f0cde1f61cc 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/javascript/grpc-support.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/javascript/grpc-support.md @@ -88,11 +88,11 @@ foryc service.fdl --javascript_out=./generated/javascript --grpc --grpc-web 输出包含: -| 文件 | 用途 | -| --------------------- | ------------------------------------- | +| 文件 | 用途 | +| --------------------- | --------------------------------------- | | `service.ts` | interface、enum、union 和 schema helper | -| `service_grpc.ts` | Node.js `@grpc/grpc-js` server/client | -| `service_grpc_web.ts` | 浏览器 `grpc-web` client | +| `service_grpc.ts` | Node.js `@grpc/grpc-js` server/client | +| `service_grpc_web.ts` | 浏览器 `grpc-web` client | ## 实现 Node.js Server @@ -278,9 +278,9 @@ stream.on("end", () => { }); ``` -## 运维语义 +## Service 行为 -生成的 service code 只替换 request/response 序列化。常规 gRPC 运维能力仍由 transport package +生成的 service code 只替换 request/response 序列化。常规 gRPC service 行为仍由 transport package 提供: - TLS 和 credential diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/kotlin/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/kotlin/grpc-support.md index d2e81792d31..89cc9893f2e 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/kotlin/grpc-support.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/kotlin/grpc-support.md @@ -151,12 +151,12 @@ service Greeter { Streaming RPC 使用 `kotlinx.coroutines.flow.Flow`。 -| IDL shape | Server 方法 | Client 方法 | -| ----------------------------------------- | ---------------------------------------- | ---------------------------------------- | -| `rpc A (Req) returns (Res)` | `suspend fun a(request: Req): Res` | `suspend fun a(request: Req): Res` | -| `rpc A (Req) returns (stream Res)` | `fun a(request: Req): Flow` | `fun a(request: Req): Flow` | +| IDL shape | Server 方法 | Client 方法 | +| ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | +| `rpc A (Req) returns (Res)` | `suspend fun a(request: Req): Res` | `suspend fun a(request: Req): Res` | +| `rpc A (Req) returns (stream Res)` | `fun a(request: Req): Flow` | `fun a(request: Req): Flow` | | `rpc A (stream Req) returns (Res)` | `suspend fun a(requests: Flow): Res` | `suspend fun a(requests: Flow): Res` | -| `rpc A (stream Req) returns (stream Res)` | `fun a(requests: Flow): Flow` | `fun a(requests: Flow): Flow` | +| `rpc A (stream Req) returns (stream Res)` | `fun a(requests: Flow): Flow` | `fun a(requests: Flow): Flow` | 生成 method path 保留 schema 中的 service 和 method 名称,例如 `/demo.greeter.Greeter/SayHello`。 @@ -219,9 +219,9 @@ stub.chat( } ``` -## 运维语义 +## Service 行为 -生成的 service code 只替换 request/response 序列化。常规 gRPC 运维能力仍由 grpc-java 和 +生成的 service code 只替换 request/response 序列化。常规 gRPC service 行为仍由 grpc-java 和 grpc-kotlin 提供: - Deadline 和取消 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/python/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/python/grpc-support.md index a144babf3f5..0ee9beb11ed 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/python/grpc-support.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/python/grpc-support.md @@ -27,9 +27,10 @@ Fory 可以为包含 service 定义的 schema 生成 Python gRPC companion modul message bytes,请使用标准 protobuf gRPC 代码生成。 当前生成的 Python companion 面向同步 `grpcio` API。请使用普通 `def` servicer 方法、 -`grpc.server(...)`、`grpc.insecure_channel(...)`,并用 Python iterator/generator 处理 -streaming RPC。Compiler 不会生成 `grpc.aio` stub 或 service base,因此不要把生成 servicer -方法实现成 `async def`,除非你在生成 companion 外自行封装 adapter。 +`grpc.server(...)`、标准 `grpc.Channel` 实例,并用 Python iterator/generator 处理 streaming RPC。 +生成的 stub 可以接收应用自行配置的任意 channel。Compiler 不会生成 `grpc.aio` stub 或 service +base,因此不要把生成 servicer 方法实现成 `async def`,除非你在生成 companion 外自行封装 adapter。 +基于 `grpc.aio` 的 Python gRPC async 支持将在下一个 Fory 版本提供。 ## 添加依赖 @@ -66,9 +67,9 @@ foryc service.fdl --python_out=./generated/python --grpc 该 schema 会生成: -| 文件 | 用途 | -| ---------------------- | --------------------------------- | -| `demo_greeter.py` | Fory dataclass 和注册辅助逻辑 | +| 文件 | 用途 | +| ---------------------- | --------------------------------------- | +| `demo_greeter.py` | Fory dataclass 和注册辅助逻辑 | | `demo_greeter_grpc.py` | `grpcio` stub、servicer base 和注册函数 | Module 名称来自 Fory package,点号会替换成下划线;没有 package 的 schema 使用 `generated.py` 和 @@ -104,6 +105,8 @@ if __name__ == "__main__": ## 创建 Client +使用生成的 stub 和普通 `grpcio` channel。生产 client 通常传入配置了 TLS/认证的 channel: + ```python import grpc @@ -112,7 +115,8 @@ import demo_greeter_grpc def main(): - with grpc.insecure_channel("localhost:50051") as channel: + credentials = grpc.ssl_channel_credentials() + with grpc.secure_channel("api.example.com:443", credentials) as channel: stub = demo_greeter_grpc.GreeterStub(channel) reply = stub.say_hello(demo_greeter.HelloRequest(name="Fory")) print(reply.reply) @@ -122,6 +126,15 @@ if __name__ == "__main__": main() ``` +本地测试和开发可以显式使用 insecure channel: + +```python +# 仅用于本地测试和开发。 +# 生产环境请使用配置了 TLS/认证的 grpc.Channel。 +with grpc.insecure_channel("localhost:50051") as channel: + stub = demo_greeter_grpc.GreeterStub(channel) +``` + Channel、credential、deadline、metadata、interceptor、retry 和 server lifecycle 都保持 `grpcio` 行为。 @@ -140,12 +153,12 @@ service Greeter { 生成 Python companion 遵循 `grpcio` 的 iterator/generator 约定: -| IDL shape | Servicer 方法形态 | Stub 方法形态 | -| ----------------------------------------- | ----------------------------------------- | ------------------------- | -| `rpc A (Req) returns (Res)` | 返回一个 response 对象 | 返回一个 response 对象 | -| `rpc A (Req) returns (stream Res)` | yield 多个 response 对象 | 返回 response iterator | -| `rpc A (stream Req) returns (Res)` | 消费 request iterator 并返回一个 response | 接收 request iterator | -| `rpc A (stream Req) returns (stream Res)` | 消费 request iterator 并 yield response | 接收并返回 iterator | +| IDL shape | Servicer 方法形态 | Stub 方法形态 | +| ----------------------------------------- | ----------------------------------------- | ---------------------- | +| `rpc A (Req) returns (Res)` | 返回一个 response 对象 | 返回一个 response 对象 | +| `rpc A (Req) returns (stream Res)` | yield 多个 response 对象 | 返回 response iterator | +| `rpc A (stream Req) returns (Res)` | 消费 request iterator 并返回一个 response | 接收 request iterator | +| `rpc A (stream Req) returns (stream Res)` | 消费 request iterator 并 yield response | 接收并返回 iterator | Servicer 方法使用 snake_case 名称;生成 descriptor 会保留 IDL 中的 service 和 method 名称作为 gRPC path。每个 message frame 都通过 Fory serializer/deserializer 编码。 @@ -170,7 +183,8 @@ class Greeter(demo_greeter_grpc.GreeterServicer): 生成的 client 使用标准 `grpcio` streaming 调用形态: ```python -with grpc.insecure_channel("localhost:50051") as channel: +credentials = grpc.ssl_channel_credentials() +with grpc.secure_channel("api.example.com:443", credentials) as channel: stub = demo_greeter_grpc.GreeterStub(channel) for reply in stub.lots_of_replies( @@ -193,9 +207,9 @@ with grpc.insecure_channel("localhost:50051") as channel: print(reply.reply) ``` -## 运维语义 +## Service 行为 -生成的 service companion 只提供 Fory serialization callback。运维行为仍遵循标准 `grpcio`: +生成的 service companion 只提供 Fory serialization callback。Service 行为仍遵循标准 `grpcio`: - Deadline 和取消 - TLS 和认证 credential diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/grpc-support.md index b6c603b61f8..de234fbd4ab 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/grpc-support.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/grpc-support.md @@ -71,10 +71,10 @@ foryc service.fdl --rust_out=./generated/rust --grpc 该 schema 会生成: -| 文件 | 用途 | -| ------------------------------ | ----------------------------------- | -| `demo_greeter.rs` | Fory model 类型和注册辅助逻辑 | -| `demo_greeter_service.rs` | 异步 service trait 与 gRPC path 常量 | +| 文件 | 用途 | +| ------------------------------ | ------------------------------------------ | +| `demo_greeter.rs` | Fory model 类型和注册辅助逻辑 | +| `demo_greeter_service.rs` | 异步 service trait 与 gRPC path 常量 | | `demo_greeter_service_grpc.rs` | tonic client、server wrapper 和 Fory codec | 将生成文件加入 crate root: @@ -283,7 +283,7 @@ while let Some(reply) = chat.message().await? { Rust gRPC payload 必须满足 `Send + 'static`,这样 tonic 才能在线程间移动 request/response。 如果 request 或 response schema 使用非线程安全的引用元信息,Rust gRPC 生成会拒绝该 service。 -## 运维语义 +## Service 行为 生成的 service companion 只提供 Fory 序列化和 tonic binding。deadline、取消、TLS、认证、 Tower middleware、interceptor、status code、metadata、channel/server 生命周期和 backpressure diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/go/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/go/grpc-support.md index 16a4422639a..d8cdd580bbf 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/go/grpc-support.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/go/grpc-support.md @@ -68,9 +68,9 @@ foryc service.fdl --go_out=./generated/go --grpc 输出包含: -| 文件 | 用途 | -| ------------------------------ | ------------------------------------ | -| `greeter/demo_greeter.go` | Fory model 类型和注册辅助逻辑 | +| 文件 | 用途 | +| ------------------------------ | ----------------------------------------- | +| `greeter/demo_greeter.go` | Fory model 类型和注册辅助逻辑 | | `greeter/demo_greeter_grpc.go` | grpc-go client、server interface 和 codec | 生成的 Go 方法使用导出的 PascalCase 名称,例如 `SayHello`。底层 gRPC method path 保留 @@ -175,10 +175,10 @@ Fory service 支持 unary、server-streaming、client-streaming 和 bidirectiona - Bidirectional streaming 使用生成的 stream client/server interface。 - 每个 message frame 都使用生成 codec。 -## 运维语义 +## Service 行为 生成的 service companion 只提供 Fory 序列化。deadline、取消、TLS、credential、unary/stream -interceptor、status code、metadata、名称解析、负载均衡、连接生命周期和 backoff 都保持标准 grpc-go 行为。 +interceptor、status code、metadata、名称解析、负载均衡、连接生命周期和 backoff 等 Service 行为都遵循标准 grpc-go。 ## 故障排查 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/java/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/java/grpc-support.md index 77ac4ff649c..23ede2278f2 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/java/grpc-support.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/java/grpc-support.md @@ -190,12 +190,12 @@ service Greeter { 生成 Java service 方法遵循 grpc-java 约定: -| IDL shape | Server 方法形态 | Client 方法形态 | -| ----------------------------------------- | ------------------------------------------------------- | ---------------------------------- | -| `rpc A (Req) returns (Res)` | `void a(Req request, StreamObserver responses)` | blocking、async、future unary stub | -| `rpc A (Req) returns (stream Res)` | `void a(Req request, StreamObserver responses)` | blocking iterator 或 async observer | -| `rpc A (stream Req) returns (Res)` | `StreamObserver a(StreamObserver responses)` | async request observer | -| `rpc A (stream Req) returns (stream Res)` | `StreamObserver a(StreamObserver responses)` | async request observer | +| IDL shape | Server 方法形态 | Client 方法形态 | +| ----------------------------------------- | ------------------------------------------------------ | ----------------------------------- | +| `rpc A (Req) returns (Res)` | `void a(Req request, StreamObserver responses)` | blocking、async、future unary stub | +| `rpc A (Req) returns (stream Res)` | `void a(Req request, StreamObserver responses)` | blocking iterator 或 async observer | +| `rpc A (stream Req) returns (Res)` | `StreamObserver a(StreamObserver responses)` | async request observer | +| `rpc A (stream Req) returns (stream Res)` | `StreamObserver a(StreamObserver responses)` | async request observer | Server 可以直接实现生成的 streaming 方法: @@ -354,9 +354,9 @@ final class StreamingClient { 生成 descriptor 会保留 IDL 中的 service 和 method 名称作为 gRPC path。 -## 运维语义 +## Service 行为 -生成的 service code 只替换 request/response 序列化。常规 gRPC 运维能力仍由 grpc-java 提供: +生成的 service code 只替换 request/response 序列化。常规 gRPC service 行为仍由 grpc-java 提供: - Deadline 和取消 - TLS 和认证 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/javascript/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/javascript/grpc-support.md index 261f310900c..f0cde1f61cc 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/javascript/grpc-support.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/javascript/grpc-support.md @@ -88,11 +88,11 @@ foryc service.fdl --javascript_out=./generated/javascript --grpc --grpc-web 输出包含: -| 文件 | 用途 | -| --------------------- | ------------------------------------- | +| 文件 | 用途 | +| --------------------- | --------------------------------------- | | `service.ts` | interface、enum、union 和 schema helper | -| `service_grpc.ts` | Node.js `@grpc/grpc-js` server/client | -| `service_grpc_web.ts` | 浏览器 `grpc-web` client | +| `service_grpc.ts` | Node.js `@grpc/grpc-js` server/client | +| `service_grpc_web.ts` | 浏览器 `grpc-web` client | ## 实现 Node.js Server @@ -278,9 +278,9 @@ stream.on("end", () => { }); ``` -## 运维语义 +## Service 行为 -生成的 service code 只替换 request/response 序列化。常规 gRPC 运维能力仍由 transport package +生成的 service code 只替换 request/response 序列化。常规 gRPC service 行为仍由 transport package 提供: - TLS 和 credential diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/kotlin/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/kotlin/grpc-support.md index d2e81792d31..89cc9893f2e 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/kotlin/grpc-support.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/kotlin/grpc-support.md @@ -151,12 +151,12 @@ service Greeter { Streaming RPC 使用 `kotlinx.coroutines.flow.Flow`。 -| IDL shape | Server 方法 | Client 方法 | -| ----------------------------------------- | ---------------------------------------- | ---------------------------------------- | -| `rpc A (Req) returns (Res)` | `suspend fun a(request: Req): Res` | `suspend fun a(request: Req): Res` | -| `rpc A (Req) returns (stream Res)` | `fun a(request: Req): Flow` | `fun a(request: Req): Flow` | +| IDL shape | Server 方法 | Client 方法 | +| ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | +| `rpc A (Req) returns (Res)` | `suspend fun a(request: Req): Res` | `suspend fun a(request: Req): Res` | +| `rpc A (Req) returns (stream Res)` | `fun a(request: Req): Flow` | `fun a(request: Req): Flow` | | `rpc A (stream Req) returns (Res)` | `suspend fun a(requests: Flow): Res` | `suspend fun a(requests: Flow): Res` | -| `rpc A (stream Req) returns (stream Res)` | `fun a(requests: Flow): Flow` | `fun a(requests: Flow): Flow` | +| `rpc A (stream Req) returns (stream Res)` | `fun a(requests: Flow): Flow` | `fun a(requests: Flow): Flow` | 生成 method path 保留 schema 中的 service 和 method 名称,例如 `/demo.greeter.Greeter/SayHello`。 @@ -219,9 +219,9 @@ stub.chat( } ``` -## 运维语义 +## Service 行为 -生成的 service code 只替换 request/response 序列化。常规 gRPC 运维能力仍由 grpc-java 和 +生成的 service code 只替换 request/response 序列化。常规 gRPC service 行为仍由 grpc-java 和 grpc-kotlin 提供: - Deadline 和取消 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/python/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/python/grpc-support.md index a144babf3f5..0ee9beb11ed 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/python/grpc-support.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/python/grpc-support.md @@ -27,9 +27,10 @@ Fory 可以为包含 service 定义的 schema 生成 Python gRPC companion modul message bytes,请使用标准 protobuf gRPC 代码生成。 当前生成的 Python companion 面向同步 `grpcio` API。请使用普通 `def` servicer 方法、 -`grpc.server(...)`、`grpc.insecure_channel(...)`,并用 Python iterator/generator 处理 -streaming RPC。Compiler 不会生成 `grpc.aio` stub 或 service base,因此不要把生成 servicer -方法实现成 `async def`,除非你在生成 companion 外自行封装 adapter。 +`grpc.server(...)`、标准 `grpc.Channel` 实例,并用 Python iterator/generator 处理 streaming RPC。 +生成的 stub 可以接收应用自行配置的任意 channel。Compiler 不会生成 `grpc.aio` stub 或 service +base,因此不要把生成 servicer 方法实现成 `async def`,除非你在生成 companion 外自行封装 adapter。 +基于 `grpc.aio` 的 Python gRPC async 支持将在下一个 Fory 版本提供。 ## 添加依赖 @@ -66,9 +67,9 @@ foryc service.fdl --python_out=./generated/python --grpc 该 schema 会生成: -| 文件 | 用途 | -| ---------------------- | --------------------------------- | -| `demo_greeter.py` | Fory dataclass 和注册辅助逻辑 | +| 文件 | 用途 | +| ---------------------- | --------------------------------------- | +| `demo_greeter.py` | Fory dataclass 和注册辅助逻辑 | | `demo_greeter_grpc.py` | `grpcio` stub、servicer base 和注册函数 | Module 名称来自 Fory package,点号会替换成下划线;没有 package 的 schema 使用 `generated.py` 和 @@ -104,6 +105,8 @@ if __name__ == "__main__": ## 创建 Client +使用生成的 stub 和普通 `grpcio` channel。生产 client 通常传入配置了 TLS/认证的 channel: + ```python import grpc @@ -112,7 +115,8 @@ import demo_greeter_grpc def main(): - with grpc.insecure_channel("localhost:50051") as channel: + credentials = grpc.ssl_channel_credentials() + with grpc.secure_channel("api.example.com:443", credentials) as channel: stub = demo_greeter_grpc.GreeterStub(channel) reply = stub.say_hello(demo_greeter.HelloRequest(name="Fory")) print(reply.reply) @@ -122,6 +126,15 @@ if __name__ == "__main__": main() ``` +本地测试和开发可以显式使用 insecure channel: + +```python +# 仅用于本地测试和开发。 +# 生产环境请使用配置了 TLS/认证的 grpc.Channel。 +with grpc.insecure_channel("localhost:50051") as channel: + stub = demo_greeter_grpc.GreeterStub(channel) +``` + Channel、credential、deadline、metadata、interceptor、retry 和 server lifecycle 都保持 `grpcio` 行为。 @@ -140,12 +153,12 @@ service Greeter { 生成 Python companion 遵循 `grpcio` 的 iterator/generator 约定: -| IDL shape | Servicer 方法形态 | Stub 方法形态 | -| ----------------------------------------- | ----------------------------------------- | ------------------------- | -| `rpc A (Req) returns (Res)` | 返回一个 response 对象 | 返回一个 response 对象 | -| `rpc A (Req) returns (stream Res)` | yield 多个 response 对象 | 返回 response iterator | -| `rpc A (stream Req) returns (Res)` | 消费 request iterator 并返回一个 response | 接收 request iterator | -| `rpc A (stream Req) returns (stream Res)` | 消费 request iterator 并 yield response | 接收并返回 iterator | +| IDL shape | Servicer 方法形态 | Stub 方法形态 | +| ----------------------------------------- | ----------------------------------------- | ---------------------- | +| `rpc A (Req) returns (Res)` | 返回一个 response 对象 | 返回一个 response 对象 | +| `rpc A (Req) returns (stream Res)` | yield 多个 response 对象 | 返回 response iterator | +| `rpc A (stream Req) returns (Res)` | 消费 request iterator 并返回一个 response | 接收 request iterator | +| `rpc A (stream Req) returns (stream Res)` | 消费 request iterator 并 yield response | 接收并返回 iterator | Servicer 方法使用 snake_case 名称;生成 descriptor 会保留 IDL 中的 service 和 method 名称作为 gRPC path。每个 message frame 都通过 Fory serializer/deserializer 编码。 @@ -170,7 +183,8 @@ class Greeter(demo_greeter_grpc.GreeterServicer): 生成的 client 使用标准 `grpcio` streaming 调用形态: ```python -with grpc.insecure_channel("localhost:50051") as channel: +credentials = grpc.ssl_channel_credentials() +with grpc.secure_channel("api.example.com:443", credentials) as channel: stub = demo_greeter_grpc.GreeterStub(channel) for reply in stub.lots_of_replies( @@ -193,9 +207,9 @@ with grpc.insecure_channel("localhost:50051") as channel: print(reply.reply) ``` -## 运维语义 +## Service 行为 -生成的 service companion 只提供 Fory serialization callback。运维行为仍遵循标准 `grpcio`: +生成的 service companion 只提供 Fory serialization callback。Service 行为仍遵循标准 `grpcio`: - Deadline 和取消 - TLS 和认证 credential diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/rust/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/rust/grpc-support.md index b6c603b61f8..de234fbd4ab 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/rust/grpc-support.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-1.2.0/guide/rust/grpc-support.md @@ -71,10 +71,10 @@ foryc service.fdl --rust_out=./generated/rust --grpc 该 schema 会生成: -| 文件 | 用途 | -| ------------------------------ | ----------------------------------- | -| `demo_greeter.rs` | Fory model 类型和注册辅助逻辑 | -| `demo_greeter_service.rs` | 异步 service trait 与 gRPC path 常量 | +| 文件 | 用途 | +| ------------------------------ | ------------------------------------------ | +| `demo_greeter.rs` | Fory model 类型和注册辅助逻辑 | +| `demo_greeter_service.rs` | 异步 service trait 与 gRPC path 常量 | | `demo_greeter_service_grpc.rs` | tonic client、server wrapper 和 Fory codec | 将生成文件加入 crate root: @@ -283,7 +283,7 @@ while let Some(reply) = chat.message().await? { Rust gRPC payload 必须满足 `Send + 'static`,这样 tonic 才能在线程间移动 request/response。 如果 request 或 response schema 使用非线程安全的引用元信息,Rust gRPC 生成会拒绝该 service。 -## 运维语义 +## Service 行为 生成的 service companion 只提供 Fory 序列化和 tonic binding。deadline、取消、TLS、认证、 Tower middleware、interceptor、status code、metadata、channel/server 生命周期和 backpressure diff --git a/versioned_docs/version-1.2.0/guide/python/grpc-support.md b/versioned_docs/version-1.2.0/guide/python/grpc-support.md index 946602be308..cdcff922430 100644 --- a/versioned_docs/version-1.2.0/guide/python/grpc-support.md +++ b/versioned_docs/version-1.2.0/guide/python/grpc-support.md @@ -29,11 +29,13 @@ encoding. Use standard protobuf gRPC code generation when clients or tools must consume protobuf message bytes directly. Generated Python companions currently target the synchronous `grpcio` API. Use -regular `def` servicer methods, `grpc.server(...)`, `grpc.insecure_channel(...)`, -and Python iterators or generators for streaming RPCs. The compiler does not +regular `def` servicer methods, `grpc.server(...)`, standard `grpc.Channel` +instances, and Python iterators or generators for streaming RPCs. The generated +stub accepts any channel configured by your application. The compiler does not generate `grpc.aio` stubs or service bases, so do not implement generated servicer methods as `async def` unless you add a custom adapter outside the -generated companion. +generated companion. Python gRPC async support based on `grpc.aio` will be +available in the next Fory release. ## Install Dependencies @@ -119,7 +121,8 @@ so service implementations do not perform manual Fory registration. ## Create a Client -Use the generated stub with a normal `grpcio` channel: +Use the generated stub with a normal `grpcio` channel. Production clients +usually pass a TLS/auth-configured channel: ```python import grpc @@ -129,7 +132,8 @@ import demo_greeter_grpc def main(): - with grpc.insecure_channel("localhost:50051") as channel: + credentials = grpc.ssl_channel_credentials() + with grpc.secure_channel("api.example.com:443", credentials) as channel: stub = demo_greeter_grpc.GreeterStub(channel) reply = stub.say_hello(demo_greeter.HelloRequest(name="Fory")) print(reply.reply) @@ -139,6 +143,14 @@ if __name__ == "__main__": main() ``` +For local tests and development, an insecure channel can be used explicitly: + +```python +# Test-only channel. Use a TLS/auth-configured grpc.Channel in production. +with grpc.insecure_channel("localhost:50051") as channel: + stub = demo_greeter_grpc.GreeterStub(channel) +``` + `grpcio` still owns channel options, credentials, deadlines, metadata, retries, and interceptors. @@ -158,12 +170,12 @@ service Greeter { Generated Python code follows `grpcio` conventions: -| IDL shape | Servicer method shape | Stub method shape | -| ----------------------------------------- | ------------------------------------------- | ---------------------------------- | -| `rpc A (Req) returns (Res)` | returns one response object | returns one response object | -| `rpc A (Req) returns (stream Res)` | yields response objects | returns an iterator of responses | -| `rpc A (stream Req) returns (Res)` | consumes an iterator and returns a response | accepts an iterator of requests | -| `rpc A (stream Req) returns (stream Res)` | consumes and yields iterators | accepts and returns iterators | +| IDL shape | Servicer method shape | Stub method shape | +| ----------------------------------------- | ------------------------------------------- | -------------------------------- | +| `rpc A (Req) returns (Res)` | returns one response object | returns one response object | +| `rpc A (Req) returns (stream Res)` | yields response objects | returns an iterator of responses | +| `rpc A (stream Req) returns (Res)` | consumes an iterator and returns a response | accepts an iterator of requests | +| `rpc A (stream Req) returns (stream Res)` | consumes and yields iterators | accepts and returns iterators | Servicer methods use snake_case names, while generated descriptors preserve the exact IDL service and method names for the gRPC path. @@ -188,7 +200,8 @@ class Greeter(demo_greeter_grpc.GreeterServicer): Generated clients use the standard `grpcio` streaming call shapes: ```python -with grpc.insecure_channel("localhost:50051") as channel: +credentials = grpc.ssl_channel_credentials() +with grpc.secure_channel("api.example.com:443", credentials) as channel: stub = demo_greeter_grpc.GreeterStub(channel) for reply in stub.lots_of_replies(