This is an automated email from the ASF dual-hosted git repository. chaokunyang pushed a commit to branch release_fory_1.2.0 in repository https://gitbox.apache.org/repos/asf/fory-site.git
commit 00dfe8601e21d4291cd059fde7da48ca2df4ecc6 Author: 慕白 <[email protected]> AuthorDate: Tue Jun 16 22:03:40 2026 +0800 Add zh-CN updates for Fory 1.2.0 --- .../2026-06-16-fory_1_2_0_release.md | 338 +++++++++++++++++++++ .../current/compiler/compiler-guide.md | 4 +- .../current/guide/cpp/index.md | 8 +- .../current/guide/csharp/grpc-support.md | 130 ++++++++ .../current/guide/csharp/index.md | 2 +- .../current/guide/dart/index.md | 2 +- .../current/guide/go/grpc-support.md | 195 ++++++++++++ .../current/guide/java/compression.md | 2 +- .../current/guide/java/grpc-support.md | 172 +++++++++++ .../current/guide/javascript/grpc-support.md | 198 ++++++++++++ .../current/guide/kotlin/grpc-support.md | 160 ++++++++++ .../current/guide/kotlin/index.md | 4 +- .../current/guide/python/grpc-support.md | 133 ++++++++ .../current/guide/rust/basic-serialization.md | 2 +- .../current/guide/rust/grpc-support.md | 199 ++++++++++++ .../current/guide/rust/index.md | 2 +- .../current/guide/scala/grpc-support.md | 169 +++++++++++ .../current/guide/scala/index.md | 2 +- .../current/guide/xlang/getting-started.md | 16 +- .../current/start/install.md | 32 +- .../download/index.md | 10 +- 21 files changed, 1737 insertions(+), 43 deletions(-) diff --git a/i18n/zh-CN/docusaurus-plugin-content-blog/2026-06-16-fory_1_2_0_release.md b/i18n/zh-CN/docusaurus-plugin-content-blog/2026-06-16-fory_1_2_0_release.md new file mode 100644 index 0000000000..e2dca415d5 --- /dev/null +++ b/i18n/zh-CN/docusaurus-plugin-content-blog/2026-06-16-fory_1_2_0_release.md @@ -0,0 +1,338 @@ +--- +slug: fory_1_2_0_release +title: Fory v1.2.0 发布 +authors: [chaokunyang] +tags: [fory, java, kotlin, scala, android, python, rust, c++, go, c#, swift, dart, compiler] +--- + +Apache Fory 团队很高兴宣布 1.2.0 版本正式发布。本版本包含来自 9 位贡献者的 [38 个 PR](https://github.com/apache/fory/compare/v1.1.0...v1.2.0),并继续改进各支持语言的跨语言运行时。请访问 [Install 页面](https://fory.apache.org/docs/start/install) 获取各平台安装方式。 + +## 发布亮点 + +* 扩展 Go、Rust、Kotlin、Scala、C# 和 JavaScript 的 gRPC 生成支持,其中 JavaScript 同时支持 Node.js 和浏览器 gRPC-Web。 +* 改进跨语言兼容性,细化 register-by-name API,支持兼容模式下的标量字段读取转换,并让 native serialization 默认启用兼容模式。 +* 强化 Java 平台支持,增加 Java 9/16 `module-info` 生成,并为 JDK 25 移除 `sun.misc.Unsafe` 使用。 +* 通过更多读取检查、deflater 泄漏修复以及更安全的 serializer/type-info 错误处理提升运行时安全性和鲁棒性。 +* 优化兼容模式和 row-format 性能,包括更快的兼容读取、紧凑 row layout 缓存以及内联 custom-codec dispatch。 +* 提升 Rust、C++ 和 service 生成质量,包括更好的标识符转义、名称冲突处理、嵌套容器引用处理和 map 代码生成。 + +## Java 25+ 不再依赖 `sun.misc.Unsafe` + +JDK 25 继续推动平台远离 `sun.misc.Unsafe`。Fory 1.2.0 为核心运行时增加了 Java 25 multi-release 实现,使应用在 JDK 25+ 上运行时,不再从 Fory 的有效 class graph 中解析 `sun.misc.Unsafe`。 + +该实现仍保留 JDK 8-24 上的快速路径;但在 JDK 25+ 上会从 jar 的 versioned 区域加载替换类。这些替换类将字段访问和 memory-buffer 原语迁移到 JVM 支持的机制,例如 `VarHandle`、`MethodHandle`、数组和 `ByteBuffer`。绕过构造器的对象分配也会被显式处理:在 JDK 25+ 上,过去依赖 Unsafe allocation 的类应提供可访问的无参构造器、使用 record 构造,或注册自定义 serializer。 + +这对 Java 用户是一个重要兼容性里程碑:应用运行在 Java 25 及之后版本时,Fory runtime 不再依赖已被终止弃用的 Unsafe API 路径。 + +## 兼容标量字段读取 + +兼容模式已经允许读写双方添加、删除和重排字段。Fory 1.2.0 将这个模型扩展到部分标量类型变更:当匹配到的顶层字段在 boolean、string、numeric 和 decimal 类型之间变化时,只要转换是无损的,reader 就可以完成反序列化。 + +例如,`"123"` 可以读取为整数字段,`1` 或 `0` 可以读取为 boolean 字段,boolean 可以读取为 `1`/`0`,数字或 decimal 可以读取为规范字符串;数字 widening 或 narrowing 只有在不丢失范围或精度时才会成功。无效字符串、越界值、有损 float/integer 转换以及开启引用跟踪的标量类型变更会在反序列化时报错。该转换只应用于匹配到的兼容字段,不应用于根值或集合元素。 + +下面示例展示 Rust、Python、Java 和 C++。兼容标量字段转换也支持 Fory 的所有兼容模式运行时:Java、Python、Rust、C++、Go、C#、Swift、Dart、JavaScript/TypeScript、Kotlin 和 Scala。 + +Java 和 Python 的 xlang 与 native serialization 默认都启用兼容模式,也可以显式配置: + +```java +Fory fory = Fory.builder() + .withXlang(true) + .withCompatible(true) + .build(); +``` + +```python +import pyfory + +fory = pyfory.Fory(xlang=True, compatible=True) +native_fory = pyfory.Fory(xlang=False, compatible=True) +``` + +Rust 示例: + +```rust +use fory::{Fory, ForyStruct}; + +#[derive(ForyStruct)] +struct MetricV1 { + value: i64, +} + +#[derive(ForyStruct)] +struct MetricV2 { + value: String, +} + +let mut writer = Fory::builder().xlang(true).compatible(true).build(); +writer.register_by_name::<MetricV1>("example.Metric")?; + +let mut reader = Fory::builder().xlang(true).compatible(true).build(); +reader.register_by_name::<MetricV2>("example.Metric")?; + +let bytes = writer.serialize(&MetricV1 { value: 42 })?; +let value: MetricV2 = reader.deserialize(&bytes)?; +assert_eq!(value.value, "42"); +``` + +Python 示例: + +```python +from dataclasses import dataclass +import pyfory + +@dataclass +class MetricV1: + value: pyfory.Int64 + +@dataclass +class MetricV2: + value: str + +writer = pyfory.Fory(xlang=True, compatible=True) +writer.register(MetricV1, name="example.Metric") + +reader = pyfory.Fory(xlang=True, compatible=True) +reader.register(MetricV2, name="example.Metric") + +data = writer.dumps(MetricV1(42)) +assert reader.loads(data).value == "42" +``` + +Java 示例: + +```java +public class MetricV1 { + public long value; +} + +public class MetricV2 { + public String value; +} + +Fory writer = Fory.builder().withXlang(true).withCompatible(true).build(); +writer.register(MetricV1.class, "example", "Metric"); + +Fory reader = Fory.builder().withXlang(true).withCompatible(true).build(); +reader.register(MetricV2.class, "example", "Metric"); + +MetricV1 source = new MetricV1(); +source.value = 42L; +byte[] bytes = writer.serialize(source); +MetricV2 value = reader.deserialize(bytes, MetricV2.class); +assert value.value.equals("42"); +``` + +C++ 示例: + +```cpp +#include <cassert> +#include <string> +#include "fory/serialization/fory.h" + +using namespace fory::serialization; + +struct MetricV1 { + int64_t value; +}; +FORY_STRUCT(MetricV1, value); + +struct MetricV2 { + std::string value; +}; +FORY_STRUCT(MetricV2, value); + +auto writer = Fory::builder().xlang(true).compatible(true).build(); +auto reader = Fory::builder().xlang(true).compatible(true).build(); + +writer.register_struct<MetricV1>("example", "Metric"); +reader.register_struct<MetricV2>("example", "Metric"); + +auto bytes = writer.serialize(MetricV1{42}).value(); +auto value = reader.deserialize<MetricV2>(bytes).value(); +assert(value.value == "42"); +``` + +反方向同样适用,例如将 `String` 字段值 `"42"` 读取为 `int64`,前提是字符串满足 Fory 严格的有限十进制语法,并且目标范围可以精确表示该值。 + +## 生成 gRPC 支持 + +Fory 1.2.0 扩展了 compiler 生成的 gRPC service companion。生成的 service 使用标准 gRPC transport、channel、deadline、metadata、interceptor、status code 和 streaming shape,但 request/response 对象使用 Fory 编码,而不是 protobuf message bytes。当 RPC 两端都由同一份 Fory IDL、protobuf IDL 或 FlatBuffers IDL 生成,并且你希望使用 gRPC 运维语义与 Fory payload 编码时,可以使用这种模式。 + +生成 gRPC 现在覆盖 Java、Python、Go、Rust、C#、Scala、Kotlin 和 JavaScript/TypeScript。JavaScript 同时支持 Node.js gRPC 和浏览器 gRPC-Web client 生成。 + +下面示例使用同一个 schema: + +```protobuf +package demo.greeter; + +message HelloRequest { + string name = 1; +} + +message HelloReply { + string reply = 1; +} + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); +} +``` + +Rust 生成基于 tonic 的 service API 和 binding module: + +```bash +foryc service.fdl --rust_out=./generated/rust --grpc +``` + +```rust +use demo_greeter::{HelloReply, HelloRequest}; +use demo_greeter_service::Greeter; +use demo_greeter_service_grpc::greeter_client::GreeterClient; +use demo_greeter_service_grpc::greeter_server::GreeterServer; + +tonic::transport::Server::builder() + .add_service(GreeterServer::new(MyGreeter::default())) + .serve(addr) + .await?; + +let mut client = GreeterClient::connect("http://[::1]:50051").await?; +let reply = client.say_hello(HelloRequest { name: "Fory".into() }).await?; +``` + +Go 生成 grpc-go interface 和 Fory-backed `CodecV2`: + +```bash +foryc service.fdl --go_out=./generated/go --grpc +``` + +```go +server := grpc.NewServer( + grpc.ForceServerCodecV2(greeter.CodecV2{}), +) +greeter.RegisterGreeterServer(server, greeterService{}) + +client := greeter.NewGreeterClient(conn) +reply, err := client.SayHello(ctx, &greeter.HelloRequest{Name: "Fory"}) +``` + +JavaScript 同时支持 Node.js gRPC 和浏览器 gRPC-Web: + +```bash +foryc service.fdl --javascript_out=./generated/javascript --grpc --grpc-web +``` + +```ts +import * as grpc from "@grpc/grpc-js"; +import { addGreeterService, createGreeterClient } from "./service_grpc"; +import { createGreeterWebPromiseClient } from "./service_grpc_web"; + +addGreeterService(server, greeterHandlers); + +const nodeClient = createGreeterClient( + "localhost:50051", + grpc.credentials.createInsecure(), +); +nodeClient.sayHello({ name: "Fory" }, callback); + +const webClient = createGreeterWebPromiseClient("https://api.example.com"); +const reply = await webClient.sayHello({ name: "Fory" }); +``` + +浏览器 gRPC-Web 遵循 gRPC-Web transport 限制:支持 unary 和 server-streaming 方法;client-streaming 和 bidirectional streaming 仍属于 Node.js/native gRPC 形态。 + +Kotlin 生成 grpc-kotlin coroutine companion: + +```bash +foryc service.fdl --kotlin_out=./generated/kotlin --grpc +``` + +```kotlin +class GreeterService : GreeterGrpcKt.GreeterCoroutineImplBase() { + override suspend fun sayHello(request: HelloRequest): HelloReply = + HelloReply(reply = "Hello, ${request.name}") +} + +val server = ServerBuilder + .forPort(50051) + .addService(GreeterService()) + .build() + .start() + +val stub = GreeterGrpcKt.GreeterCoroutineStub(channel) +val reply = stub.sayHello(HelloRequest(name = "Fory")) +``` + +Scala 生成 Scala 3 grpc-java companion,并提供更符合 Scala 使用习惯的 client handle: + +```bash +foryc service.fdl --scala_out=./generated/scala --grpc +``` + +```scala +final class GreeterService extends GreeterGrpc.GreeterImplBase { + override def sayHello(request: HelloRequest): HelloReply = + HelloReply(s"Hello, ${request.name}") +} + +val server = ServerBuilder + .forPort(50051) + .addService(new GreeterService) + .build() + .start() + +val client = GreeterGrpc.newClient(channel) +val reply = Await.result(client.sayHello(HelloRequest("Fory")).asFuture, 30.seconds) +``` + +生成的 gRPC companion 不会让核心 Fory 语言包强依赖 gRPC。应用按实际使用的 transport 添加依赖:Java 和 Scala 使用 grpc-java,Python 使用 `grpcio`,Go 使用 grpc-go,Rust 使用 `tonic`/`bytes`,C# 使用 .NET gRPC 包,JavaScript 使用 `@grpc/grpc-js` 或 `grpc-web`,Kotlin 使用 grpc-java/grpc-kotlin。 + +## 功能特性 + +* feat(java): add java9/16 module-info support,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3721 +* refactor(format): inline custom-codec dispatch in row codecs,作者 @stevenschlansker,见 https://github.com/apache/fory/pull/3716 +* perf(format): cache compact row layout per nested slot,作者 @stevenschlansker,见 https://github.com/apache/fory/pull/3717 +* feat(java): remove sun.misc.Unsafe for jdk25,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3702 +* feat(rust): support thread safe `Arc<dyn Any + Send + Sync>` type,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3736 +* refactor(rust): refactor sync send type,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3737 +* feat(xlang): refine register by name api,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3739 +* feat(xlang): support compatible scalar read conversions,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3740 +* feat: default compatible mode for native serialization,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3742 +* perf: optimize compatible mode read performance,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3743 +* feat(compiler): handle Rust identifier escaping and name collisions,作者 @BaldDemian,见 https://github.com/apache/fory/pull/3744 +* feat(go): implement grpc stub generation,作者 @ayush00git,见 https://github.com/apache/fory/pull/3698 +* refactor(compiler): generate C++ unordered map for Fory map,作者 @BaldDemian,见 https://github.com/apache/fory/pull/3745 +* feat(compiler): handle nested container ref pointer options in C++ compiler correctly,作者 @BaldDemian,见 https://github.com/apache/fory/pull/3735 +* feat: add more read checks,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3748 +* feat(compiler): support Rust gRPC code generation,作者 @BaldDemian,见 https://github.com/apache/fory/pull/3738 +* feat(cpp): support struct property accessors,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3751 +* feat(python): make scalar wire markers typing-friendly,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3756 +* feat(kotlin): add kotlin grpc support,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3757 +* feat(rust): make fory-derive generated code use exported api in fory rust lib,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3759 +* feat(scala): add generated grpc service support for scala,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3762 +* feat(csharp): add generated grpc support for C#,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3761 +* feat(javascript): add javascript gRPC support for nodejs/browser,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3760 + +## Bug 修复 + +* fix(go): return nil serializer on getTypeInfo err,作者 @ayush00git,见 https://github.com/apache/fory/pull/3719 +* fix(benchmarks): uses outdated google-java-format, upgrade spotless,作者 @stevenschlansker,见 https://github.com/apache/fory/pull/3722 +* fix(format): pass row body size, not full payload size, to BinaryRow.pointTo,作者 @stevenschlansker,见 https://github.com/apache/fory/pull/3715 +* fix(java): fix deflater memory leak,作者 @MNTMDEV,见 https://github.com/apache/fory/pull/3726 +* fix(compiler): handle nested container ref pointer options in Rust compiler correctly,作者 @BaldDemian,见 https://github.com/apache/fory/pull/3731 +* fix(java): ignore non-Scala/Lombok-style default helper methods,作者 @mandrean,见 https://github.com/apache/fory/pull/3733 +* fix(c++): std::unordered_map cannot be used in struct. (#3727),作者 @ruoruoniao,见 https://github.com/apache/fory/pull/3728 +* fix(grpc): fix rust/go grpc support,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3753 +* fix(cpp): align unsigned struct default encoding,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3754 + +## 其他改进 + +* chore(deps): fix vulnerable dependencies,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3741 +* chore: Bump MessagePack from 2.5.187 to 2.5.301,作者 @dependabot[bot],见 https://github.com/apache/fory/pull/3750 +* chore(deps): bump Go gRPC test dependencies,作者 @chaokunyang,见 https://github.com/apache/fory/pull/3763 + +## 新贡献者 + +* @MNTMDEV 在 https://github.com/apache/fory/pull/3726 中完成了首次贡献 +* @ruoruoniao 在 https://github.com/apache/fory/pull/3728 中完成了首次贡献 + +**完整变更日志**: https://github.com/apache/fory/compare/v1.1.0...v1.2.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/compiler/compiler-guide.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/compiler/compiler-guide.md index a9e14644e7..16a2d40b27 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/compiler/compiler-guide.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/compiler/compiler-guide.md @@ -667,7 +667,7 @@ cc_library( ```yaml dependencies: - fory: ^1.1.0 + fory: ^1.2.0 dev_dependencies: build_runner: ^2.4.0 @@ -859,5 +859,5 @@ fory = "x.y.z" ```yaml dependencies: - fory: ^1.1.0 + fory: ^1.2.0 ``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/cpp/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/cpp/index.md index 3b7a91eaa8..92599c21e3 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/cpp/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/cpp/index.md @@ -61,7 +61,7 @@ include(FetchContent) FetchContent_Declare( fory GIT_REPOSITORY https://github.com/apache/fory.git - GIT_TAG v1.1.0 + GIT_TAG v1.2.0 SOURCE_SUBDIR cpp ) FetchContent_MakeAvailable(fory) @@ -91,11 +91,11 @@ module( bazel_dep(name = "rules_cc", version = "0.1.1") -bazel_dep(name = "fory", version = "1.1.0") +bazel_dep(name = "fory", version = "1.2.0") git_override( module_name = "fory", remote = "https://github.com/apache/fory.git", - commit = "v1.1.0", # 或使用特定 commit hash 以确保可复现性 + commit = "v1.2.0", # 或使用特定 commit hash 以确保可复现性 ) ``` @@ -126,7 +126,7 @@ bazel run //:my_app 对于本地开发,也可以改用 `local_path_override`: ```bazel -bazel_dep(name = "fory", version = "1.1.0") +bazel_dep(name = "fory", version = "1.2.0") local_path_override( module_name = "fory", path = "/path/to/fory", diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/csharp/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/csharp/grpc-support.md new file mode 100644 index 0000000000..d9d7636e07 --- /dev/null +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/csharp/grpc-support.md @@ -0,0 +1,130 @@ +--- +title: gRPC 支持 +sidebar_position: 10 +id: grpc_support +license: | + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--- + +Fory 可以为包含 service 定义的 schema 生成 C# gRPC service companion。生成代码使用标准 .NET +gRPC API,而 request/response 对象使用 Fory payload 编码。 + +当 RPC 两端都由同一份 Fory IDL、protobuf IDL 或 FlatBuffers IDL 生成,并且你希望使用 +gRPC 传输语义与 Fory payload 编码时,可以使用这种模式。如果 API 必须被通用 protobuf client +消费,请使用标准 protobuf gRPC 代码生成。 + +## 添加依赖 + +Server project: + +```xml +<ItemGroup> + <PackageReference Include="Apache.Fory" Version="1.2.0" /> + <PackageReference Include="Grpc.AspNetCore" Version="2.71.0" /> +</ItemGroup> +``` + +Client project: + +```xml +<ItemGroup> + <PackageReference Include="Apache.Fory" Version="1.2.0" /> + <PackageReference Include="Grpc.Core.Api" Version="2.71.0" /> + <PackageReference Include="Grpc.Net.Client" Version="2.71.0" /> +</ItemGroup> +``` + +根据应用使用的 .NET gRPC hosting/client package 调整依赖。`Apache.Fory` 不会把 gRPC 作为硬依赖。 + +## 定义 Service + +```protobuf +package demo.greeter; + +message HelloRequest { + string name = 1; +} + +message HelloReply { + string reply = 1; +} + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); +} +``` + +生成 C# model 和 gRPC companion: + +```bash +foryc service.fdl --csharp_out=./generated/csharp --grpc +``` + +生成 companion 会包含 service base、client、method descriptor,以及 Fory-backed request/response +marshaller。 + +## 实现 Server + +```csharp +using Grpc.Core; + +public sealed class GreeterService : Greeter.GreeterBase +{ + public override Task<HelloReply> SayHello( + HelloRequest request, + ServerCallContext context) + { + return Task.FromResult(new HelloReply + { + Reply = $"Hello, {request.Name}" + }); + } +} +``` + +在 ASP.NET Core gRPC host 中注册生成 service,与普通 .NET gRPC service 一样管理 TLS、认证、 +interceptor、deadline 和 cancellation。 + +## 创建 Client + +```csharp +using Grpc.Net.Client; + +using var channel = GrpcChannel.ForAddress("https://localhost:50051"); +var client = new Greeter.GreeterClient(channel); +var reply = await client.SayHelloAsync(new HelloRequest { Name = "Fory" }); +Console.WriteLine(reply.Reply); +``` + +生成 client 使用 Fory marshaller 编码 request/response。Call option、metadata、deadline 和 +credential 仍遵循 .NET gRPC 行为。 + +## Streaming RPC + +Fory service 支持 unary、server-streaming、client-streaming 和 bidirectional streaming。生成 C# +代码使用 .NET gRPC 的 `AsyncUnaryCall`、`AsyncServerStreamingCall`、`AsyncClientStreamingCall` +和 `AsyncDuplexStreamingCall` 形态。 + +## 故障排查 + +### 缺少 `Grpc.*` 类型 + +添加应用所需的 .NET gRPC package,例如 `Grpc.AspNetCore` 或 `Grpc.Net.Client`。 + +### Protobuf Client 无法读取响应 + +Fory gRPC 使用 Fory 二进制协议 payload,不是 protobuf wire-format message。请在两端使用同一份 +schema 生成的 Fory gRPC companion。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/csharp/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/csharp/index.md index 71fd8870c7..94d9c269e5 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/csharp/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/csharp/index.md @@ -43,7 +43,7 @@ Apache Fory™ C# 是面向 .NET 的高性能跨语言序列化运行时。它 ```xml <ItemGroup> - <PackageReference Include="Apache.Fory" Version="1.1.0" /> + <PackageReference Include="Apache.Fory" Version="1.2.0" /> </ItemGroup> ``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/dart/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/dart/index.md index 29e7f1c42a..569fb7f5c1 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/dart/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/dart/index.md @@ -42,7 +42,7 @@ Apache Fory™ Dart 可以把 Dart 对象序列化为字节,再从字节反序 ```yaml dependencies: - fory: ^1.1.0 + fory: ^1.2.0 dev_dependencies: build_runner: ^2.4.0 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 new file mode 100644 index 0000000000..16a4422639 --- /dev/null +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/go/grpc-support.md @@ -0,0 +1,195 @@ +--- +title: gRPC 支持 +sidebar_position: 13 +id: grpc_support +license: | + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--- + +Fory 可以为包含 service 定义的 schema 生成 Go gRPC service companion。生成代码使用 +grpc-go 负责传输,并使用 Fory-backed `CodecV2` 编码 request 和 response payload。 + +当 RPC 两端都由同一份 Fory IDL、protobuf IDL 或 FlatBuffers IDL 生成,并且你希望使用 +gRPC 传输语义与 Fory payload 编码时,可以使用这种模式。如果客户端或工具必须直接消费 +protobuf message bytes,请使用标准 protobuf gRPC 代码生成。 + +## 添加依赖 + +向 Go module 添加 grpc-go。Fory Go package 不会把 gRPC 作为硬依赖。 + +```bash +go get google.golang.org/grpc +``` + +生成代码也会导入 Fory Go module: + +```bash +go get github.com/apache/fory/go/fory +``` + +## 定义 Service + +Service 定义可以来自 Fory IDL、protobuf IDL 或 FlatBuffers `rpc_service`: + +```protobuf +package demo.greeter; + +message HelloRequest { + string name = 1; +} + +message HelloReply { + string reply = 1; +} + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); +} +``` + +使用 `--grpc` 生成 Go model 和 gRPC companion: + +```bash +foryc service.fdl --go_out=./generated/go --grpc +``` + +输出包含: + +| 文件 | 用途 | +| ------------------------------ | ------------------------------------ | +| `greeter/demo_greeter.go` | Fory model 类型和注册辅助逻辑 | +| `greeter/demo_greeter_grpc.go` | grpc-go client、server interface 和 codec | + +生成的 Go 方法使用导出的 PascalCase 名称,例如 `SayHello`。底层 gRPC method path 保留 +schema 中的原始方法名,因此 `sayHello` 或 `say_hello` 等名称仍按 schema 拼写路由。 + +## 实现 Server + +实现生成的 `GreeterServer` interface,使用生成的 Fory codec 创建 grpc-go server,并注册 service: + +```go +package main + +import ( + "context" + "log" + "net" + + "google.golang.org/grpc" + + "example.com/app/generated/go/greeter" +) + +type greeterService struct { + greeter.UnimplementedGreeterServer +} + +func (greeterService) SayHello( + ctx context.Context, + request *greeter.HelloRequest, +) (*greeter.HelloReply, error) { + return &greeter.HelloReply{Reply: "Hello, " + request.Name}, nil +} + +func main() { + listener, err := net.Listen("tcp", ":50051") + if err != nil { + log.Fatal(err) + } + + server := grpc.NewServer( + grpc.ForceServerCodecV2(greeter.CodecV2{}), + ) + greeter.RegisterGreeterServer(server, greeterService{}) + + if err := server.Serve(listener); err != nil { + log.Fatal(err) + } +} +``` + +`grpc.ForceServerCodecV2(...)` 是必需的,它让 server 使用生成的 Fory codec 解码 frame,而不是默认 protobuf codec。 + +## 创建 Client + +生成的 client constructor 接收 grpc-go connection。生成的 client 方法会为每次调用强制使用匹配的 Fory codec。 + +```go +package main + +import ( + "context" + "fmt" + "log" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + "example.com/app/generated/go/greeter" +) + +func main() { + conn, err := grpc.NewClient( + "localhost:50051", + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + log.Fatal(err) + } + defer conn.Close() + + client := greeter.NewGreeterClient(conn) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + reply, err := client.SayHello(ctx, &greeter.HelloRequest{Name: "Fory"}) + if err != nil { + log.Fatal(err) + } + fmt.Println(reply.Reply) +} +``` + +## Streaming RPC + +Fory service 支持 unary、server-streaming、client-streaming 和 bidirectional streaming。生成 Go 代码遵循 grpc-go 约定: + +- Unary 方法接收 `context.Context` 和 request pointer,返回 response pointer 与 `error`。 +- Server-streaming client 方法返回生成的 stream client。 +- Client-streaming server 方法接收生成的 stream server。 +- Bidirectional streaming 使用生成的 stream client/server interface。 +- 每个 message frame 都使用生成 codec。 + +## 运维语义 + +生成的 service companion 只提供 Fory 序列化。deadline、取消、TLS、credential、unary/stream +interceptor、status code、metadata、名称解析、负载均衡、连接生命周期和 backoff 都保持标准 grpc-go 行为。 + +## 故障排查 + +### 缺少 `google.golang.org/grpc` + +向 module 添加 grpc-go: + +```bash +go get google.golang.org/grpc +``` + +### `grpc: error while marshaling` + +确认 client 和 server 都使用生成的 `CodecV2{}`,并且生成的 model 文件与 gRPC companion 编译在同一个 package 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/java/compression.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/java/compression.md index 2b8c1c7d4f..e43ad76931 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/java/compression.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/java/compression.md @@ -84,7 +84,7 @@ CompressedArraySerializers.registerSerializers(fory); <dependency> <groupId>org.apache.fory</groupId> <artifactId>fory-simd</artifactId> - <version>1.1.0</version> + <version>1.2.0</version> </dependency> ``` 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 new file mode 100644 index 0000000000..7ceae91a1f --- /dev/null +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/java/grpc-support.md @@ -0,0 +1,172 @@ +--- +title: gRPC 支持 +sidebar_position: 10 +id: grpc_support +license: | + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--- + +Fory 可以为包含 service 定义的 schema 生成 Java gRPC service companion。生成的 service code +使用普通 grpc-java channel、server、deadline、status code、interceptor 和 transport security, +但 request/response 对象使用 Fory 序列化,而不是 protobuf。 + +当两端都由同一份 Fory IDL、protobuf IDL 或 FlatBuffers IDL 生成,并且你希望使用 gRPC +传输语义与 Fory payload 编码时,可以使用这种模式。如果 API 必须被通用 protobuf client、 +reflection 工具或期望 protobuf message bytes 的组件消费,请使用标准 protobuf gRPC 代码生成。 + +Scala 生成的 grpc-java companion 见 [Scala gRPC 支持](../scala/grpc-support.md)。Kotlin +coroutine stub 和 service base 见 [Kotlin gRPC 支持](../kotlin/grpc-support.md)。 + +## 添加依赖 + +生成的 Java service 文件编译时需要 grpc-java。Fory Java artifact 不会把 gRPC 作为硬依赖, +因此请在应用中添加 grpc-java 依赖: + +```xml +<dependency> + <groupId>io.grpc</groupId> + <artifactId>grpc-api</artifactId> + <version>${grpc.version}</version> +</dependency> +<dependency> + <groupId>io.grpc</groupId> + <artifactId>grpc-stub</artifactId> + <version>${grpc.version}</version> +</dependency> +<dependency> + <groupId>io.grpc</groupId> + <artifactId>grpc-netty-shaded</artifactId> + <version>${grpc.version}</version> +</dependency> +``` + +Gradle 示例: + +```kotlin +dependencies { + implementation("org.apache.fory:fory-core:$foryVersion") + implementation("io.grpc:grpc-api:$grpcVersion") + implementation("io.grpc:grpc-stub:$grpcVersion") + implementation("io.grpc:grpc-netty-shaded:$grpcVersion") +} +``` + +## 定义 Service + +```protobuf +package demo.greeter; + +message HelloRequest { + string name = 1; +} + +message HelloReply { + string reply = 1; +} + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); +} +``` + +使用 `--grpc` 生成 Java model 和 gRPC companion: + +```bash +foryc service.fdl --java_out=./generated/java --grpc +``` + +生成结果包含 model 类型、schema module 和 grpc-java service companion。生成的 method descriptor +使用 Fory-backed `MethodDescriptor.Marshaller`,因此不会调用 protobuf parser。 + +## 实现 Server + +实现生成的 service base,并注册到标准 grpc-java `Server`: + +```java +import io.grpc.Server; +import io.grpc.ServerBuilder; +import io.grpc.stub.StreamObserver; + +final class GreeterService extends GreeterGrpc.GreeterImplBase { + @Override + public void sayHello( + HelloRequest request, + StreamObserver<HelloReply> responseObserver) { + responseObserver.onNext(new HelloReply("Hello, " + request.name())); + responseObserver.onCompleted(); + } +} + +Server server = ServerBuilder + .forPort(50051) + .addService(new GreeterService()) + .build() + .start(); +``` + +生成代码负责注册和序列化 request/response 类型,service 实现不需要手动创建 Fory 实例。 + +## 创建 Client + +使用普通 grpc-java channel 和生成 stub: + +```java +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; + +ManagedChannel channel = ManagedChannelBuilder + .forAddress("localhost", 50051) + .usePlaintext() + .build(); + +GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel); +HelloReply reply = stub.sayHello(new HelloRequest("Fory")); +``` + +Channel lifecycle、deadline、credential、metadata、load balancing、retry 和 interceptor 都保持 +grpc-java 行为。 + +## Streaming RPC + +Fory service 可以使用 gRPC 的所有 streaming shape: + +```protobuf +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); + rpc LotsOfReplies (HelloRequest) returns (stream HelloReply); + rpc LotsOfGreetings (stream HelloRequest) returns (HelloReply); + rpc Chat (stream HelloRequest) returns (stream HelloReply); +} +``` + +生成 Java service 方法遵循 grpc-java 约定: + +- Unary 方法使用 request 参数和 response `StreamObserver`。 +- Server-streaming 方法向 response observer 多次 `onNext`。 +- Client-streaming 与 bidirectional streaming 返回 request `StreamObserver`。 +- Blocking stub 暴露 grpc-java 支持的 blocking API。 + +## 故障排查 + +### 缺少 `io.grpc` 或 Guava 类 + +添加上面的 grpc-java 依赖。生成的 Fory service 文件导入 grpc-java API,但 Fory Java artifact +不会自动依赖 gRPC。 + +### Protobuf Client 无法解码 + +Fory gRPC companion 不使用 protobuf wire encoding。请使用 Fory 生成的 client 调用 Fory 生成的 +service,或提供单独的 protobuf endpoint。 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 new file mode 100644 index 0000000000..c0df229c4f --- /dev/null +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/javascript/grpc-support.md @@ -0,0 +1,198 @@ +--- +title: gRPC 支持 +sidebar_position: 25 +id: grpc_support +license: | + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--- + +Fory 可以为包含 service 定义的 schema 生成 JavaScript service companion。生成的 service code +使用普通 gRPC transport,但 request 和 response 对象使用 Fory 序列化,而不是 protobuf。 + +使用 `--grpc` 生成 Node.js server/client 代码;使用 `--grpc-web` 生成调用 gRPC-Web 兼容 +server 或 proxy 的浏览器 client。 + +## 添加依赖 + +生成的 model 文件依赖 `@apache-fory/core`。 + +Node.js gRPC companion 导入 `@grpc/grpc-js`: + +```bash +npm install @apache-fory/core @grpc/grpc-js +``` + +浏览器 gRPC-Web companion 导入 `grpc-web`: + +```bash +npm install @apache-fory/core grpc-web +``` + +Fory 不会把 gRPC package 作为硬依赖。只需添加应用实际使用的 transport package。 + +## 定义 Service + +```protobuf +package demo.greeter; + +message HelloRequest { + string name = 1; +} + +message HelloReply { + string reply = 1; +} + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); +} +``` + +生成 Node.js gRPC binding: + +```bash +foryc service.fdl --javascript_out=./generated/javascript --grpc +``` + +生成浏览器 gRPC-Web binding: + +```bash +foryc service.fdl --javascript_out=./generated/javascript --grpc-web +``` + +也可以同时生成: + +```bash +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 | + +## 实现 Node.js Server + +```ts +import * as grpc from "@grpc/grpc-js"; +import { + GreeterHandlers, + addGreeterService, +} from "./generated/javascript/service_grpc"; + +const greeter: GreeterHandlers = { + sayHello(call, callback) { + callback(null, { + reply: `Hello, ${call.request.name}`, + }); + }, +}; + +const server = new grpc.Server(); +addGreeterService(server, greeter); +server.bindAsync( + "0.0.0.0:50051", + grpc.ServerCredentials.createInsecure(), + (error, port) => { + if (error) { + throw error; + } + server.start(); + console.log(`listening on ${port}`); + }, +); +``` + +## 创建 Node.js Client + +```ts +import * as grpc from "@grpc/grpc-js"; +import { createGreeterClient } from "./generated/javascript/service_grpc"; + +const client = createGreeterClient( + "localhost:50051", + grpc.credentials.createInsecure(), +); + +client.sayHello({ name: "Fory" }, (error, reply) => { + if (error) { + throw error; + } + console.log(reply.reply); +}); +``` + +可以继续使用普通 `@grpc/grpc-js` metadata、call option、credential、deadline 和 interceptor。 + +## 创建 Browser Client + +```ts +import { createGreeterWebClient } from "./generated/javascript/service_grpc_web"; + +const client = createGreeterWebClient("https://api.example.com", { + wireFormat: "grpcweb", +}); + +client.sayHello({ name: "Fory" }, null, (error, reply) => { + if (error) { + console.error(error.message); + return; + } + console.log(reply.reply); +}); +``` + +Unary 调用也可以使用生成的 promise client: + +```ts +import { createGreeterWebPromiseClient } from "./generated/javascript/service_grpc_web"; + +const client = createGreeterWebPromiseClient("https://api.example.com"); +const reply = await client.sayHello({ name: "Fory" }); +console.log(reply.reply); +``` + +## Streaming RPC + +Node.js companion 支持所有 gRPC streaming shape。浏览器 gRPC-Web companion 支持 unary 和 +server-streaming;gRPC-Web 不支持 client-streaming 或 bidirectional streaming,compiler 会拒绝 +这些 shape 的 `--grpc-web` 生成。 + +```protobuf +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); + rpc LotsOfReplies (HelloRequest) returns (stream HelloReply); + rpc LotsOfGreetings (stream HelloRequest) returns (HelloReply); + rpc Chat (stream HelloRequest) returns (stream HelloReply); +} +``` + +Node.js server 实现使用普通 `@grpc/grpc-js` streaming call object。生成 companion 只负责把 Fory +payload 接入 gRPC,deadline、credential、metadata、interceptor 和错误语义仍遵循 gRPC 库行为。 + +## 故障排查 + +### 缺少 gRPC Package + +Node.js 添加 `@grpc/grpc-js`,浏览器添加 `grpc-web`。生成 model 仍需要 `@apache-fory/core`。 + +### Protobuf Client 无法读取响应 + +Fory gRPC 使用 Fory 二进制协议 payload,不是 protobuf wire-format message。请在两端使用同一份 +schema 生成的 Fory gRPC companion。 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 new file mode 100644 index 0000000000..e369199092 --- /dev/null +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/kotlin/grpc-support.md @@ -0,0 +1,160 @@ +--- +title: Kotlin gRPC 支持 +sidebar_position: 6 +id: grpc_support +license: | + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--- + +Fory IDL 可以生成 Kotlin coroutine gRPC companion。生成的 gRPC 文件使用普通 grpc-java 和 +grpc-kotlin API,每个 request/response message 使用 Fory 序列化。 + +## 依赖 + +在编译生成源码的应用或 service module 中添加 Fory Kotlin、KSP、grpc-java、grpc-kotlin、 +coroutines 和一个 grpc-java transport: + +```kotlin +plugins { + id("com.google.devtools.ksp") version "<ksp-version>" +} + +dependencies { + implementation("org.apache.fory:fory-kotlin:<fory-version>") + ksp("org.apache.fory:fory-kotlin-ksp:<fory-version>") + + implementation("io.grpc:grpc-api:<grpc-version>") + implementation("io.grpc:grpc-stub:<grpc-version>") + implementation("io.grpc:grpc-kotlin-stub:<grpc-kotlin-version>") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:<coroutines-version>") + + runtimeOnly("io.grpc:grpc-netty-shaded:<grpc-version>") +} +``` + +如果应用已经统一使用其他 grpc-java transport,可以替换 `grpc-netty-shaded`。生成的 Kotlin +Fory gRPC 不需要 `grpc-protobuf` 来编码 payload。 + +## 生成代码 + +```protobuf +package demo.greeter; + +message HelloRequest { + string name = 1; +} + +message HelloReply { + string reply = 1; +} + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); +} +``` + +运行: + +```bash +foryc service.fdl --kotlin_out=./generated/kotlin --grpc +``` + +Compiler 会生成 Kotlin model 文件、schema module(例如 `ServiceForyModule.kt`)以及 service +companion(例如 `GreeterGrpcKt.kt`)。编译生成 model 文件时需要运行 KSP,以便 runtime 可以使用 +schema serializer。 + +## Server + +实现生成的 coroutine base class,并注册到普通 grpc-java server: + +```kotlin +import demo.greeter.GreeterGrpcKt +import demo.greeter.HelloReply +import demo.greeter.HelloRequest +import io.grpc.ServerBuilder + +class GreeterService : GreeterGrpcKt.GreeterCoroutineImplBase() { + override suspend fun sayHello(request: HelloRequest): HelloReply = + HelloReply(reply = "Hello, ${request.name}") +} + +val server = ServerBuilder + .forPort(50051) + .addService(GreeterService()) + .build() + .start() +``` + +未实现的生成方法会返回 gRPC `UNIMPLEMENTED`。Service 方法抛出的异常遵循 grpc-kotlin server 行为。 + +## Client + +从 grpc-java channel 直接构造生成的 coroutine stub: + +```kotlin +import demo.greeter.GreeterGrpcKt +import demo.greeter.HelloRequest +import io.grpc.ManagedChannelBuilder + +val channel = ManagedChannelBuilder + .forAddress("localhost", 50051) + .usePlaintext() + .build() + +val stub = GreeterGrpcKt.GreeterCoroutineStub(channel) +val reply = stub.sayHello(HelloRequest(name = "Fory")) +``` + +Channel 构造、关闭、deadline、credential、interceptor、load balancing、retry 和 server lifecycle +仍由 grpc-java/grpc-kotlin 负责。 + +## Streaming + +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<Res>` | `fun a(request: Req): Flow<Res>` | +| `rpc A (stream Req) returns (Res)` | `suspend fun a(requests: Flow<Req>): Res` | `suspend fun a(requests: Flow<Req>): Res` | +| `rpc A (stream Req) returns (stream Res)` | `fun a(requests: Flow<Req>): Flow<Res>` | `fun a(requests: Flow<Req>): Flow<Res>` | + +生成 method path 保留 schema 中的 service 和 method 名称,例如 `/demo.greeter.Greeter/SayHello`。 + +## 互操作性 + +生成的 Kotlin service companion 在 gRPC frame 中使用 Fory 二进制 payload。它可以与从同一 schema +生成的其他 Fory gRPC companion 互操作,例如 Java、Go、Python 和 Rust。通用 protobuf gRPC +client 无法解码这些 payload。 + +## 故障排查 + +**缺少生成的 service 文件** + +同时传入 `--grpc` 和 `--kotlin_out`。没有 service 定义的 schema 只会生成 model 文件和 schema module。 + +**运行时找不到 serializer class** + +确保生成的 Kotlin model source 运行了 KSP,并且 `fory-kotlin-ksp` 与 `fory-kotlin` 使用同一个 Fory 版本。 + +**gRPC 类无法解析** + +向应用 module 添加 grpc-java 和 grpc-kotlin 依赖。Fory Kotlin artifact 不会自动添加这些依赖。 + +**Protobuf client 无法读取响应** + +Fory gRPC 使用 Fory 二进制协议 payload,不是 protobuf wire-format message。请在两端使用同一份 +schema 生成的 Fory gRPC companion。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/kotlin/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/kotlin/index.md index f7a2b53fbf..859dfa00f9 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/kotlin/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/kotlin/index.md @@ -50,14 +50,14 @@ Fory Kotlin 继承了 Fory Java 的全部特性,并增加了 Kotlin 特定优 <dependency> <groupId>org.apache.fory</groupId> <artifactId>fory-kotlin</artifactId> - <version>1.1.0</version> + <version>1.2.0</version> </dependency> ``` ### Gradle ```kotlin -implementation("org.apache.fory:fory-kotlin:1.1.0") +implementation("org.apache.fory:fory-kotlin:1.2.0") ``` ## 快速开始 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 new file mode 100644 index 0000000000..a6aed054c4 --- /dev/null +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/python/grpc-support.md @@ -0,0 +1,133 @@ +--- +title: gRPC 支持 +sidebar_position: 9 +id: grpc_support +license: | + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--- + +Fory 可以为包含 service 定义的 schema 生成 Python gRPC companion module。生成代码使用 +`grpcio` 负责传输,request 和 response 对象使用 `pyfory` 序列化。 + +当两端都由同一份 Fory IDL、protobuf IDL 或 FlatBuffers IDL 生成,并且你希望使用 gRPC +传输语义与 Fory payload 编码时,可以使用这种模式。如果客户端或工具必须直接消费 protobuf +message bytes,请使用标准 protobuf gRPC 代码生成。 + +## 添加依赖 + +```bash +pip install pyfory grpcio +``` + +Fory Python package 不会把 gRPC 作为硬依赖;只有编译或运行生成 gRPC companion 的应用需要安装 +`grpcio`。 + +## 定义 Service + +```protobuf +package demo.greeter; + +message HelloRequest { + string name = 1; +} + +message HelloReply { + string reply = 1; +} + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); +} +``` + +生成 Python model 和 gRPC companion: + +```bash +foryc service.fdl --python_out=./generated/python --grpc +``` + +生成结果通常包含 model module 和 `<module>_grpc.py` companion。Companion 会导入生成的 +`to_bytes`/`from_bytes` 辅助逻辑,并把它们接入 `grpcio` serializer/deserializer。 + +## 实现 Server + +```python +from concurrent import futures +import grpc + +from generated.python.service import HelloReply +from generated.python import service_grpc + + +class Greeter(service_grpc.GreeterServicer): + def SayHello(self, request, context): + return HelloReply(reply=f"Hello, {request.name}") + + +server = grpc.server(futures.ThreadPoolExecutor(max_workers=4)) +service_grpc.add_GreeterServicer_to_server(Greeter(), server) +server.add_insecure_port("[::]:50051") +server.start() +server.wait_for_termination() +``` + +## 创建 Client + +```python +import grpc + +from generated.python.service import HelloRequest +from generated.python import service_grpc + +with grpc.insecure_channel("localhost:50051") as channel: + stub = service_grpc.GreeterStub(channel) + reply = stub.SayHello(HelloRequest(name="Fory")) + print(reply.reply) +``` + +Channel、credential、deadline、metadata、interceptor、retry 和 server lifecycle 都保持 `grpcio` +行为。 + +## Streaming RPC + +Fory service 可以使用 unary、server-streaming、client-streaming 和 bidirectional streaming: + +```protobuf +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); + rpc LotsOfReplies (HelloRequest) returns (stream HelloReply); + rpc LotsOfGreetings (stream HelloRequest) returns (HelloReply); + rpc Chat (stream HelloRequest) returns (stream HelloReply); +} +``` + +生成 Python companion 使用 `grpcio` 的 iterator/generator 约定处理 streaming。每个 message +frame 都通过 Fory serializer/deserializer 编码。 + +## 故障排查 + +### 缺少 `grpc` + +安装 `grpcio`: + +```bash +pip install grpcio +``` + +### Protobuf Client 无法解码 + +Fory gRPC 使用 Fory 二进制协议 payload,不是 protobuf wire-format message。两端应使用同一份 +schema 生成的 Fory gRPC companion。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/basic-serialization.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/basic-serialization.md index 691f093e7c..76bfe93fa6 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/basic-serialization.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/basic-serialization.md @@ -143,7 +143,7 @@ let later = timestamp.checked_add_duration(duration)?; ```toml [dependencies] -fory = { version = "1.1.0", features = ["chrono"] } +fory = { version = "1.2.0", features = ["chrono"] } ``` ### 自定义类型 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 new file mode 100644 index 0000000000..c3dc73452d --- /dev/null +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/grpc-support.md @@ -0,0 +1,199 @@ +--- +title: gRPC 支持 +sidebar_position: 12 +id: grpc_support +license: | + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--- + +Fory 可以为包含 service 定义的 schema 生成 Rust gRPC service companion。生成代码使用 +`tonic` 负责传输,使用 Fory 序列化 request 和 response payload。 + +当 RPC 两端都由同一份 Fory IDL、protobuf IDL 或 FlatBuffers IDL 生成,并且你希望使用 +gRPC 的传输语义与 Fory payload 编码时,可以使用这种模式。如果客户端或工具必须直接读取 +protobuf message bytes,请继续使用标准 protobuf gRPC 代码生成。 + +## 添加依赖 + +编译生成 service 文件的 crate 需要添加 `tonic` 和 `bytes`。Fory Rust crate 不会将 +gRPC 作为硬依赖。异步 server/client 还需要 `tokio`;如果 service 实现需要构造 +streaming response,可添加 `tokio-stream`。 + +```toml +[dependencies] +fory = "1.2.0" +bytes = "1" +tonic = { version = "0.14", features = ["transport"] } +tokio = { version = "1", features = ["macros", "rt-multi-thread"] } +tokio-stream = "0.1" +``` + +请使用与应用服务栈兼容的依赖版本。 + +## 定义 Service + +Service 定义可以来自 Fory IDL、protobuf IDL 或 FlatBuffers `rpc_service`。例如: + +```protobuf +package demo.greeter; + +message HelloRequest { + string name = 1; +} + +message HelloReply { + string reply = 1; +} + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); +} +``` + +使用 `--grpc` 生成 Rust model 和 gRPC companion: + +```bash +foryc service.fdl --rust_out=./generated/rust --grpc +``` + +该 schema 会生成: + +| 文件 | 用途 | +| ------------------------------ | ----------------------------------- | +| `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: + +```rust +pub mod demo_greeter; +pub mod demo_greeter_service; +pub mod demo_greeter_service_grpc; +``` + +## 实现 Server + +实现生成的异步 trait,并把生成的 server wrapper 添加到普通 `tonic` server: + +```rust +use demo_greeter::{HelloReply, HelloRequest}; +use demo_greeter_service::Greeter; +use demo_greeter_service_grpc::greeter_server::GreeterServer; +use tonic::{Request, Response, Status}; + +#[derive(Default)] +struct MyGreeter; + +#[tonic::async_trait] +impl Greeter for MyGreeter { + async fn say_hello( + &self, + request: Request<HelloRequest>, + ) -> Result<Response<HelloReply>, Status> { + let request = request.into_inner(); + Ok(Response::new(HelloReply { + reply: format!("Hello, {}", request.name), + })) + } +} + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let addr = "[::1]:50051".parse()?; + tonic::transport::Server::builder() + .add_service(GreeterServer::new(MyGreeter::default())) + .serve(addr) + .await?; + Ok(()) +} +``` + +生成的 service code 会负责序列化 request 和 response 类型,service 实现中不需要手动注册 Fory。 + +## 创建 Client + +使用生成的 tonic client: + +```rust +use demo_greeter::HelloRequest; +use demo_greeter_service_grpc::greeter_client::GreeterClient; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let mut client = GreeterClient::connect("http://[::1]:50051").await?; + let response = client + .say_hello(HelloRequest { + name: "Fory".to_string(), + }) + .await?; + println!("{}", response.into_inner().reply); + Ok(()) +} +``` + +Channel 配置、TLS、deadline、metadata、interceptor 和传输生命周期仍由 `tonic` 管理。 + +## Streaming RPC + +Fory service 支持 unary、server-streaming、client-streaming 和 bidirectional streaming: + +```protobuf +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); + rpc LotsOfReplies (HelloRequest) returns (stream HelloReply); + rpc LotsOfGreetings (stream HelloRequest) returns (HelloReply); + rpc Chat (stream HelloRequest) returns (stream HelloReply); +} +``` + +生成 Rust 代码遵循 tonic 约定: + +- Unary 方法使用 `tonic::Request<T>`,返回 `tonic::Response<U>`。 +- Server-streaming 方法返回内部值为 stream 的 response。 +- Client-streaming 和 bidirectional 方法接收 `tonic::Streaming<T>`。 +- 生成的 client module 暴露与 service 方法对应的异步方法。 +- 每个 message frame 都使用生成 codec,包括 streaming frame。 + +Rust gRPC payload 必须满足 `Send + 'static`,这样 tonic 才能在线程间移动 request/response。 +如果 request 或 response schema 使用非线程安全的引用元信息,Rust gRPC 生成会拒绝该 service。 + +## 运维语义 + +生成的 service companion 只提供 Fory 序列化和 tonic binding。deadline、取消、TLS、认证、 +Tower middleware、interceptor、status code、metadata、channel/server 生命周期和 backpressure +仍遵循标准 tonic 行为。 + +## 故障排查 + +### 缺少 `tonic` 或 `bytes` + +在编译生成 service 文件的 crate 中添加上述依赖。 + +### `UNIMPLEMENTED` + +确认已通过 `Server::builder().add_service(...)` 添加生成的 server wrapper,并且 client 与 +server 来自相同的 package、service 和 method 名称。 + +### 生成时报非线程安全引用错误 + +Rust gRPC payload 必须满足 `Send + 'static`。请调整 request/response schema 使用线程安全 +引用形态,或不要把非线程安全类型放在 RPC 边界上。 + +### Protobuf Client 无法解码 Service + +Fory gRPC companion 不使用 protobuf wire encoding。请使用 Fory 生成的 client 调用 Fory 生成的 +service,或为通用 protobuf client 提供单独的 protobuf service endpoint。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/index.md index 04b0d2fb30..d6349d2e66 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/rust/index.md @@ -47,7 +47,7 @@ Rust 实现提供灵活而高性能的序列化能力,具备自动内存管理 ```toml [dependencies] -fory = "1.1.0" +fory = "1.2.0" ``` ### 基础示例 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/scala/grpc-support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/scala/grpc-support.md new file mode 100644 index 0000000000..dd1780dff2 --- /dev/null +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/scala/grpc-support.md @@ -0,0 +1,169 @@ +--- +title: gRPC 支持 +sidebar_position: 6 +id: grpc_support +license: | + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--- + +Fory 可以为包含 service 定义的 schema 生成 Scala 3 gRPC service companion。生成代码使用普通 +grpc-java channel、server、deadline、status code、interceptor 和 transport security,但 +request/response 对象使用 Fory 序列化,而不是 protobuf。 + +当 RPC 两端都由同一份 Fory IDL、protobuf IDL 或 FlatBuffers IDL 生成,并且你希望使用 +gRPC 传输语义与 Fory payload 编码时,可以使用这种模式。如果 API 必须被通用 protobuf client +或 reflection 工具消费,请使用标准 protobuf gRPC 代码生成。 + +## 添加依赖 + +生成的 Scala service 文件编译时需要 grpc-java。`fory-scala` artifact 不会把 gRPC 作为硬依赖: + +```sbt +libraryDependencies ++= Seq( + "org.apache.fory" %% "fory-scala" % "<fory-version>", + "io.grpc" % "grpc-api" % "<grpc-version>", + "io.grpc" % "grpc-stub" % "<grpc-version>", + "io.grpc" % "grpc-netty-shaded" % "<grpc-version>" +) +``` + +生成的 Scala model 和 gRPC companion 是 Scala 3 source。`fory-scala` 仍同时 cross-build +Scala 2.13 和 Scala 3。 + +## 定义 Service + +```protobuf +package demo.greeter; + +message HelloRequest { + string name = 1; +} + +message HelloReply { + string reply = 1; +} + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); +} +``` + +生成 Scala model 和 gRPC companion: + +```bash +foryc service.fdl --scala_out=./generated/scala --grpc +``` + +输出包含: + +| 文件 | 用途 | +| ------------------------- | ---------------------------------- | +| `HelloRequest.scala` | request 的 Fory model type | +| `HelloReply.scala` | response 的 Fory model type | +| `GreeterForyModule.scala` | 生成类型的 Fory 注册 module | +| `GreeterGrpc.scala` | grpc-java service base、client 和 codec | + +## 实现 Server + +继承生成的 `GreeterGrpc.GreeterImplBase`,并注册到标准 grpc-java `Server`: + +```scala +package demo.greeter + +import io.grpc.ServerBuilder + +final class GreeterService extends GreeterGrpc.GreeterImplBase { + override def sayHello(request: HelloRequest): HelloReply = + HelloReply(s"Hello, ${request.name}") +} + +@main def runServer(): Unit = { + val server = ServerBuilder + .forPort(50051) + .addService(new GreeterService) + .build() + .start() + server.awaitTermination() +} +``` + +生成代码会注册 request/response 类型,service 实现不需要手动注册 serializer。 + +## 创建 Client + +使用普通 grpc-java channel 和生成 client: + +```scala +package demo.greeter + +import io.grpc.ManagedChannelBuilder +import scala.concurrent.Await +import scala.concurrent.duration.DurationInt + +@main def runClient(): Unit = { + val channel = ManagedChannelBuilder + .forAddress("localhost", 50051) + .usePlaintext() + .build() + try { + val client = GreeterGrpc.newClient(channel) + val call = client.sayHello(HelloRequest("Fory")) + val reply = Await.result(call.asFuture, 30.seconds) + println(reply.reply) + } finally { + channel.shutdownNow() + } +} +``` + +Unary Scala-friendly 方法返回 `RpcFuture[A]`。调用者可以通过 `asFuture` 与 Scala `Future` 组合, +并在需要提前取消 RPC 时调用 `cancel()`。 + +## Streaming RPC + +Fory service 支持与 grpc-java 相同的 streaming shape: + +```protobuf +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); + rpc LotsOfReplies (HelloRequest) returns (stream HelloReply); + rpc LotsOfGreetings (stream HelloRequest) returns (HelloReply); + rpc Chat (stream HelloRequest) returns (stream HelloReply); +} +``` + +| IDL shape | Scala client convenience | grpc-java-style 方法 | +| ----------------------- | ------------------------ | -------------------------------------------- | +| Unary | `RpcFuture[Resp]` | async observer、blocking、`ListenableFuture` | +| Server streaming | `RpcIterator[Resp]` | async observer 和 blocking iterator | +| Client streaming | 无 | `StreamObserver` request stream | +| Bidirectional streaming | 无 | request/response `StreamObserver` | + +Server-streaming 的 `RpcIterator[A]` 扩展 Scala `Iterator[A]` 和 `AutoCloseable`。如果调用者提前停止消费, +应调用 `close()` 或 `cancel()` 释放底层 gRPC call。 + +Client-streaming 和 bidirectional streaming 保持 grpc-java `StreamObserver` API,因为 request +stream lifecycle、completion、cancellation 和 flow-control 规则都属于 grpc-java。 + +## 故障排查 + +### 缺少 grpc-java 类 + +添加 `grpc-api`、`grpc-stub` 和一个 transport,例如 `grpc-netty-shaded`。 + +### Protobuf Client 无法读取响应 + +Fory gRPC 使用 Fory 二进制协议 payload。请在两端使用同一份 schema 生成的 Fory gRPC companion。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/scala/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/scala/index.md index f6a0a3a685..f04891a0d4 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/scala/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/scala/index.md @@ -48,7 +48,7 @@ Fory Scala 继承了 Fory Java 的全部特性,并增加了 Scala 特定优化 使用 sbt 添加依赖: ```sbt -libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.1.0" +libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.2.0" ``` ## 快速开始 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/xlang/getting-started.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/xlang/getting-started.md index f8fe9b2946..f2b9a89e77 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/xlang/getting-started.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/guide/xlang/getting-started.md @@ -31,14 +31,14 @@ license: | <dependency> <groupId>org.apache.fory</groupId> <artifactId>fory-core</artifactId> - <version>1.1.0</version> + <version>1.2.0</version> </dependency> ``` **Gradle:** ```gradle -implementation 'org.apache.fory:fory-core:1.1.0' +implementation 'org.apache.fory:fory-core:1.2.0' ``` ### Python @@ -57,7 +57,7 @@ go get github.com/apache/fory/go/fory ```toml [dependencies] -fory = "1.1.0" +fory = "1.2.0" ``` ### JavaScript/TypeScript @@ -75,13 +75,13 @@ npm install @apache-fory/core @apache-fory/hps ### C\# ```bash -dotnet add package Apache.Fory --version 1.1.0 +dotnet add package Apache.Fory --version 1.2.0 ``` ### Dart ```bash -dart pub add fory:^1.1.0 +dart pub add fory:^1.2.0 dart pub add dev:build_runner ``` @@ -91,20 +91,20 @@ dart pub add dev:build_runner ```swift dependencies: [ - .package(url: "https://github.com/apache/fory.git", exact: "1.1.0") + .package(url: "https://github.com/apache/fory.git", exact: "1.2.0") ] ``` ### Scala ```scala -libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.1.0" +libraryDependencies += "org.apache.fory" %% "fory-scala" % "1.2.0" ``` ### Kotlin ```kotlin -implementation("org.apache.fory:fory-kotlin:1.1.0") +implementation("org.apache.fory:fory-kotlin:1.2.0") ``` ### C++ diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/install.md index d29a4f0d96..5c43f4d64b 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/install.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/start/install.md @@ -16,14 +16,14 @@ Apache Fory™ 同时提供源码发布物和各语言对应的软件包。 <dependency> <groupId>org.apache.fory</groupId> <artifactId>fory-core</artifactId> - <version>1.1.0</version> + <version>1.2.0</version> </dependency> <!-- 可选的 row format 支持 --> <!-- <dependency> <groupId>org.apache.fory</groupId> <artifactId>fory-format</artifactId> - <version>1.1.0</version> + <version>1.2.0</version> </dependency> --> <!-- 用于数组压缩的 SIMD 加速(Java 16+) --> @@ -31,7 +31,7 @@ Apache Fory™ 同时提供源码发布物和各语言对应的软件包。 <dependency> <groupId>org.apache.fory</groupId> <artifactId>fory-simd</artifactId> - <version>1.1.0</version> + <version>1.2.0</version> </dependency> --> ``` @@ -44,7 +44,7 @@ Scala 2.13 的 Maven 依赖: <dependency> <groupId>org.apache.fory</groupId> <artifactId>fory-scala_2.13</artifactId> - <version>1.1.0</version> + <version>1.2.0</version> </dependency> ``` @@ -54,20 +54,20 @@ Scala 3 的 Maven 依赖: <dependency> <groupId>org.apache.fory</groupId> <artifactId>fory-scala_3</artifactId> - <version>1.1.0</version> + <version>1.2.0</version> </dependency> ``` Scala 2.13 的 sbt 依赖: ```sbt -libraryDependencies += "org.apache.fory" % "fory-scala_2.13" % "1.1.0" +libraryDependencies += "org.apache.fory" % "fory-scala_2.13" % "1.2.0" ``` Scala 3 的 sbt 依赖: ```sbt -libraryDependencies += "org.apache.fory" % "fory-scala_3" % "1.1.0" +libraryDependencies += "org.apache.fory" % "fory-scala_3" % "1.2.0" ``` ## Kotlin @@ -78,7 +78,7 @@ libraryDependencies += "org.apache.fory" % "fory-scala_3" % "1.1.0" <dependency> <groupId>org.apache.fory</groupId> <artifactId>fory-kotlin</artifactId> - <version>1.1.0</version> + <version>1.2.0</version> </dependency> ``` @@ -86,7 +86,7 @@ libraryDependencies += "org.apache.fory" % "fory-scala_3" % "1.1.0" ```bash python -m pip install --upgrade pip -pip install pyfory==1.1.0 +pip install pyfory==1.2.0 ``` ## Go @@ -94,7 +94,7 @@ pip install pyfory==1.1.0 请使用完整的 Go 模块路径 `github.com/apache/fory/go/fory`: ```bash -go get github.com/apache/fory/go/[email protected] +go get github.com/apache/fory/go/[email protected] ``` 如果你的 Go proxy 还没有同步新的子模块 tag,请稍后重试,或者临时使用 `GOPROXY=direct`。 @@ -103,13 +103,13 @@ go get github.com/apache/fory/go/[email protected] ```toml [dependencies] -fory = "1.1.0" +fory = "1.2.0" ``` 或者使用 `cargo add`: ```bash -cargo add [email protected] +cargo add [email protected] ``` ## JavaScript / TypeScript @@ -132,7 +132,7 @@ npm install @apache-fory/hps ```yaml dependencies: - fory: ^1.1.0 + fory: ^1.2.0 dev_dependencies: build_runner: ^2.4.13 @@ -149,12 +149,12 @@ dart run build_runner build --delete-conflicting-outputs 安装 `Apache.Fory` NuGet 包。它同时包含运行时以及 `[ForyObject]` 类型所需的源代码生成器。 ```bash -dotnet add package Apache.Fory --version 1.1.0 +dotnet add package Apache.Fory --version 1.2.0 ``` ```xml <ItemGroup> - <PackageReference Include="Apache.Fory" Version="1.1.0" /> + <PackageReference Include="Apache.Fory" Version="1.2.0" /> </ItemGroup> ``` @@ -164,7 +164,7 @@ dotnet add package Apache.Fory --version 1.1.0 ```swift dependencies: [ - .package(url: "https://github.com/apache/fory.git", exact: "1.1.0") + .package(url: "https://github.com/apache/fory.git", exact: "1.2.0") ], targets: [ .target( diff --git a/i18n/zh-CN/docusaurus-plugin-content-pages/download/index.md b/i18n/zh-CN/docusaurus-plugin-content-pages/download/index.md index e4a1d64365..9cebfa3847 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-pages/download/index.md +++ b/i18n/zh-CN/docusaurus-plugin-content-pages/download/index.md @@ -9,11 +9,11 @@ Apache Fory™ 的官方发布以源码制品形式提供。 ## 最新版本 -当前最新源码版本为 1.1.0: +当前最新源码版本为 1.2.0: | 版本 | 日期 | 源码 | 发布说明 | | ------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | -| 1.1.0 | 2026-05-31 | [source](https://www.apache.org/dyn/closer.lua/fory/1.1.0/apache-fory-1.1.0-src.tar.gz?action=download) [asc](https://downloads.apache.org/fory/1.1.0/apache-fory-1.1.0-src.tar.gz.asc) [sha512](https://downloads.apache.org/fory/1.1.0/apache-fory-1.1.0-src.tar.gz.sha512) | [release notes](https://github.com/apache/fory/releases/tag/v1.1.0) | +| 1.2.0 | 2026-06-16 | [source](https://www.apache.org/dyn/closer.lua/fory/1.2.0/apache-fory-1.2.0-src.tar.gz?action=download) [asc](https://downloads.apache.org/fory/1.2.0/apache-fory-1.2.0-src.tar.gz.asc) [sha512](https://downloads.apache.org/fory/1.2.0/apache-fory-1.2.0-src.tar.gz.sha512) | [release notes](https://github.com/apache/fory/releases/tag/v1.2.0) | ## 所有归档版本 @@ -31,13 +31,13 @@ Fory 为下载站点上的所有文件提供 SHA 摘要和 PGP 签名文件。 要验证 SHA 摘要,你需要 `.tar.gz` 文件及其对应的 `.tar.gz.sha512` 文件。示例命令如下: ```bash -sha512sum --check apache-fory-1.1.0-src.tar.gz.sha512 +sha512sum --check apache-fory-1.2.0-src.tar.gz.sha512 ``` 输出类似下面这样即表示校验通过: ```bash -apache-fory-1.1.0-src.tar.gz: OK +apache-fory-1.2.0-src.tar.gz: OK ``` ### 校验签名 @@ -53,7 +53,7 @@ gpg --import KEYS 之后可以校验签名: ```bash -gpg --verify apache-fory-1.1.0-src.tar.gz.asc apache-fory-1.1.0-src.tar.gz +gpg --verify apache-fory-1.2.0-src.tar.gz.asc apache-fory-1.2.0-src.tar.gz ``` 如果出现如下输出,即表示签名正确: --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
