From 880fae4625bdc1dcde0d5f1247091eeb30dab554 Mon Sep 17 00:00:00 2001 From: Xinyi Date: Thu, 8 May 2025 17:31:07 +0800 Subject: [PATCH 01/14] docs(generic streaming): update streamCli.Close() usage in code examples for clarity --- .../generic-call/generic_streaming.md | 286 ++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md new file mode 100644 index 00000000000..03f51bed9b5 --- /dev/null +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -0,0 +1,286 @@ +--- +title: "流式泛化调用用户指南" +date: 2025-05-07 +weight: 6 +keywords: ["流式泛化调用用户指南"] +description: "" +--- + +## 简介 + +**Kitex v0.12.0 起支持流式接口的 JSON 泛化调用(仅客户端)**。 + +## 使用方法 + +### 泛化流式客户端初始化 + +#### protobuf + +以如下 Protobuf IDL 为例: + +```protobuf +syntax = "proto3"; +package pb; +option go_package = "pb"; + +message Request { + string message = 1; +} + +message Response { + string message = 1; +} + +service StreamingService { + rpc StreamRequestEcho (stream Request) returns (Response) {} + rpc StreamResponseEcho (Request) returns (stream Response) {} + rpc BidirectionalEcho (stream Request) returns (stream Response) {} + rpc UnaryEcho (Request) returns (Response) {} +} +``` + +上述 IDL 包含四种方法,分别对应四种场景: + +1. 客户端流:客户端发送多条消息,服务端返回一条消息后关闭流。 +2. 服务端流:客户端发送一条消息,服务端返回多条消息后关闭流,适合大模型等场景。 +3. 双向流:客户端和服务端可独立收发消息,顺序可自定义。 +4. 单次调用(非流式)。 + +流式客户端初始化示例: + +```go +ctx := context.Background() + +// 初始化泛化客户端 +dOpts := proto.Options{} +p, err := generic.NewPbFileProviderWithDynamicGo(idlPath, ctx, dOpts) +if err != nil { + log.Fatal(err) +} + +// 创建 JSON 泛化对象 +g, err := generic.JSONPbGeneric(p) +if err != nil { + log.Fatal(err) +} + +// 初始化流式客户端 +cli, err := genericclient.NewStreamingClient( + "streaming", + g, + client.WithTransportProtocol(transport.GRPC), + client.WithHostPorts("127.0.0.1:8888"), + client.WithMetaHandler(transmeta.ClientHTTP2Handler), +) + +// ... 其他流式调用示例 ... +``` + +#### thrift + +以如下 Thrift IDL 为例: + +```thrift +namespace go echo + +struct Request { + 1: required string message, +} + +struct Response { + 1: required string message, +} + +service TestService { + Response Echo (1: Request req) (streaming.mode="bidirectional"), + Response EchoClient (1: Request req) (streaming.mode="client"), + Response EchoServer (1: Request req) (streaming.mode="server"), + // Response EchoUnary (1: Request req) (streaming.mode="unary"), // 不推荐 + + Response EchoPingPong (1: Request req), // KitexThrift,非流式 +} +``` + +上述 IDL 包含以下场景: + +1. 客户端流:客户端发送多条消息,服务端返回一条消息后关闭流。 +2. 服务端流:客户端发送一条消息,服务端返回多条消息后关闭流,适合大模型等场景。 +3. 双向流:客户端和服务端可独立收发消息,顺序可自定义。 +4. 单次调用(gRPC):带 `streaming.mode` 注解的非流式(不推荐,性能有损失)。 +5. 单次调用(KitexThrift):非流式(推荐)。 + +流式客户端初始化示例: + +```go +// 1. 创建 Thrift 文件提供者 +p, err := generic.NewThriftFileProvider("../idl/streaming.thrift") +if err != nil { + log.Fatal(err) +} + +// 2. 创建 JSON Thrift 泛化调用 +g, err := generic.JSONThriftGeneric(p) +if err != nil { + log.Fatal(err) +} + +// 3. 创建流式客户端 +cli, err := genericclient.NewStreamingClient( + "streaming_service", + g, + client.WithTransportProtocol(transport.GRPC), + client.WithHostPorts("127.0.0.1:8888"), +) +// ... 其他流式调用示例 ... +``` + +### 客户端流(Client Streaming) + +示例: + +```go +// 使用已创建的流式客户端初始化 client streaming +streamCli, err := genericclient.NewClientStreaming(ctx, cli, "EchoClient") + +// 发送多个请求 +for i := 0; i < 3; i++ { + req := fmt.Sprintf(`{"message": "grpc client streaming generic %dth request"}`, i) + if err = streamCli.Send(req); err != nil { + return fmt.Errorf("failed to send: %v", err) + } + time.Sleep(time.Second) +} + +// 接收最终响应 +resp, err := streamCli.CloseAndRecv() +strResp, ok := resp.(string) // 响应为 json 字符串 +``` + +### 服务端流(Server Streaming) + +注意:`Recv` 返回非 nil 错误(包括 `io.EOF`)表示服务端已发送完毕或出错。 + +示例: + +```go +// 使用已创建的流式客户端初始化 server streaming,并发送消息 +streamCli, err := genericclient.NewServerStreaming(ctx, cli, "EchoServer", `{"message": "grpc server streaming generic request"}`) + +// 接收多个响应 +for { + resp, err := streamCli.Recv() + if err == io.EOF { + fmt.Println("Server streaming message receive done. stream is closed") + break + } else if err != nil { + return fmt.Errorf("failed to receive: %v", err) + } + + strResp, ok := resp.(string) +} +``` + +### 双向流(Bidirectional Streaming) + +示例: + +```go +// 使用已创建的流式客户端初始化 bidirectional streaming +streamCli, err := genericclient.NewBidirectionalStreaming(ctx, cli, "Echo") +if err != nil { + return fmt.Errorf("failed to create bidirectional streaming: %v", err) +} + +wg := &sync.WaitGroup{} +wg.Add(2) +var sendErr, recvErr error + +// 发送消息 +go func() { + defer func() { + if p := recover(); p != nil { + sendErr = fmt.Errorf("panic: %v", p) + } + wg.Done() + }() + + for i := 0; i < 3; i++ { + req := fmt.Sprintf(`{"message": "grpc bidirectional streaming generic %dth request"}`, i) + if err = streamCli.Send(req); err != nil { + sendErr = fmt.Errorf("bidirectionalStreaming send: failed, err = %v", err) + break + } + klog.Infof("BidirectionalStreamingTest send: req = %+v", req) + } + + // 发送完所有消息后关闭客户端到服务端的流方向 + if cerr := streamCli.Close(); cerr != nil { + sendErr = fmt.Errorf("stream close failed: %v", cerr) + } +}() + + +// 接收消息 +go func() { + defer func() { + if p := recover(); p != nil { + recvErr = fmt.Errorf("panic: %v", p) + } + wg.Done() + }() + + for { + resp, err := streamCli.Recv() + if err == io.EOF { + klog.Infof("bidirectionalStreaming message receive done. stream is closed") + break + } else if err != nil { + recvErr = fmt.Errorf("failed to recv: %v", err) + break + } + + strResp, ok := resp.(string) + } +}() + +wg.Wait() +``` + +### 单次调用(PingPong) + +用法与普通(非流式)泛化调用类似。 + +示例: + +```go +resp, err := cli.GenericCall(ctx, "EchoPingPong", `{"message": "unary request"}`) +strResp, ok := resp.(string) // 响应为 json 字符串 +``` + +## 常见问题(FAQ) + +### Recv() got err: rpc error: code = 12 desc = Method not found! + +该错误出现在 Kitex **protobuf** 泛化流式调用下游为 **gRPC-python**(或其他语言 gRPC 库)时。 + +根因是 Kitex 没有解析 protobuf idl 的 package,导致 gRPC 请求的 `:path` 缺少 package 部分,gRPC-python 找不到对应方法。 + +例如: + +- 普通客户端 + +`:path` - /search.gpt_engine.GPTStreamService/GPTGeneration + +- protobuf 泛化客户端 + +`:path` - /GPTStreamService/GPTGeneration + +#### 解决办法 + +可用如下分支修复,等待 Kitex v1.18.1 正式发布后即可解决: + +```shell +go get -u github.com/cloudwego/kitex@v0.12.1-0.20241220085925-b5894d2f9e0c +``` + +如需完整 main 函数示例,请参考官方 demo。 \ No newline at end of file From acf1c45c3df89af926451234f2bc64c76ffa28a6 Mon Sep 17 00:00:00 2001 From: Xinyi Date: Fri, 9 May 2025 23:18:37 +0800 Subject: [PATCH 02/14] docs: create generic streaming documentation in Chinese --- .../advanced-feature/generic-call/generic_streaming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index 03f51bed9b5..a6915867a9d 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -1,6 +1,6 @@ --- title: "流式泛化调用用户指南" -date: 2025-05-07 +date: 2025-05-09 weight: 6 keywords: ["流式泛化调用用户指南"] description: "" From 428c235bbcf5286ede2f69b649460e36f29a89ec Mon Sep 17 00:00:00 2001 From: Xinyi Date: Fri, 9 May 2025 23:27:26 +0800 Subject: [PATCH 03/14] docs(kitex): align generic streaming code examples with kitex-examples demo --- .../generic-call/generic_streaming.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index a6915867a9d..ae46dea0fe0 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -54,15 +54,9 @@ ctx := context.Background() // 初始化泛化客户端 dOpts := proto.Options{} p, err := generic.NewPbFileProviderWithDynamicGo(idlPath, ctx, dOpts) -if err != nil { - log.Fatal(err) -} // 创建 JSON 泛化对象 g, err := generic.JSONPbGeneric(p) -if err != nil { - log.Fatal(err) -} // 初始化流式客户端 cli, err := genericclient.NewStreamingClient( @@ -114,15 +108,9 @@ service TestService { ```go // 1. 创建 Thrift 文件提供者 p, err := generic.NewThriftFileProvider("../idl/streaming.thrift") -if err != nil { - log.Fatal(err) -} // 2. 创建 JSON Thrift 泛化调用 g, err := generic.JSONThriftGeneric(p) -if err != nil { - log.Fatal(err) -} // 3. 创建流式客户端 cli, err := genericclient.NewStreamingClient( @@ -130,7 +118,9 @@ cli, err := genericclient.NewStreamingClient( g, client.WithTransportProtocol(transport.GRPC), client.WithHostPorts("127.0.0.1:8888"), + client.WithMetaHandler(transmeta.ClientHTTP2Handler), ) + // ... 其他流式调用示例 ... ``` From b6bec3887a37a05073beb346b9fbf75ff92cf91b Mon Sep 17 00:00:00 2001 From: Xinyi Date: Fri, 9 May 2025 23:32:20 +0800 Subject: [PATCH 04/14] docs(kitex): add link to generic streaming demo --- .../advanced-feature/generic-call/generic_streaming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index ae46dea0fe0..3d41e9e7868 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -273,4 +273,4 @@ strResp, ok := resp.(string) // 响应为 json 字符串 go get -u github.com/cloudwego/kitex@v0.12.1-0.20241220085925-b5894d2f9e0c ``` -如需完整 main 函数示例,请参考官方 demo。 \ No newline at end of file +如需完整 main 函数示例,请参考[官方 demo](https://github.com/cloudwego/kitex-examples/tree/main/generic_streaming)。 \ No newline at end of file From 5d8f1e77e217804cc1edddf6293a00849c15a6c4 Mon Sep 17 00:00:00 2001 From: Xinyi Date: Mon, 12 May 2025 13:14:41 +0800 Subject: [PATCH 05/14] docs(kitex): improve generic streaming documentation with better imports and standardized terms --- .../generic-call/generic_streaming.md | 21 +++++++++++++++++-- .../generic-call/generic_streaming.md | 19 +++++++++++++---- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index 73652156a1d..df45f61ebf7 100644 --- a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -51,10 +51,17 @@ First of all, please initialize the streaming client. Here is an example of stre ```go import ( - dproto "github.com/cloudwego/dynamicgo/proto" + "context" + + "github.com/cloudwego/kitex/client" + "github.com/cloudwego/kitex/client/genericclient" + "github.com/cloudwego/kitex/pkg/generic" + "github.com/cloudwego/kitex/pkg/generic/proto" + "github.com/cloudwego/kitex/pkg/transmeta" + "github.com/cloudwego/kitex/transport" ) -dOpts := dproto.Options{} // you can specify parsing options as you want +dOpts := proto.Options{} // you can specify parsing options as you want p, err := generic.NewPbFileProviderWithDynamicGo(your_idl, ctx, dOpts) // create json pb generic g, err := generic.JSONPbGeneric(p) @@ -102,6 +109,16 @@ The four methods included in the example IDL correspond to four scenarios: Here is an example of streaming client initialization. ```go +import ( + "context" + + "github.com/cloudwego/kitex/client" + "github.com/cloudwego/kitex/client/genericclient" + "github.com/cloudwego/kitex/pkg/generic" + "github.com/cloudwego/kitex/pkg/transmeta" + "github.com/cloudwego/kitex/transport" +) + p, err := generic.NewThriftFileProvider(your_idl_path) /* // if you use dynamicgo diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index 3d41e9e7868..c2a852404d0 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -41,14 +41,25 @@ service StreamingService { 上述 IDL 包含四种方法,分别对应四种场景: -1. 客户端流:客户端发送多条消息,服务端返回一条消息后关闭流。 -2. 服务端流:客户端发送一条消息,服务端返回多条消息后关闭流,适合大模型等场景。 -3. 双向流:客户端和服务端可独立收发消息,顺序可自定义。 -4. 单次调用(非流式)。 +1. Client Streaming:客户端发送多条消息,服务端返回一条消息后关闭流。 +2. Server Streaming:客户端发送一条消息,服务端返回多条消息后关闭流,适合大模型等场景。 +3. Bidirectional Streaming:客户端和服务端可独立收发消息,顺序可自定义。 +4. Unary:单次调用(非流式)。 流式客户端初始化示例: ```go +import ( + "context" + + "github.com/cloudwego/kitex/client" + "github.com/cloudwego/kitex/client/genericclient" + "github.com/cloudwego/kitex/pkg/generic" + "github.com/cloudwego/kitex/pkg/generic/proto" + "github.com/cloudwego/kitex/pkg/transmeta" + "github.com/cloudwego/kitex/transport" +) + ctx := context.Background() // 初始化泛化客户端 From 411bbe3b50c30ca152ab4091dcee61b40ebde1f2 Mon Sep 17 00:00:00 2001 From: Xinyi Date: Mon, 12 May 2025 13:17:39 +0800 Subject: [PATCH 06/14] docs(kitex): clarify distinction between Unary and Ping Pong modes in streaming documentation --- .../generic-call/generic_streaming.md | 18 +++++++++--------- .../generic-call/generic_streaming.md | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index df45f61ebf7..d59bd0054c7 100644 --- a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -42,10 +42,10 @@ service Echo { The four methods included in the example IDL correspond to four scenarios: -1. Client streaming: the client sends multiple messages, the server returns one message, and then closes the stream. -2. Server streaming: The client sends one message, the server returns multiple messages, and then closes the stream. It's suitable for LLM scenarios. -3. Bidirectional streaming: The sending and receiving of client/server are independent, which can be organized in arbitrary order. -4. Unary: non streaming. +1. Client Streaming: the client sends multiple messages, the server returns one message, and then closes the stream. +2. Server Streaming: The client sends one message, the server returns multiple messages, and then closes the stream. It's suitable for LLM scenarios. +3. Bidirectional Streaming: The sending and receiving of client/server are independent, which can be organized in arbitrary order. +4. Unary: In gRPC, this is a single call mode without using streams, similar to the Ping Pong mode in Thrift. First of all, please initialize the streaming client. Here is an example of streaming client initialization. @@ -100,11 +100,11 @@ service TestService { The four methods included in the example IDL correspond to four scenarios: -1. Client streaming: the client sends multiple messages, the server returns one message, and then closes the stream. -2. Server streaming: The client sends one message, the server returns multiple messages, and then closes the stream. It's suitable for LLM scenarios. -3. Bidirectional streaming: The sending and receiving of client/server are independent, which can be organized in arbitrary order. -4. Unary (gRPC): Non-streaming. With `streaming.mode` annotation. Not recommended due to performance loss. -5. Unary (KitexThrift): Non-streaming. Recommended. +1. Client Streaming: the client sends multiple messages, the server returns one message, and then closes the stream. +2. Server Streaming: The client sends one message, the server returns multiple messages, and then closes the stream. It's suitable for LLM scenarios. +3. Bidirectional Streaming: The sending and receiving of client/server are independent, which can be organized in arbitrary order. +4. Unary (gRPC): Non-streaming with `streaming.mode` annotation. Not recommended due to performance loss. +5. Ping Pong mode (KitexThrift): Traditional Thrift request-response pattern without using streams. Better performance, recommended. Here is an example of streaming client initialization. diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index c2a852404d0..8434d4041b7 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -44,7 +44,7 @@ service StreamingService { 1. Client Streaming:客户端发送多条消息,服务端返回一条消息后关闭流。 2. Server Streaming:客户端发送一条消息,服务端返回多条消息后关闭流,适合大模型等场景。 3. Bidirectional Streaming:客户端和服务端可独立收发消息,顺序可自定义。 -4. Unary:单次调用(非流式)。 +4. Unary:gRPC 中的单次调用模式,不使用流机制,类似于 Thrift 中的 Ping Pong 模式。 流式客户端初始化示例: @@ -112,7 +112,7 @@ service TestService { 2. 服务端流:客户端发送一条消息,服务端返回多条消息后关闭流,适合大模型等场景。 3. 双向流:客户端和服务端可独立收发消息,顺序可自定义。 4. 单次调用(gRPC):带 `streaming.mode` 注解的非流式(不推荐,性能有损失)。 -5. 单次调用(KitexThrift):非流式(推荐)。 +5. Ping Pong 模式(KitexThrift):传统的 Thrift 一发一收模式,不使用流机制,性能更好,推荐使用。 流式客户端初始化示例: From 44e1410fffc8308096abd0e4a2a2b8e203efe8fd Mon Sep 17 00:00:00 2001 From: Xinyi Date: Mon, 12 May 2025 13:20:57 +0800 Subject: [PATCH 07/14] docs(kitex): clarify io.EOF meaning in streaming documentation --- .../advanced-feature/generic-call/generic_streaming.md | 2 +- .../advanced-feature/generic-call/generic_streaming.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index d59bd0054c7..d35f18d0656 100644 --- a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -154,7 +154,7 @@ strResp, ok := resp.(string) // response is json string ### Server Streaming -Note: A non-nil error (including `io.EOF`) returned by `Recv` indicates that the server has finished sending (or encountered an error) +Note: An `io.EOF` error returned by `Recv` indicates that the server has finished sending and normally closed the stream, while other non-nil errors indicate actual errors. Example: diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index 8434d4041b7..b0cf9f1bd9b 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -1,6 +1,6 @@ --- title: "流式泛化调用用户指南" -date: 2025-05-09 +date: 2025-05-12 weight: 6 keywords: ["流式泛化调用用户指南"] description: "" @@ -159,7 +159,7 @@ strResp, ok := resp.(string) // 响应为 json 字符串 ### 服务端流(Server Streaming) -注意:`Recv` 返回非 nil 错误(包括 `io.EOF`)表示服务端已发送完毕或出错。 +注意:`Recv` 返回 `io.EOF` 错误表示服务端已发送完毕并正常关闭流,其它非 nil 错误表示出错。 示例: From 09ad7a9a0261c8af1aae47560aea2984804b8895 Mon Sep 17 00:00:00 2001 From: Xinyi Date: Mon, 12 May 2025 13:22:33 +0800 Subject: [PATCH 08/14] docs(kitex): update Kitex version to v0.13.1 in streaming documentation --- .../advanced-feature/generic-call/generic_streaming.md | 4 ++-- .../advanced-feature/generic-call/generic_streaming.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index d35f18d0656..62fdd5bd429 100644 --- a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -263,8 +263,8 @@ e.g. #### Solution -Use the following branch to solve it and wait for the official release of Kitex v1.18.1 to fix this issue. +Use the following branch to solve it and wait for the official release of Kitex v0.13.1 to fix this issue. ```shell -go get -u github.com/cloudwego/kitex@v0.12.1-0.20241220085925-b5894d2f9e0c +go get -u github.com/cloudwego/kitex@v0.13.1 ``` diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index b0cf9f1bd9b..3ae471dc003 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -278,10 +278,10 @@ strResp, ok := resp.(string) // 响应为 json 字符串 #### 解决办法 -可用如下分支修复,等待 Kitex v1.18.1 正式发布后即可解决: +可用如下分支修复,等待 Kitex v0.13.1 正式发布后即可解决: ```shell -go get -u github.com/cloudwego/kitex@v0.12.1-0.20241220085925-b5894d2f9e0c +go get -u github.com/cloudwego/kitex@v0.13.1 ``` 如需完整 main 函数示例,请参考[官方 demo](https://github.com/cloudwego/kitex-examples/tree/main/generic_streaming)。 \ No newline at end of file From 0fe9aba02f03476f027f4e5a050c294790c70af9 Mon Sep 17 00:00:00 2001 From: Xinyi Date: Mon, 12 May 2025 13:26:10 +0800 Subject: [PATCH 09/14] docs(kitex): add genericclient imports to all streaming code examples --- .../generic-call/generic_streaming.md | 33 +++++++++++++++++++ .../generic-call/generic_streaming.md | 32 ++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index 62fdd5bd429..244ebfba621 100644 --- a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -139,6 +139,14 @@ cli, err := genericclient.NewStreamingClient("destService", g, Example: ```go +import ( + "context" + "fmt" + "time" + + "github.com/cloudwego/kitex/client/genericclient" +) + // initialize client streaming client using the streaming client you created streamCli, err := genericclient.NewClientStreaming(ctx, cli, "StreamRequestEcho") for i := 0; i < 3; i++ { @@ -159,6 +167,15 @@ Note: An `io.EOF` error returned by `Recv` indicates that the server has finishe Example: ```go +import ( + "context" + "fmt" + "io" + + "github.com/cloudwego/kitex/client/genericclient" + "github.com/cloudwego/kitex/pkg/klog" +) + // initialize server streaming client using the streaming client you created, and send a message streamCli, err := genericclient.NewServerStreaming(ctx, cli, "StreamResponseEcho", `{"message": "grpc server streaming generic request"}`) for { @@ -181,6 +198,16 @@ for { Example: ```go +import ( + "context" + "fmt" + "io" + "sync" + + "github.com/cloudwego/kitex/client/genericclient" + "github.com/cloudwego/kitex/pkg/klog" +) + // initialize bidirectional streaming client using the streaming client you created streamCli, err := genericclient.NewBidirectionalStreaming(ctx, cli, "BidirectionalEcho") @@ -239,6 +266,12 @@ The usage of unary call is similar to normal (non-streaming) generic call. Example: ```go +import ( + "context" + + "github.com/cloudwego/kitex/client/genericclient" +) + resp, err := cli.GenericCall(ctx, "UnaryEcho", `{"message": "unary request"}`) strResp, ok := resp.(string) // response is json string ``` diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index 3ae471dc003..a5061ceb34b 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -140,6 +140,14 @@ cli, err := genericclient.NewStreamingClient( 示例: ```go +import ( + "context" + "fmt" + "time" + + "github.com/cloudwego/kitex/client/genericclient" +) + // 使用已创建的流式客户端初始化 client streaming streamCli, err := genericclient.NewClientStreaming(ctx, cli, "EchoClient") @@ -164,6 +172,14 @@ strResp, ok := resp.(string) // 响应为 json 字符串 示例: ```go +import ( + "context" + "fmt" + "io" + + "github.com/cloudwego/kitex/client/genericclient" +) + // 使用已创建的流式客户端初始化 server streaming,并发送消息 streamCli, err := genericclient.NewServerStreaming(ctx, cli, "EchoServer", `{"message": "grpc server streaming generic request"}`) @@ -186,6 +202,16 @@ for { 示例: ```go +import ( + "context" + "fmt" + "io" + "sync" + + "github.com/cloudwego/kitex/client/genericclient" + "github.com/cloudwego/kitex/pkg/klog" +) + // 使用已创建的流式客户端初始化 bidirectional streaming streamCli, err := genericclient.NewBidirectionalStreaming(ctx, cli, "Echo") if err != nil { @@ -254,6 +280,12 @@ wg.Wait() 示例: ```go +import ( + "context" + + "github.com/cloudwego/kitex/client/genericclient" +) + resp, err := cli.GenericCall(ctx, "EchoPingPong", `{"message": "unary request"}`) strResp, ok := resp.(string) // 响应为 json 字符串 ``` From 33ccbdf45ad71f2d764cb6d2c079870c6874d5b8 Mon Sep 17 00:00:00 2001 From: Xinyi Date: Mon, 12 May 2025 13:30:25 +0800 Subject: [PATCH 10/14] docs(kitex): use English terminology for streaming modes in Chinese document --- .../generic-call/generic_streaming.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index a5061ceb34b..0254a0e303e 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -108,11 +108,11 @@ service TestService { 上述 IDL 包含以下场景: -1. 客户端流:客户端发送多条消息,服务端返回一条消息后关闭流。 -2. 服务端流:客户端发送一条消息,服务端返回多条消息后关闭流,适合大模型等场景。 -3. 双向流:客户端和服务端可独立收发消息,顺序可自定义。 -4. 单次调用(gRPC):带 `streaming.mode` 注解的非流式(不推荐,性能有损失)。 -5. Ping Pong 模式(KitexThrift):传统的 Thrift 一发一收模式,不使用流机制,性能更好,推荐使用。 +1. Client Streaming:客户端发送多条消息,服务端返回一条消息后关闭流。 +2. Server Streaming:客户端发送一条消息,服务端返回多条消息后关闭流,适合大模型等场景。 +3. Bidirectional Streaming:客户端和服务端可独立收发消息,顺序可自定义。 +4. Unary (gRPC):带 `streaming.mode` 注解的非流式(不推荐,性能有损失)。 +5. Ping Pong (KitexThrift):传统的 Thrift 一发一收模式,不使用流机制,性能更好,推荐使用。 流式客户端初始化示例: @@ -135,7 +135,7 @@ cli, err := genericclient.NewStreamingClient( // ... 其他流式调用示例 ... ``` -### 客户端流(Client Streaming) +### Client Streaming 示例: @@ -165,7 +165,7 @@ resp, err := streamCli.CloseAndRecv() strResp, ok := resp.(string) // 响应为 json 字符串 ``` -### 服务端流(Server Streaming) +### Server Streaming 注意:`Recv` 返回 `io.EOF` 错误表示服务端已发送完毕并正常关闭流,其它非 nil 错误表示出错。 @@ -197,7 +197,7 @@ for { } ``` -### 双向流(Bidirectional Streaming) +### Bidirectional Streaming 示例: @@ -273,7 +273,7 @@ go func() { wg.Wait() ``` -### 单次调用(PingPong) +### Ping Pong 用法与普通(非流式)泛化调用类似。 From 5896f579e5d8a1f44a608836ab48786639300f7c Mon Sep 17 00:00:00 2001 From: Xinyi Date: Mon, 12 May 2025 13:31:29 +0800 Subject: [PATCH 11/14] docs(kitex): refine description of Ping Pong mode in Chinese document --- .../advanced-feature/generic-call/generic_streaming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index 0254a0e303e..2e05f542476 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -112,7 +112,7 @@ service TestService { 2. Server Streaming:客户端发送一条消息,服务端返回多条消息后关闭流,适合大模型等场景。 3. Bidirectional Streaming:客户端和服务端可独立收发消息,顺序可自定义。 4. Unary (gRPC):带 `streaming.mode` 注解的非流式(不推荐,性能有损失)。 -5. Ping Pong (KitexThrift):传统的 Thrift 一发一收模式,不使用流机制,性能更好,推荐使用。 +5. Ping Pong (KitexThrift):传统的 Thrift 请求-响应模式,不使用流机制,性能更好,推荐使用。 流式客户端初始化示例: From fcc1bd3405b21a4b8ccae01d52009123d9ef828d Mon Sep 17 00:00:00 2001 From: Xinyi Date: Mon, 12 May 2025 13:33:26 +0800 Subject: [PATCH 12/14] docs(kitex): capitalize Protobuf in both Chinese and English streaming documents --- .../advanced-feature/generic-call/generic_streaming.md | 8 ++++---- .../advanced-feature/generic-call/generic_streaming.md | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index 244ebfba621..5972a4089e9 100644 --- a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -14,7 +14,7 @@ description: "" ### Generic Streaming Client Initialization -#### protobuf +#### Protobuf Take the following Protobuf IDL as an example: @@ -280,9 +280,9 @@ strResp, ok := resp.(string) // response is json string ### Recv() got err: rpc error: code = 12 desc = Method not found! -This error occurs when calling with Kitex **protobuf** generic streaming when the downstream is **gRPC-python** (gRPC libraries for other languages may also have this problem). +This error occurs when calling with Kitex **Protobuf** generic streaming when the downstream is **gRPC-python** (gRPC libraries for other languages may also have this problem). -The root cause is that Kitex does not parse the package in the protobuf idl, so the package part of `:path` in the gPRC request is missing, and gRPC-python can't find the corresponding method. +The root cause is that Kitex does not parse the package in the Protobuf IDL, so the package part of `:path` in the gPRC request is missing, and gRPC-python can't find the corresponding method. e.g. @@ -290,7 +290,7 @@ e.g. `:path` - /search.gpt_engine.GPTStreamService/GPTGeneration -- protobuf generic client +- Protobuf generic client `:path` - /GPTStreamService/GPTGeneration diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index 2e05f542476..76a5a4c677f 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -14,7 +14,7 @@ description: "" ### 泛化流式客户端初始化 -#### protobuf +#### Protobuf 以如下 Protobuf IDL 为例: @@ -294,9 +294,9 @@ strResp, ok := resp.(string) // 响应为 json 字符串 ### Recv() got err: rpc error: code = 12 desc = Method not found! -该错误出现在 Kitex **protobuf** 泛化流式调用下游为 **gRPC-python**(或其他语言 gRPC 库)时。 +该错误出现在 Kitex **Protobuf** 泛化流式调用下游为 **gRPC-python**(或其他语言 gRPC 库)时。 -根因是 Kitex 没有解析 protobuf idl 的 package,导致 gRPC 请求的 `:path` 缺少 package 部分,gRPC-python 找不到对应方法。 +根因是 Kitex 没有解析 Protobuf IDL 的 package,导致 gRPC 请求的 `:path` 缺少 package 部分,gRPC-python 找不到对应方法。 例如: @@ -304,7 +304,7 @@ strResp, ok := resp.(string) // 响应为 json 字符串 `:path` - /search.gpt_engine.GPTStreamService/GPTGeneration -- protobuf 泛化客户端 +- Protobuf 泛化客户端 `:path` - /GPTStreamService/GPTGeneration From c3754c79c7235f9b4ed208cd724b02fe2bb07210 Mon Sep 17 00:00:00 2001 From: Xinyi Date: Mon, 12 May 2025 14:50:34 +0800 Subject: [PATCH 13/14] docs(kitex): add imports in streaming examples --- .../generic-call/generic_streaming.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index 76a5a4c677f..e8d678ad9e3 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -44,7 +44,7 @@ service StreamingService { 1. Client Streaming:客户端发送多条消息,服务端返回一条消息后关闭流。 2. Server Streaming:客户端发送一条消息,服务端返回多条消息后关闭流,适合大模型等场景。 3. Bidirectional Streaming:客户端和服务端可独立收发消息,顺序可自定义。 -4. Unary:gRPC 中的单次调用模式,不使用流机制,类似于 Thrift 中的 Ping Pong 模式。 +4. Unary:gRPC 中的单次调用模式,类似于 Thrift 中的 Ping Pong 模式。 流式客户端初始化示例: @@ -117,6 +117,16 @@ service TestService { 流式客户端初始化示例: ```go +import ( + "context" + + "github.com/cloudwego/kitex/client" + "github.com/cloudwego/kitex/client/genericclient" + "github.com/cloudwego/kitex/pkg/generic" + "github.com/cloudwego/kitex/pkg/transmeta" + "github.com/cloudwego/kitex/transport" +) + // 1. 创建 Thrift 文件提供者 p, err := generic.NewThriftFileProvider("../idl/streaming.thrift") From 8d678a535a876492f542da7dc8d34f4852fc2416 Mon Sep 17 00:00:00 2001 From: Xinyi Date: Mon, 12 May 2025 14:53:57 +0800 Subject: [PATCH 14/14] docs(kitex): add link to Kitex v0.13.1 release notes --- .../advanced-feature/generic-call/generic_streaming.md | 2 +- .../advanced-feature/generic-call/generic_streaming.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index 5972a4089e9..d26ff4ab59b 100644 --- a/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/en/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -296,7 +296,7 @@ e.g. #### Solution -Use the following branch to solve it and wait for the official release of Kitex v0.13.1 to fix this issue. +Use Kitex v0.13.1 or higher version to fix this issue. Kitex v0.13.1 was released in April 2025 ([See release notes](https://github.com/cloudwego/kitex/releases/tag/v0.13.1)): ```shell go get -u github.com/cloudwego/kitex@v0.13.1 diff --git a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md index e8d678ad9e3..4e0465b2663 100644 --- a/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md +++ b/content/zh/docs/kitex/Tutorials/advanced-feature/generic-call/generic_streaming.md @@ -320,7 +320,7 @@ strResp, ok := resp.(string) // 响应为 json 字符串 #### 解决办法 -可用如下分支修复,等待 Kitex v0.13.1 正式发布后即可解决: +使用 Kitex v0.13.1 及以上版本可解决此问题。Kitex v0.13.1 已于 2025年4月发布([查看发布说明](https://github.com/cloudwego/kitex/releases/tag/v0.13.1)): ```shell go get -u github.com/cloudwego/kitex@v0.13.1