From b7d7ea6e178a1da03c3a199863c69be6de53092c Mon Sep 17 00:00:00 2001 From: hechenghao Date: Thu, 24 Jul 2025 11:45:39 +0800 Subject: [PATCH 1/3] Implement a chat room using tRPC. --- .idea/.gitignore | 8 + .idea/golinter.xml | 7 + .idea/modules.xml | 8 + .idea/trpc-a2a-go.iml | 9 + .idea/vcs.xml | 6 + examples/chat/README.md | 23 ++ examples/chat/doc/README.md | 142 ++++++++ examples/chat/out/chatroom_service.go | 104 ++++++ examples/chat/out/cmd/client/main.go | 103 ++++++ examples/chat/out/go.mod | 49 +++ examples/chat/out/go.sum | 128 +++++++ examples/chat/out/main.go | 18 + .../chat/out/stub/chat/protobuf/chat.pb.go | 145 ++++++++ .../chat/out/stub/chat/protobuf/chat.proto | 15 + .../chat/out/stub/chat/protobuf/chat.trpc.go | 156 +++++++++ .../chat/out/stub/chat/protobuf/chat_mock.go | 320 ++++++++++++++++++ examples/chat/out/stub/chat/protobuf/go.mod | 42 +++ examples/chat/out/stub/chat/protobuf/go.sum | 139 ++++++++ examples/chat/out/trpc.log | 29 ++ examples/chat/out/trpc_go.yaml | 49 +++ examples/chat/protobuf/chat.proto | 15 + 21 files changed, 1515 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/golinter.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/trpc-a2a-go.iml create mode 100644 .idea/vcs.xml create mode 100644 examples/chat/README.md create mode 100644 examples/chat/doc/README.md create mode 100644 examples/chat/out/chatroom_service.go create mode 100644 examples/chat/out/cmd/client/main.go create mode 100644 examples/chat/out/go.mod create mode 100644 examples/chat/out/go.sum create mode 100644 examples/chat/out/main.go create mode 100644 examples/chat/out/stub/chat/protobuf/chat.pb.go create mode 100644 examples/chat/out/stub/chat/protobuf/chat.proto create mode 100644 examples/chat/out/stub/chat/protobuf/chat.trpc.go create mode 100644 examples/chat/out/stub/chat/protobuf/chat_mock.go create mode 100644 examples/chat/out/stub/chat/protobuf/go.mod create mode 100644 examples/chat/out/stub/chat/protobuf/go.sum create mode 100644 examples/chat/out/trpc.log create mode 100644 examples/chat/out/trpc_go.yaml create mode 100644 examples/chat/protobuf/chat.proto diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..13566b81 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/golinter.xml b/.idea/golinter.xml new file mode 100644 index 00000000..1ccf3ec6 --- /dev/null +++ b/.idea/golinter.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..f6e743a7 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/trpc-a2a-go.iml b/.idea/trpc-a2a-go.iml new file mode 100644 index 00000000..5e764c4f --- /dev/null +++ b/.idea/trpc-a2a-go.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/examples/chat/README.md b/examples/chat/README.md new file mode 100644 index 00000000..b42f5b7b --- /dev/null +++ b/examples/chat/README.md @@ -0,0 +1,23 @@ +## 背景 +基于trpc实现一个简单的聊天室 + +## 环境 +- os ubuntu24.04 +- go 1.24 + +## 运行 + +```shell + cd example/chat/out +``` + +1. 启动服务端 +```shell + go run . +``` +2. 启动客户端 +```shell + go run cmd/client/main.go --name="default" --room="anonymous" --target="ip://127.0.0.1:8000"" +``` + + diff --git a/examples/chat/doc/README.md b/examples/chat/doc/README.md new file mode 100644 index 00000000..80dc95bc --- /dev/null +++ b/examples/chat/doc/README.md @@ -0,0 +1,142 @@ +# tRPC-A2A-Go 聊天室体验报告 + +## 一、体验背景 + +本次体验基于 tRPC-A2A-Go 框架实现一个简单的聊天室功能,旨在熟悉 tRPC 框架的双向流式通信能力及 A2A(Application-to-Application)通信规范。通过实践了解 tRPC 在构建实时通信应用场景下的开发流程、接口设计及部署方式。 + +## 二、环境准备 + +1. **基础环境** + - 操作系统:Ubuntu 24.04 + - Go 版本:1.24 + - tRPC 相关工具:trpc-cli + +2. **依赖安装** + ```shell + # 安装 tRPC 代码生成工具 + go install trpc.group/trpc-go/trpc-cmdline/trpc@latest + ``` + +## 三、开发过程 + +### 1. 协议设计(Protobuf) + +根据聊天室场景需求,定义了 `ChatroomMessage` 消息结构和 `ChatroomService` 服务接口,使用 proto3 语法: + +```protobuf +syntax = "proto3"; + +package chat; +option go_package = "chat/protobuf;chat"; + +message ChatroomMessage { + string room_id = 1; // 聊天室的唯一标识 + string sender = 2; // 消息发送者 + string content = 3; // 消息内容 +} + +service ChatroomService { + // 双向流式的聊天室通信方法 + rpc Chat(stream ChatroomMessage) returns (stream ChatroomMessage); +} +``` + +关键设计说明: +- 采用双向流式 RPC(`stream`)实现实时消息推送 +- 消息包含聊天室 ID、发送者和内容三个核心字段 +- 通过 `go_package` 指定生成代码的 Go 包路径 + +### 2. 代码生成 + +使用 tRPC 工具根据 proto 文件生成基础代码: + +```makefile +.PHONY: chat-proto +chat-proto: + trpc create -p protobuf/chat.proto -o out +``` + +执行生成命令: +```shell +make chat-proto +``` + +生成结果:在 `out` 目录下自动创建了服务端和客户端的基础框架代码,包括: +- 服务接口定义 +- 消息编解码逻辑 +- 网络传输层封装 + +### 3. 业务逻辑实现 + +#### 服务端实现 +服务端需要维护聊天室会话,实现消息转发逻辑: +- 维护房间与连接的映射关系 +- 接收客户端消息并广播给同房间其他用户 +- 处理新用户加入和用户离开事件 + +#### 客户端实现 +客户端实现用户交互和消息收发: +- 命令行参数解析(用户名、房间号、服务端地址) +- 从标准输入读取用户消息并发送 +- 监听服务端推送的消息并显示 + +### 4. 运行与测试 + +1. 启动服务端 +```shell +cd example/chat/out +go run . +``` + +2. 启动多个客户端(新终端窗口) +```shell +# 客户端1 +go run cmd/client/main.go --name="Alice" --room="anonymous" --target="ip://127.0.0.1:8000" + +# 客户端2 +go run cmd/client/main.go --name="Bob" --room="anonymous" --target="ip://127.0.0.1:8000" +``` + +3. 功能测试 +- 发送消息:在任一客户端输入文本并回车,其他客户端可收到消息 +- 多房间隔离:不同房间的消息不会互相干扰 +- 身份标识:消息会显示发送者名称,区分不同用户 + +## 四、A2A 特性体验 + +1. **双向流式通信** + 通过 tRPC 的流式 RPC 实现了全双工通信,客户端和服务端可随时发送消息,满足聊天室实时交互需求。 + +2. **服务发现与注册** + 体验了 tRPC 内置的服务发现机制,客户端通过 `target` 参数指定服务端地址即可建立连接。 + +3. **协议兼容性** + 基于 Protobuf 协议实现,具备良好的跨语言兼容性,可扩展支持多语言客户端接入。 + +4. **错误处理** + 框架自动处理网络异常和连接断开情况,客户端断开后服务端会自动清理会话。 + +## 五、问题与解决方案 + +1. **消息广播效率** + 问题:当房间用户较多时,消息广播可能出现延迟 + 解决方案:实现消息异步转发,使用缓冲通道减少阻塞 + +2. **客户端重连** + 问题:网络中断后客户端需要手动重启 + 解决方案:在客户端实现自动重连机制,检测连接状态并尝试重新连接 + +## 六、总结与展望 + +### 体验总结 +1. tRPC-A2A-Go 框架提供了简洁的接口定义和代码生成能力,大幅降低了实时通信应用的开发门槛 +2. 双向流式 RPC 机制非常适合聊天室这类需要持续交互的场景 +3. 完善的工具链支持(代码生成、构建部署)简化了开发流程 + +### 未来优化方向 +1. 增加用户认证机制,确保消息发送者身份合法性 +2. 实现消息持久化,支持历史消息查询 +3. 扩展支持文件传输、表情等富媒体消息 +4. 优化服务端架构,支持水平扩展以应对高并发场景 + +通过本次体验,深入了解了 tRPC-A2A-Go 在实时通信场景下的应用方式,框架的设计理念和易用性给人留下深刻印象,适合用于构建高性能的分布式应用。 \ No newline at end of file diff --git a/examples/chat/out/chatroom_service.go b/examples/chat/out/chatroom_service.go new file mode 100644 index 00000000..ff3a1b49 --- /dev/null +++ b/examples/chat/out/chatroom_service.go @@ -0,0 +1,104 @@ +package main + +import ( + "io" + "log" + "strings" + "sync" + + pb "chat/protobuf" +) + +type chatroomServiceImpl struct { + pb.UnimplementedChatroomService + clients map[string]pb.ChatroomService_ChatServer // key: roomId:sender + senderMap map[string]string // sender -> roomId + mu sync.RWMutex +} + +func NewChatroomService() *chatroomServiceImpl { + return &chatroomServiceImpl{ + clients: make(map[string]pb.ChatroomService_ChatServer), + senderMap: make(map[string]string), + } +} + +func (s *chatroomServiceImpl) Chat(stream pb.ChatroomService_ChatServer) error { + firstMsg, err := stream.Recv() + if err != nil { + log.Printf("初始化连接失败: %v", err) + return err + } + clientID := firstMsg.RoomId + ":" + firstMsg.Sender + + s.mu.Lock() + // ✅ 用户唯一性检查 + if oldRoom, exists := s.senderMap[firstMsg.Sender]; exists { + s.mu.Unlock() + log.Printf("用户 %s 已在房间 %s 中活跃,拒绝重复加入", firstMsg.Sender, oldRoom) + _ = stream.Send(&pb.ChatroomMessage{ + RoomId: firstMsg.RoomId, + Sender: "系统", + Content: "你已在其他房间连接,请退出后再加入新房间", + }) + return nil + } + + // 注册 + s.clients[clientID] = stream + s.senderMap[firstMsg.Sender] = firstMsg.RoomId + s.mu.Unlock() + + log.Printf("%s 加入了房间 %s", firstMsg.Sender, firstMsg.RoomId) + + s.broadcast(firstMsg.RoomId, &pb.ChatroomMessage{ + RoomId: firstMsg.RoomId, + Sender: "系统", + Content: firstMsg.Sender + " 加入了聊天室", + }, clientID) + + // 退出处理 + defer func() { + s.mu.Lock() + delete(s.clients, clientID) + delete(s.senderMap, firstMsg.Sender) + s.mu.Unlock() + + log.Printf("%s 离开了房间 %s", firstMsg.Sender, firstMsg.RoomId) + s.broadcast(firstMsg.RoomId, &pb.ChatroomMessage{ + RoomId: firstMsg.RoomId, + Sender: "系统", + Content: firstMsg.Sender + " 离开了聊天室", + }, clientID) + }() + + for { + msg, err := stream.Recv() + if err != nil { + if err == io.EOF { + log.Printf("客户端 %s 主动关闭连接", clientID) + } else { + log.Printf("接收消息失败 (%s): %v", clientID, err) + } + return err + } + log.Printf("[%s] %s", msg.Sender, msg.Content) + s.broadcast(firstMsg.RoomId, msg, clientID) + } +} + +func (s *chatroomServiceImpl) broadcast(roomID string, msg *pb.ChatroomMessage, excludeID string) { + s.mu.RLock() + defer s.mu.RUnlock() + + for id, client := range s.clients { + if id == excludeID { + continue + } + if strings.HasPrefix(id, roomID+":") { + if err := client.Send(msg); err != nil { + log.Printf("广播失败 [%s]: %v", id, err) + } + } + } +} diff --git a/examples/chat/out/cmd/client/main.go b/examples/chat/out/cmd/client/main.go new file mode 100644 index 00000000..9c8a4ae5 --- /dev/null +++ b/examples/chat/out/cmd/client/main.go @@ -0,0 +1,103 @@ +package main + +import ( + "bufio" + "context" + "flag" + "fmt" + "io" + "os" + "os/signal" + "strings" + "syscall" + "trpc.group/trpc-go/trpc-go/client" + "trpc.group/trpc-go/trpc-go/log" + + pb "chat/protobuf" + _ "trpc.group/trpc-go/trpc-filter/debuglog" +) + +func main() { + roomID := flag.String("room", "default", "聊天室ID") + sender := flag.String("name", "anonymous", "用户名") + target := flag.String("target", "ip://127.0.0.1:8000", "服务地址") + flag.Parse() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + cli := pb.NewChatroomServiceClientProxy(client.WithTarget(*target)) + stream, err := cli.Chat(ctx) + if err != nil { + log.Fatalf("连接聊天室失败: %v", err) + } + + // 发送初始化消息 + initMsg := &pb.ChatroomMessage{ + RoomId: *roomID, + Sender: *sender, + Content: "加入聊天室", + } + if err := stream.Send(initMsg); err != nil { + log.Fatalf("发送初始消息失败: %v", err) + } + + // 接收消息协程 + go func() { + for { + msg, err := stream.Recv() + if err != nil { + if err == io.EOF { + log.Infof("服务器关闭了连接") + } else { + log.Infof("接收消息失败: %v", err) + } + cancel() + return + } + + // 特别提示被拒绝加入房间 + if msg.Sender == "系统" && strings.Contains(msg.Content, "已在其他房间连接") { + fmt.Printf("[系统] %s\n", msg.Content) + cancel() + os.Exit(0) + } + + fmt.Printf("[%s] %s\n", msg.Sender, msg.Content) + } + }() + + // 捕获退出信号 + go func() { + sigch := make(chan os.Signal, 1) + signal.Notify(sigch, syscall.SIGINT, syscall.SIGTERM) + <-sigch + fmt.Println("\n已收到退出信号,正在退出...") + _ = stream.CloseSend() + cancel() + os.Exit(0) + }() + + // 控制台输入循环 + fmt.Println("已加入聊天室,输入消息发送(Ctrl+C退出):") + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + text := strings.TrimSpace(scanner.Text()) + if text == "" { + continue + } + msg := &pb.ChatroomMessage{ + RoomId: *roomID, + Sender: *sender, + Content: text, + } + if err := stream.Send(msg); err != nil { + log.Infof("发送消息失败: %v", err) + break + } + } + + if err := scanner.Err(); err != nil { + log.Infof("读取输入失败: %v", err) + } +} diff --git a/examples/chat/out/go.mod b/examples/chat/out/go.mod new file mode 100644 index 00000000..5e32da99 --- /dev/null +++ b/examples/chat/out/go.mod @@ -0,0 +1,49 @@ +module chat + +go 1.24.4 + +replace chat/protobuf;chat => ./stub/chat/protobuf;chat + +replace chat/protobuf => ./stub/chat/protobuf + +require ( + chat/protobuf v0.0.0-00010101000000-000000000000 + trpc.group/trpc-go/trpc-filter/debuglog v1.0.0 + trpc.group/trpc-go/trpc-filter/recovery v1.0.0 + trpc.group/trpc-go/trpc-go v1.0.3 +) + +require ( + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/andybalholm/brotli v1.0.5 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-playground/form/v4 v4.2.0 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/flatbuffers v23.5.26+incompatible // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.16.7 // indirect + github.com/lestrrat-go/strftime v1.0.6 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/panjf2000/ants/v2 v2.8.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/spf13/cast v1.5.1 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.48.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/automaxprocs v1.5.3 // indirect + go.uber.org/mock v0.5.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.25.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + trpc.group/trpc-go/tnet v1.0.1 // indirect + trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0 // indirect +) diff --git a/examples/chat/out/go.sum b/examples/chat/out/go.sum new file mode 100644 index 00000000..6ef2780c --- /dev/null +++ b/examples/chat/out/go.sum @@ -0,0 +1,128 @@ +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/form/v4 v4.2.0 h1:N1wh+Goz61e6w66vo8vJkQt+uwZSoLz50kZPJWR8eic= +github.com/go-playground/form/v4 v4.2.0/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U= +github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/flatbuffers v23.5.26+incompatible h1:M9dgRyhJemaM4Sw8+66GHBu8ioaQmyPLg1b8VwK5WJg= +github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8= +github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= +github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ= +github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/panjf2000/ants/v2 v2.8.1 h1:C+n/f++aiW8kHCExKlpX6X+okmxKXP7DWLutxuAPuwQ= +github.com/panjf2000/ants/v2 v2.8.1/go.mod h1:KIBmYG9QQX5U2qzFP/yQJaq/nSb6rahS9iEHkrCMgM8= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.48.0 h1:oJWvHb9BIZToTQS3MuQ2R3bJZiNSa2KiNdeI8A+79Tc= +github.com/valyala/fasthttp v1.48.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= +go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= +go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +trpc.group/trpc-go/tnet v1.0.1 h1:Yzqyrgyfm+W742FzGr39c4+OeQmLi7PWotJxrOBtV9o= +trpc.group/trpc-go/tnet v1.0.1/go.mod h1:s/webUFYWEFBHErKyFmj7LYC7XfC2LTLCcwfSnJ04M0= +trpc.group/trpc-go/trpc-filter/debuglog v1.0.0 h1:mrMpdwfW9KdMOgD17oBGWd8aUpgxkizJQu3wGIZkMP0= +trpc.group/trpc-go/trpc-filter/debuglog v1.0.0/go.mod h1:KjJS8NHv2700k6B8a8h5dTJJYkXxrVZ9vCt2vIDexeY= +trpc.group/trpc-go/trpc-filter/recovery v1.0.0 h1:Mn3eaKxrtDt1Jqdmg6XsA4QMu5OkDTF63g3bNnGZkbM= +trpc.group/trpc-go/trpc-filter/recovery v1.0.0/go.mod h1:+G5aViMmmYLZ6mrqLAQnX4lqKFroNlu9Eb58l9DJAaA= +trpc.group/trpc-go/trpc-go v1.0.3 h1:X4RhPmJOkVoK6EGKoV241dvEpB6EagBeyu3ZrqkYZQY= +trpc.group/trpc-go/trpc-go v1.0.3/go.mod h1:82O+G2rD5ST+JAPuPPSqvsr6UI59UxV27iAILSkAIlQ= +trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0 h1:rMtHYzI0ElMJRxHtT5cD99SigFE6XzKK4PFtjcwokI0= +trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0/go.mod h1:K+a1K/Gnlcg9BFHWx30vLBIEDhxODhl25gi1JjA54CQ= diff --git a/examples/chat/out/main.go b/examples/chat/out/main.go new file mode 100644 index 00000000..54bf0f08 --- /dev/null +++ b/examples/chat/out/main.go @@ -0,0 +1,18 @@ +package main + +import ( + pb "chat/protobuf" + + _ "trpc.group/trpc-go/trpc-filter/debuglog" + _ "trpc.group/trpc-go/trpc-filter/recovery" + trpc "trpc.group/trpc-go/trpc-go" + "trpc.group/trpc-go/trpc-go/log" +) + +func main() { + s := trpc.NewServer() + pb.RegisterChatroomServiceService(s.Service("chat.ChatroomService"), NewChatroomService()) + if err := s.Serve(); err != nil { + log.Fatal(err) + } +} diff --git a/examples/chat/out/stub/chat/protobuf/chat.pb.go b/examples/chat/out/stub/chat/protobuf/chat.pb.go new file mode 100644 index 00000000..146d641a --- /dev/null +++ b/examples/chat/out/stub/chat/protobuf/chat.pb.go @@ -0,0 +1,145 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v3.21.12 +// source: protobuf/chat.proto + +package chat + +import ( + reflect "reflect" + sync "sync" + unsafe "unsafe" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ChatroomMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` // 聊天室的唯一标识 + Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"` // 消息发送者 + Content string `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"` // 消息内容 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatroomMessage) Reset() { + *x = ChatroomMessage{} + mi := &file_protobuf_chat_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatroomMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatroomMessage) ProtoMessage() {} + +func (x *ChatroomMessage) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_chat_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatroomMessage.ProtoReflect.Descriptor instead. +func (*ChatroomMessage) Descriptor() ([]byte, []int) { + return file_protobuf_chat_proto_rawDescGZIP(), []int{0} +} + +func (x *ChatroomMessage) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ChatroomMessage) GetSender() string { + if x != nil { + return x.Sender + } + return "" +} + +func (x *ChatroomMessage) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +var File_protobuf_chat_proto protoreflect.FileDescriptor + +const file_protobuf_chat_proto_rawDesc = "" + + "\n" + + "\x13protobuf/chat.proto\x12\x04chat\"\\\n" + + "\x0fChatroomMessage\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x16\n" + + "\x06sender\x18\x02 \x01(\tR\x06sender\x12\x18\n" + + "\acontent\x18\x03 \x01(\tR\acontent2K\n" + + "\x0fChatroomService\x128\n" + + "\x04Chat\x12\x15.chat.ChatroomMessage\x1a\x15.chat.ChatroomMessage(\x010\x01B\x14Z\x12chat/protobuf;chatb\x06proto3" + +var ( + file_protobuf_chat_proto_rawDescOnce sync.Once + file_protobuf_chat_proto_rawDescData []byte +) + +func file_protobuf_chat_proto_rawDescGZIP() []byte { + file_protobuf_chat_proto_rawDescOnce.Do(func() { + file_protobuf_chat_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_protobuf_chat_proto_rawDesc), len(file_protobuf_chat_proto_rawDesc))) + }) + return file_protobuf_chat_proto_rawDescData +} + +var file_protobuf_chat_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_protobuf_chat_proto_goTypes = []any{ + (*ChatroomMessage)(nil), // 0: chat.ChatroomMessage +} +var file_protobuf_chat_proto_depIdxs = []int32{ + 0, // 0: chat.ChatroomService.Chat:input_type -> chat.ChatroomMessage + 0, // 1: chat.ChatroomService.Chat:output_type -> chat.ChatroomMessage + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_protobuf_chat_proto_init() } +func file_protobuf_chat_proto_init() { + if File_protobuf_chat_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_protobuf_chat_proto_rawDesc), len(file_protobuf_chat_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_protobuf_chat_proto_goTypes, + DependencyIndexes: file_protobuf_chat_proto_depIdxs, + MessageInfos: file_protobuf_chat_proto_msgTypes, + }.Build() + File_protobuf_chat_proto = out.File + file_protobuf_chat_proto_goTypes = nil + file_protobuf_chat_proto_depIdxs = nil +} diff --git a/examples/chat/out/stub/chat/protobuf/chat.proto b/examples/chat/out/stub/chat/protobuf/chat.proto new file mode 100644 index 00000000..7867b3e2 --- /dev/null +++ b/examples/chat/out/stub/chat/protobuf/chat.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package chat; +option go_package = "chat/protobuf;chat"; + +message ChatroomMessage { + string room_id = 1; // 聊天室的唯一标识 + string sender = 2; // 消息发送者 + string content = 3; // 消息内容 +} + +service ChatroomService { + // 双向流式的聊天室通信方法 + rpc Chat(stream ChatroomMessage) returns (stream ChatroomMessage); +} diff --git a/examples/chat/out/stub/chat/protobuf/chat.trpc.go b/examples/chat/out/stub/chat/protobuf/chat.trpc.go new file mode 100644 index 00000000..35d8af0a --- /dev/null +++ b/examples/chat/out/stub/chat/protobuf/chat.trpc.go @@ -0,0 +1,156 @@ +// Code generated by trpc-go/trpc-cmdline v1.0.9. DO NOT EDIT. +// source: protobuf/chat.proto + +package chat + +import ( + "context" + "errors" + "fmt" + + _ "trpc.group/trpc-go/trpc-go" + "trpc.group/trpc-go/trpc-go/client" + "trpc.group/trpc-go/trpc-go/codec" + _ "trpc.group/trpc-go/trpc-go/http" + "trpc.group/trpc-go/trpc-go/server" + "trpc.group/trpc-go/trpc-go/stream" +) + +// START ======================================= Server Service Definition ======================================= START + +// ChatroomServiceService defines service. +type ChatroomServiceService interface { + // Chat 双向流式的聊天室通信方法 + Chat(ChatroomService_ChatServer) error +} + +func ChatroomServiceService_Chat_Handler(srv interface{}, stream server.Stream) error { + return srv.(ChatroomServiceService).Chat(&chatroomServiceChatServer{stream}) +} + +type ChatroomService_ChatServer interface { + Send(*ChatroomMessage) error + Recv() (*ChatroomMessage, error) + server.Stream +} + +type chatroomServiceChatServer struct { + server.Stream +} + +func (x *chatroomServiceChatServer) Send(m *ChatroomMessage) error { + return x.Stream.SendMsg(m) +} + +func (x *chatroomServiceChatServer) Recv() (*ChatroomMessage, error) { + m := new(ChatroomMessage) + if err := x.Stream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// ChatroomServiceServer_ServiceDesc descriptor for server.RegisterService. +var ChatroomServiceServer_ServiceDesc = server.ServiceDesc{ + ServiceName: "chat.ChatroomService", + HandlerType: ((*ChatroomServiceService)(nil)), + StreamHandle: stream.NewStreamDispatcher(), + Methods: []server.Method{}, + Streams: []server.StreamDesc{ + { + StreamName: "/chat.ChatroomService/Chat", + Handler: ChatroomServiceService_Chat_Handler, + ServerStreams: true, + }, + }, +} + +// RegisterChatroomServiceService registers service. +func RegisterChatroomServiceService(s server.Service, svr ChatroomServiceService) { + if err := s.Register(&ChatroomServiceServer_ServiceDesc, svr); err != nil { + panic(fmt.Sprintf("ChatroomService register error:%v", err)) + } +} + +// START --------------------------------- Default Unimplemented Server Service --------------------------------- START + +type UnimplementedChatroomService struct{} + +// Chat 双向流式的聊天室通信方法 +func (s *UnimplementedChatroomService) Chat(stream ChatroomService_ChatServer) error { + return errors.New("rpc Chat of service ChatroomService is not implemented") +} + +// END --------------------------------- Default Unimplemented Server Service --------------------------------- END + +// END ======================================= Server Service Definition ======================================= END + +// START ======================================= Client Service Definition ======================================= START + +// ChatroomServiceClientProxy defines service client proxy +type ChatroomServiceClientProxy interface { + // Chat 双向流式的聊天室通信方法 + Chat(ctx context.Context, opts ...client.Option) (ChatroomService_ChatClient, error) +} + +type ChatroomServiceClientProxyImpl struct { + client client.Client + streamClient stream.Client + opts []client.Option +} + +var NewChatroomServiceClientProxy = func(opts ...client.Option) ChatroomServiceClientProxy { + return &ChatroomServiceClientProxyImpl{client: client.DefaultClient, streamClient: stream.DefaultStreamClient, opts: opts} +} + +func (c *ChatroomServiceClientProxyImpl) Chat(ctx context.Context, opts ...client.Option) (ChatroomService_ChatClient, error) { + ctx, msg := codec.WithCloneMessage(ctx) + + msg.WithClientRPCName("/chat.ChatroomService/Chat") + msg.WithCalleeServiceName(ChatroomServiceServer_ServiceDesc.ServiceName) + msg.WithCalleeApp("") + msg.WithCalleeServer("") + msg.WithCalleeService("ChatroomService") + msg.WithCalleeMethod("Chat") + msg.WithSerializationType(codec.SerializationTypePB) + + clientStreamDesc := &client.ClientStreamDesc{} + clientStreamDesc.StreamName = "/chat.ChatroomService/Chat" + clientStreamDesc.ClientStreams = true + clientStreamDesc.ServerStreams = true + + callopts := make([]client.Option, 0, len(c.opts)+len(opts)) + callopts = append(callopts, c.opts...) + callopts = append(callopts, opts...) + + stream, err := c.streamClient.NewStream(ctx, clientStreamDesc, "/chat.ChatroomService/Chat", callopts...) + if err != nil { + return nil, err + } + x := &chatroomServiceChatClient{stream} + return x, nil +} + +type ChatroomService_ChatClient interface { + Send(*ChatroomMessage) error + Recv() (*ChatroomMessage, error) + client.ClientStream +} + +type chatroomServiceChatClient struct { + client.ClientStream +} + +func (x *chatroomServiceChatClient) Send(m *ChatroomMessage) error { + return x.ClientStream.SendMsg(m) +} + +func (x *chatroomServiceChatClient) Recv() (*ChatroomMessage, error) { + m := new(ChatroomMessage) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// END ======================================= Client Service Definition ======================================= END diff --git a/examples/chat/out/stub/chat/protobuf/chat_mock.go b/examples/chat/out/stub/chat/protobuf/chat_mock.go new file mode 100644 index 00000000..02b6f955 --- /dev/null +++ b/examples/chat/out/stub/chat/protobuf/chat_mock.go @@ -0,0 +1,320 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: stub/chat/protobuf/chat.trpc.go +// +// Generated by this command: +// +// mockgen -destination=stub/chat/protobuf/chat_mock.go -package=chat -self_package=chat/protobuf --source=stub/chat/protobuf/chat.trpc.go +// + +// Package chat is a generated GoMock package. +package chat + +import ( + context "context" + reflect "reflect" + + gomock "go.uber.org/mock/gomock" + client "trpc.group/trpc-go/trpc-go/client" +) + +// MockChatroomServiceService is a mock of ChatroomServiceService interface. +type MockChatroomServiceService struct { + ctrl *gomock.Controller + recorder *MockChatroomServiceServiceMockRecorder +} + +// MockChatroomServiceServiceMockRecorder is the mock recorder for MockChatroomServiceService. +type MockChatroomServiceServiceMockRecorder struct { + mock *MockChatroomServiceService +} + +// NewMockChatroomServiceService creates a new mock instance. +func NewMockChatroomServiceService(ctrl *gomock.Controller) *MockChatroomServiceService { + mock := &MockChatroomServiceService{ctrl: ctrl} + mock.recorder = &MockChatroomServiceServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockChatroomServiceService) EXPECT() *MockChatroomServiceServiceMockRecorder { + return m.recorder +} + +// ISGOMOCK indicates that this struct is a gomock mock. +func (m *MockChatroomServiceService) ISGOMOCK() struct{} { + return struct{}{} +} + +// Chat mocks base method. +func (m *MockChatroomServiceService) Chat(arg0 ChatroomService_ChatServer) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Chat", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Chat indicates an expected call of Chat. +func (mr *MockChatroomServiceServiceMockRecorder) Chat(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Chat", reflect.TypeOf((*MockChatroomServiceService)(nil).Chat), arg0) +} + +// MockChatroomService_ChatServer is a mock of ChatroomService_ChatServer interface. +type MockChatroomService_ChatServer struct { + ctrl *gomock.Controller + recorder *MockChatroomService_ChatServerMockRecorder +} + +// MockChatroomService_ChatServerMockRecorder is the mock recorder for MockChatroomService_ChatServer. +type MockChatroomService_ChatServerMockRecorder struct { + mock *MockChatroomService_ChatServer +} + +// NewMockChatroomService_ChatServer creates a new mock instance. +func NewMockChatroomService_ChatServer(ctrl *gomock.Controller) *MockChatroomService_ChatServer { + mock := &MockChatroomService_ChatServer{ctrl: ctrl} + mock.recorder = &MockChatroomService_ChatServerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockChatroomService_ChatServer) EXPECT() *MockChatroomService_ChatServerMockRecorder { + return m.recorder +} + +// ISGOMOCK indicates that this struct is a gomock mock. +func (m *MockChatroomService_ChatServer) ISGOMOCK() struct{} { + return struct{}{} +} + +// Context mocks base method. +func (m *MockChatroomService_ChatServer) Context() context.Context { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Context") + ret0, _ := ret[0].(context.Context) + return ret0 +} + +// Context indicates an expected call of Context. +func (mr *MockChatroomService_ChatServerMockRecorder) Context() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockChatroomService_ChatServer)(nil).Context)) +} + +// Recv mocks base method. +func (m *MockChatroomService_ChatServer) Recv() (*ChatroomMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Recv") + ret0, _ := ret[0].(*ChatroomMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Recv indicates an expected call of Recv. +func (mr *MockChatroomService_ChatServerMockRecorder) Recv() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockChatroomService_ChatServer)(nil).Recv)) +} + +// RecvMsg mocks base method. +func (m_2 *MockChatroomService_ChatServer) RecvMsg(m any) error { + m_2.ctrl.T.Helper() + ret := m_2.ctrl.Call(m_2, "RecvMsg", m) + ret0, _ := ret[0].(error) + return ret0 +} + +// RecvMsg indicates an expected call of RecvMsg. +func (mr *MockChatroomService_ChatServerMockRecorder) RecvMsg(m any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockChatroomService_ChatServer)(nil).RecvMsg), m) +} + +// Send mocks base method. +func (m *MockChatroomService_ChatServer) Send(arg0 *ChatroomMessage) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Send", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Send indicates an expected call of Send. +func (mr *MockChatroomService_ChatServerMockRecorder) Send(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockChatroomService_ChatServer)(nil).Send), arg0) +} + +// SendMsg mocks base method. +func (m_2 *MockChatroomService_ChatServer) SendMsg(m any) error { + m_2.ctrl.T.Helper() + ret := m_2.ctrl.Call(m_2, "SendMsg", m) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendMsg indicates an expected call of SendMsg. +func (mr *MockChatroomService_ChatServerMockRecorder) SendMsg(m any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockChatroomService_ChatServer)(nil).SendMsg), m) +} + +// MockChatroomServiceClientProxy is a mock of ChatroomServiceClientProxy interface. +type MockChatroomServiceClientProxy struct { + ctrl *gomock.Controller + recorder *MockChatroomServiceClientProxyMockRecorder +} + +// MockChatroomServiceClientProxyMockRecorder is the mock recorder for MockChatroomServiceClientProxy. +type MockChatroomServiceClientProxyMockRecorder struct { + mock *MockChatroomServiceClientProxy +} + +// NewMockChatroomServiceClientProxy creates a new mock instance. +func NewMockChatroomServiceClientProxy(ctrl *gomock.Controller) *MockChatroomServiceClientProxy { + mock := &MockChatroomServiceClientProxy{ctrl: ctrl} + mock.recorder = &MockChatroomServiceClientProxyMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockChatroomServiceClientProxy) EXPECT() *MockChatroomServiceClientProxyMockRecorder { + return m.recorder +} + +// ISGOMOCK indicates that this struct is a gomock mock. +func (m *MockChatroomServiceClientProxy) ISGOMOCK() struct{} { + return struct{}{} +} + +// Chat mocks base method. +func (m *MockChatroomServiceClientProxy) Chat(ctx context.Context, opts ...client.Option) (ChatroomService_ChatClient, error) { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Chat", varargs...) + ret0, _ := ret[0].(ChatroomService_ChatClient) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Chat indicates an expected call of Chat. +func (mr *MockChatroomServiceClientProxyMockRecorder) Chat(ctx any, opts ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Chat", reflect.TypeOf((*MockChatroomServiceClientProxy)(nil).Chat), varargs...) +} + +// MockChatroomService_ChatClient is a mock of ChatroomService_ChatClient interface. +type MockChatroomService_ChatClient struct { + ctrl *gomock.Controller + recorder *MockChatroomService_ChatClientMockRecorder +} + +// MockChatroomService_ChatClientMockRecorder is the mock recorder for MockChatroomService_ChatClient. +type MockChatroomService_ChatClientMockRecorder struct { + mock *MockChatroomService_ChatClient +} + +// NewMockChatroomService_ChatClient creates a new mock instance. +func NewMockChatroomService_ChatClient(ctrl *gomock.Controller) *MockChatroomService_ChatClient { + mock := &MockChatroomService_ChatClient{ctrl: ctrl} + mock.recorder = &MockChatroomService_ChatClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockChatroomService_ChatClient) EXPECT() *MockChatroomService_ChatClientMockRecorder { + return m.recorder +} + +// ISGOMOCK indicates that this struct is a gomock mock. +func (m *MockChatroomService_ChatClient) ISGOMOCK() struct{} { + return struct{}{} +} + +// CloseSend mocks base method. +func (m *MockChatroomService_ChatClient) CloseSend() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CloseSend") + ret0, _ := ret[0].(error) + return ret0 +} + +// CloseSend indicates an expected call of CloseSend. +func (mr *MockChatroomService_ChatClientMockRecorder) CloseSend() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockChatroomService_ChatClient)(nil).CloseSend)) +} + +// Context mocks base method. +func (m *MockChatroomService_ChatClient) Context() context.Context { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Context") + ret0, _ := ret[0].(context.Context) + return ret0 +} + +// Context indicates an expected call of Context. +func (mr *MockChatroomService_ChatClientMockRecorder) Context() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockChatroomService_ChatClient)(nil).Context)) +} + +// Recv mocks base method. +func (m *MockChatroomService_ChatClient) Recv() (*ChatroomMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Recv") + ret0, _ := ret[0].(*ChatroomMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Recv indicates an expected call of Recv. +func (mr *MockChatroomService_ChatClientMockRecorder) Recv() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockChatroomService_ChatClient)(nil).Recv)) +} + +// RecvMsg mocks base method. +func (m_2 *MockChatroomService_ChatClient) RecvMsg(m any) error { + m_2.ctrl.T.Helper() + ret := m_2.ctrl.Call(m_2, "RecvMsg", m) + ret0, _ := ret[0].(error) + return ret0 +} + +// RecvMsg indicates an expected call of RecvMsg. +func (mr *MockChatroomService_ChatClientMockRecorder) RecvMsg(m any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockChatroomService_ChatClient)(nil).RecvMsg), m) +} + +// Send mocks base method. +func (m *MockChatroomService_ChatClient) Send(arg0 *ChatroomMessage) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Send", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Send indicates an expected call of Send. +func (mr *MockChatroomService_ChatClientMockRecorder) Send(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockChatroomService_ChatClient)(nil).Send), arg0) +} + +// SendMsg mocks base method. +func (m_2 *MockChatroomService_ChatClient) SendMsg(m any) error { + m_2.ctrl.T.Helper() + ret := m_2.ctrl.Call(m_2, "SendMsg", m) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendMsg indicates an expected call of SendMsg. +func (mr *MockChatroomService_ChatClientMockRecorder) SendMsg(m any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockChatroomService_ChatClient)(nil).SendMsg), m) +} diff --git a/examples/chat/out/stub/chat/protobuf/go.mod b/examples/chat/out/stub/chat/protobuf/go.mod new file mode 100644 index 00000000..ec3a38be --- /dev/null +++ b/examples/chat/out/stub/chat/protobuf/go.mod @@ -0,0 +1,42 @@ +module chat/protobuf + +go 1.24.4 + +require ( + go.uber.org/mock v0.5.2 + google.golang.org/protobuf v1.36.6 + trpc.group/trpc-go/trpc-go v1.0.3 +) + +require ( + github.com/BurntSushi/toml v0.3.1 // indirect + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/go-playground/form/v4 v4.2.0 // indirect + github.com/golang/snappy v0.0.3 // indirect + github.com/google/flatbuffers v2.0.0+incompatible // indirect + github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.15.9 // indirect + github.com/lestrrat-go/strftime v1.0.6 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/panjf2000/ants/v2 v2.4.6 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/spf13/cast v1.3.1 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.43.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/automaxprocs v1.3.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + trpc.group/trpc-go/tnet v1.0.1 // indirect + trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0 // indirect +) diff --git a/examples/chat/out/stub/chat/protobuf/go.sum b/examples/chat/out/stub/chat/protobuf/go.sum new file mode 100644 index 00000000..da17164b --- /dev/null +++ b/examples/chat/out/stub/chat/protobuf/go.sum @@ -0,0 +1,139 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/form/v4 v4.2.0 h1:N1wh+Goz61e6w66vo8vJkQt+uwZSoLz50kZPJWR8eic= +github.com/go-playground/form/v4 v4.2.0/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U= +github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/flatbuffers v2.0.0+incompatible h1:dicJ2oXwypfwUGnB2/TYWYEKiuk9eYQlQO/AnOHl5mI= +github.com/google/flatbuffers v2.0.0+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8= +github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= +github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ= +github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/panjf2000/ants/v2 v2.4.6 h1:drmj9mcygn2gawZ155dRbo+NfXEfAssjZNU1qoIb4gQ= +github.com/panjf2000/ants/v2 v2.4.6/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.43.0 h1:Gy4sb32C98fbzVWZlTM1oTMdLWGyvxR03VhM6cBIU4g= +github.com/valyala/fasthttp v1.43.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/automaxprocs v1.3.0 h1:II28aZoGdaglS5vVNnspf28lnZpXScxtIozx1lAjdb0= +go.uber.org/automaxprocs v1.3.0/go.mod h1:9CWT6lKIep8U41DDaPiH6eFscnTyjfTANNQNx6LrIcA= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= +go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +trpc.group/trpc-go/tnet v1.0.1 h1:Yzqyrgyfm+W742FzGr39c4+OeQmLi7PWotJxrOBtV9o= +trpc.group/trpc-go/tnet v1.0.1/go.mod h1:s/webUFYWEFBHErKyFmj7LYC7XfC2LTLCcwfSnJ04M0= +trpc.group/trpc-go/trpc-go v1.0.3 h1:X4RhPmJOkVoK6EGKoV241dvEpB6EagBeyu3ZrqkYZQY= +trpc.group/trpc-go/trpc-go v1.0.3/go.mod h1:82O+G2rD5ST+JAPuPPSqvsr6UI59UxV27iAILSkAIlQ= +trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0 h1:rMtHYzI0ElMJRxHtT5cD99SigFE6XzKK4PFtjcwokI0= +trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0/go.mod h1:K+a1K/Gnlcg9BFHWx30vLBIEDhxODhl25gi1JjA54CQ= diff --git a/examples/chat/out/trpc.log b/examples/chat/out/trpc.log new file mode 100644 index 00000000..b235f144 --- /dev/null +++ b/examples/chat/out/trpc.log @@ -0,0 +1,29 @@ +2025-07-23 10:38:30.645 INFO client/client_linux.go:35 client chat.ChatroomService is empowered with tnet! 🤩 +2025-07-23 10:38:30.646 INFO client/client_linux.go:35 client is empowered with tnet! 🤩 +2025-07-23 10:38:30.646 INFO server/service_linux.go:21 service chat.ChatroomService with network tcp and protocol trpc is empowered with tnet! 🤩 you can set 'transport: go-net' in your trpc_go.yaml's service configuration to switch to the golang net framework +2025-07-23 10:38:30.646 INFO tnet/server_transport.go:66 service:chat.ChatroomService is using tnet transport, current number of pollers: 1 +2025-07-23 10:38:30.646 INFO server/service.go:168 process:349337, trpc service:chat.ChatroomService launch success, tcp:127.0.0.1:8000, serving ... +2025-07-23 10:40:34.142 INFO client/client_linux.go:35 client chat.ChatroomService is empowered with tnet! 🤩 +2025-07-23 10:40:34.142 INFO client/client_linux.go:35 client is empowered with tnet! 🤩 +2025-07-23 10:40:34.143 INFO server/service_linux.go:21 service chat.ChatroomService with network tcp and protocol trpc is empowered with tnet! 🤩 you can set 'transport: go-net' in your trpc_go.yaml's service configuration to switch to the golang net framework +2025-07-23 10:40:34.143 INFO tnet/server_transport.go:66 service:chat.ChatroomService is using tnet transport, current number of pollers: 1 +2025-07-23 10:40:34.143 INFO server/service.go:168 process:350955, trpc service:chat.ChatroomService launch success, tcp:127.0.0.1:8000, serving ... +2025-07-23 10:41:41.710 INFO server/service.go:527 process:350955, trpc service:chat.ChatroomService, closing ... +2025-07-23 10:41:41.710 INFO server/service.go:554 process:350955, trpc service:chat.ChatroomService, closed +2025-07-23 10:41:41.710 INFO admin/admin.go:192 process:350955, admin server, closed +2025-07-23 21:30:00.466 INFO client/client_linux.go:35 client chat.ChatroomService is empowered with tnet! 🤩 +2025-07-23 21:30:00.466 INFO client/client_linux.go:35 client is empowered with tnet! 🤩 +2025-07-23 21:30:00.466 INFO server/service_linux.go:21 service chat.ChatroomService with network tcp and protocol trpc is empowered with tnet! 🤩 you can set 'transport: go-net' in your trpc_go.yaml's service configuration to switch to the golang net framework +2025-07-23 21:30:00.466 INFO tnet/server_transport.go:66 service:chat.ChatroomService is using tnet transport, current number of pollers: 1 +2025-07-23 21:30:00.466 INFO server/service.go:168 process:261444, trpc service:chat.ChatroomService launch success, tcp:127.0.0.1:8000, serving ... +2025-07-23 21:31:32.620 INFO server/service.go:527 process:261444, trpc service:chat.ChatroomService, closing ... +2025-07-23 21:31:32.620 INFO server/service.go:554 process:261444, trpc service:chat.ChatroomService, closed +2025-07-23 21:31:32.620 INFO admin/admin.go:192 process:261444, admin server, closed +2025-07-24 11:08:51.718 INFO client/client_linux.go:35 client chat.ChatroomService is empowered with tnet! 🤩 +2025-07-24 11:08:51.718 INFO client/client_linux.go:35 client is empowered with tnet! 🤩 +2025-07-24 11:08:51.718 INFO server/service_linux.go:21 service chat.ChatroomService with network tcp and protocol trpc is empowered with tnet! 🤩 you can set 'transport: go-net' in your trpc_go.yaml's service configuration to switch to the golang net framework +2025-07-24 11:08:51.718 INFO tnet/server_transport.go:66 service:chat.ChatroomService is using tnet transport, current number of pollers: 1 +2025-07-24 11:08:51.718 INFO server/service.go:168 process:622089, trpc service:chat.ChatroomService launch success, tcp:127.0.0.1:8000, serving ... +2025-07-24 11:10:25.463 INFO admin/admin.go:192 process:622089, admin server, closed +2025-07-24 11:10:25.463 INFO server/service.go:527 process:622089, trpc service:chat.ChatroomService, closing ... +2025-07-24 11:10:25.463 INFO server/service.go:554 process:622089, trpc service:chat.ChatroomService, closed diff --git a/examples/chat/out/trpc_go.yaml b/examples/chat/out/trpc_go.yaml new file mode 100644 index 00000000..e1b0f7c0 --- /dev/null +++ b/examples/chat/out/trpc_go.yaml @@ -0,0 +1,49 @@ +global: # Global configuration. + namespace: Development # Environment type, either Production or Development. + env_name: test # Environment name for non-production environments. + +server: # Server configuration. + app: chat # Application name for the business. + server: ChatroomService # Process server name. + bin_path: /usr/local/trpc/bin/ # Path to binary executable files and framework configuration files. + conf_path: /usr/local/trpc/conf/ # Path to business configuration files. + data_path: /usr/local/trpc/data/ # Path to business data files. + filter: # List of interceptors for all service handler functions. + - simpledebuglog + - recovery # Intercept panics from business processing goroutines created by the framework. + service: # Services provided by the business, can have multiple. + - name: chat.ChatroomService # Route name for the service. + ip: 127.0.0.1 # Service listening IP address, can use placeholder ${ip}. Use either ip or nic, ip takes priority. + # nic: eth0 + port: 8000 # Service listening port, can use placeholder ${port}. + network: tcp # Network listening type: tcp or udp. + protocol: trpc # Application layer protocol: trpc or http. + timeout: 1000 # Maximum processing time for requests in milliseconds. + +client: # Backend configuration for client calls. + timeout: 1000 # Maximum processing time for all backends. + namespace: Development # Environment for all backends. + filter: # List of interceptors for all backend function calls. + - simpledebuglog + service: # Configuration for individual backends. + - name: chat.ChatroomService # Service name for the backend. + namespace: Development # Environment for the backend. + network: tcp # Network type for the backend: tcp or udp (configuration takes priority). + protocol: trpc # Application layer protocol: trpc or http. + target: ip://127.0.0.1:8000 # Service address for requests. + timeout: 1000 # Maximum processing time for requests. + + +plugins: # Plugin configuration. + log: # Log configuration. + default: # Default log configuration, supports multiple outputs. + - writer: console # Console standard output (default). + level: debug # Log level for standard output. + - writer: file # Local file log. + level: info # Log level for local file rolling logs. + writer_config: + filename: ./trpc.log # Path to store local file rolling logs. + max_size: 10 # Maximum size of local file rolling logs in MB. + max_backups: 10 # Maximum number of log files. + max_age: 7 # Maximum number of days to keep logs. + compress: false # Whether to compress log files. diff --git a/examples/chat/protobuf/chat.proto b/examples/chat/protobuf/chat.proto new file mode 100644 index 00000000..7867b3e2 --- /dev/null +++ b/examples/chat/protobuf/chat.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package chat; +option go_package = "chat/protobuf;chat"; + +message ChatroomMessage { + string room_id = 1; // 聊天室的唯一标识 + string sender = 2; // 消息发送者 + string content = 3; // 消息内容 +} + +service ChatroomService { + // 双向流式的聊天室通信方法 + rpc Chat(stream ChatroomMessage) returns (stream ChatroomMessage); +} From b80692b88d39cb737aaae2f7918c66bbdaa3ffbf Mon Sep 17 00:00:00 2001 From: hechenghao Date: Thu, 24 Jul 2025 14:23:55 +0800 Subject: [PATCH 2/3] chore: remove .idea folder from repo --- .idea/.gitignore | 8 -------- .idea/golinter.xml | 7 ------- .idea/modules.xml | 8 -------- .idea/trpc-a2a-go.iml | 9 --------- .idea/vcs.xml | 6 ------ 5 files changed, 38 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/golinter.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/trpc-a2a-go.iml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b81..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/golinter.xml b/.idea/golinter.xml deleted file mode 100644 index 1ccf3ec6..00000000 --- a/.idea/golinter.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index f6e743a7..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/trpc-a2a-go.iml b/.idea/trpc-a2a-go.iml deleted file mode 100644 index 5e764c4f..00000000 --- a/.idea/trpc-a2a-go.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From ad1ba8dec037a2670ae8ffd924038084d5d78e87 Mon Sep 17 00:00:00 2001 From: hechenghao Date: Mon, 28 Jul 2025 22:05:25 +0800 Subject: [PATCH 3/3] fix --- examples/chat/README.md | 73 +++- examples/chat/client/main.go | 142 ++++++++ examples/chat/doc/README.md | 262 ++++++++------ examples/chat/go.mod | 29 ++ examples/chat/go.sum | 62 ++++ examples/chat/out/chatroom_service.go | 104 ------ examples/chat/out/cmd/client/main.go | 103 ------ examples/chat/out/go.mod | 49 --- examples/chat/out/go.sum | 128 ------- examples/chat/out/main.go | 18 - .../chat/out/stub/chat/protobuf/chat.pb.go | 145 -------- .../chat/out/stub/chat/protobuf/chat.proto | 15 - .../chat/out/stub/chat/protobuf/chat.trpc.go | 156 --------- .../chat/out/stub/chat/protobuf/chat_mock.go | 320 ------------------ examples/chat/out/stub/chat/protobuf/go.mod | 42 --- examples/chat/out/stub/chat/protobuf/go.sum | 139 -------- examples/chat/out/trpc.log | 29 -- examples/chat/out/trpc_go.yaml | 49 --- examples/chat/protobuf/chat.proto | 15 - examples/chat/server/main.go | 299 ++++++++++++++++ 20 files changed, 753 insertions(+), 1426 deletions(-) create mode 100644 examples/chat/client/main.go create mode 100644 examples/chat/go.mod create mode 100644 examples/chat/go.sum delete mode 100644 examples/chat/out/chatroom_service.go delete mode 100644 examples/chat/out/cmd/client/main.go delete mode 100644 examples/chat/out/go.mod delete mode 100644 examples/chat/out/go.sum delete mode 100644 examples/chat/out/main.go delete mode 100644 examples/chat/out/stub/chat/protobuf/chat.pb.go delete mode 100644 examples/chat/out/stub/chat/protobuf/chat.proto delete mode 100644 examples/chat/out/stub/chat/protobuf/chat.trpc.go delete mode 100644 examples/chat/out/stub/chat/protobuf/chat_mock.go delete mode 100644 examples/chat/out/stub/chat/protobuf/go.mod delete mode 100644 examples/chat/out/stub/chat/protobuf/go.sum delete mode 100644 examples/chat/out/trpc.log delete mode 100644 examples/chat/out/trpc_go.yaml delete mode 100644 examples/chat/protobuf/chat.proto create mode 100644 examples/chat/server/main.go diff --git a/examples/chat/README.md b/examples/chat/README.md index b42f5b7b..c4fe769b 100644 --- a/examples/chat/README.md +++ b/examples/chat/README.md @@ -1,23 +1,78 @@ ## 背景 -基于trpc实现一个简单的聊天室 + +基于 trpc-a2a-go 和 langchaingo 实现一个带 AI 机器人的简单聊天室。 ## 环境 -- os ubuntu24.04 -- go 1.24 -## 运行 +- OS: Ubuntu 24.04 +- Go: 1.24 及以上 +- 依赖:trpc-a2a-go、langchaingo、OpenAI API Key(如需 AI 机器人) + +## 功能细节 + +1. 每个聊天室有独立 ID,每个用户有独立 ID,一个用户不能重复进入同一个聊天室。 +2. 有人发消息会广播至所有人(包括自己)。 +3. 消息以 "@ai" 开头,则触发机器人回复。 +4. AI 机器人回复基于 langchaingo(OpenAI)。 + +## 目录结构 + +``` +examples/chat/ + ├── client/ + │ └── main.go # 聊天室命令行客户端 + └── server/ + └── main.go # 聊天室服务端(含 AI 机器人) +``` + +## 运行方式 + +### 1. 安装依赖 + +```shell +cd examples/chat +# 安装 trpc-a2a-go 及 langchaingo 依赖 +# (如未安装) +go mod tidy +``` + +### 2. 配置 OpenAI API Key(如需 AI 机器人) ```shell - cd example/chat/out +export OPENAI_API_KEY=sk-xxxxxx ``` -1. 启动服务端 +### 3. 启动服务端 + ```shell - go run . +cd server +# 默认监听 8080 端口 +go run . ``` -2. 启动客户端 + +### 4. 启动客户端 + ```shell - go run cmd/client/main.go --name="default" --room="anonymous" --target="ip://127.0.0.1:8000"" +cd ../client +# -room 指定聊天室ID,-user 指定用户名 +go run . -room=room1 -user=张三 +# 可多开终端模拟多用户 +go run . -room=room1 -user=李四 ``` +### 5. 聊天体验 + +- 输入内容直接发送消息。 +- 输入 `@ai 你好` 可触发 AI 机器人回复。 +- 所有用户实时收到群聊消息。 + +## 备注 + +- 支持流式消息推送。 +- 支持多聊天室并发。 +- 如需自定义端口、服务地址等,可用 `-host`、`-port` 参数。 +- 代码结构清晰,便于二次开发。 + +--- +如遇问题可参考 `examples/chat/server/main.go` 和 `examples/chat/client/main.go`,或 issue 反馈。 diff --git a/examples/chat/client/main.go b/examples/chat/client/main.go new file mode 100644 index 00000000..17833434 --- /dev/null +++ b/examples/chat/client/main.go @@ -0,0 +1,142 @@ +package main + +import ( + "context" + "flag" + "fmt" + "os" + "os/signal" + "strings" + "time" + + "github.com/google/uuid" + "trpc.group/trpc-go/trpc-a2a-go/client" + "trpc.group/trpc-go/trpc-a2a-go/log" + "trpc.group/trpc-go/trpc-a2a-go/protocol" +) + +func main() { + agentURL := flag.String("agent", "http://localhost:8080/", "Target A2A agent URL") + roomID := flag.String("room", "default", "Chat room ID") + userName := flag.String("user", "user", "Your name") + streaming := flag.Bool("streaming", true, "Use streaming mode") + flag.Parse() + + userID := uuid.New().String() + + a2aClient, err := client.NewA2AClient(*agentURL, client.WithTimeout(60*time.Second)) + if err != nil { + log.Fatalf("Failed to create A2A client: %v", err) + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // 捕获 Ctrl+C 退出 + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, os.Interrupt) + go func() { + <-sigChan + fmt.Println("\nExiting...") + cancel() + os.Exit(0) + }() + + fmt.Printf("Welcome %s! Room: %s\n", *userName, *roomID) + + // 启动流式接收 + go receiveStreaming(ctx, a2aClient, *roomID, userID, *userName) + + // 主循环发送消息 + for { + var input string + fmt.Print("> ") + if _, err := fmt.Scanln(&input); err != nil { + continue + } + sendMessage(ctx, a2aClient, *roomID, userID, *userName, input, *streaming) + } +} + +func sendMessage(ctx context.Context, a2aClient *client.A2AClient, roomID, userID, userName, msg string, streaming bool) { + userMsg := protocol.NewMessage( + protocol.MessageRoleUser, + []protocol.Part{protocol.NewTextPart(msg)}, + ) + userMsg.ContextID = &roomID // 作为room_id + userMsg.Metadata = map[string]interface{}{ + "user_id": userID, + "user_name": userName, + } + + params := protocol.SendMessageParams{ + Message: userMsg, + Configuration: &protocol.SendMessageConfiguration{ + Blocking: boolPtr(false), + }, + } + if !streaming { + result, err := a2aClient.SendMessage(ctx, params) + if err != nil { + log.Errorf("Send failed: %v", err) + return + } + if m, ok := result.Result.(*protocol.Message); ok { + printMessage(*m) + } + return + } + // 流式模式只需发送,接收由 receiveStreaming 负责 + _, err := a2aClient.SendMessage(ctx, params) + if err != nil { + log.Errorf("Send failed: %v", err) + } +} + +func receiveStreaming(ctx context.Context, a2aClient *client.A2AClient, roomID, userID, userName string) { + // 启动流式订阅 + userMsg := protocol.NewMessage( + protocol.MessageRoleUser, + []protocol.Part{protocol.NewTextPart(fmt.Sprintf("%s joined the chat.", userName))}, + ) + userMsg.ContextID = &roomID + userMsg.Metadata = map[string]interface{}{ + "user_id": userID, + "user_name": userName, + } + + params := protocol.SendMessageParams{ + Message: userMsg, + Configuration: &protocol.SendMessageConfiguration{ + Blocking: boolPtr(false), + }, + } + eventChan, err := a2aClient.StreamMessage(ctx, params) + if err != nil { + log.Fatalf("Failed to start streaming: %v", err) + } + for { + select { + case event, ok := <-eventChan: + if !ok { + log.Infof("Stream closed by server.") + return + } + if m, ok := event.Result.(*protocol.Message); ok { + printMessage(*m) + } + case <-ctx.Done(): + return + } + } +} + +func printMessage(message protocol.Message) { + for _, part := range message.Parts { + if textPart, ok := part.(*protocol.TextPart); ok { + fmt.Printf("\n%s\n> ", strings.TrimSpace(textPart.Text)) + } + } +} + +func boolPtr(b bool) *bool { return &b } diff --git a/examples/chat/doc/README.md b/examples/chat/doc/README.md index 80dc95bc..fb225eff 100644 --- a/examples/chat/doc/README.md +++ b/examples/chat/doc/README.md @@ -1,142 +1,194 @@ -# tRPC-A2A-Go 聊天室体验报告 +# tRPC-A2A-Go 开发体验报告 -## 一、体验背景 +## 一、体验场景构建 -本次体验基于 tRPC-A2A-Go 框架实现一个简单的聊天室功能,旨在熟悉 tRPC 框架的双向流式通信能力及 A2A(Application-to-Application)通信规范。通过实践了解 tRPC 在构建实时通信应用场景下的开发流程、接口设计及部署方式。 +本次体验基于 tRPC-A2A-Go 框架实现了一个带 AI 机器人的多用户聊天室系统,该系统具备以下核心功能: -## 二、环境准备 +1. 多聊天室并发支持,每个聊天室有独立 ID +2. 用户身份管理,同一用户不能重复进入同一聊天室 +3. 实时消息广播,所有用户可接收群内消息 +4. AI 机器人交互,通过 "@ai" 前缀触发机器人回复 +5. 支持流式消息推送,提升实时通信体验 -1. **基础环境** - - 操作系统:Ubuntu 24.04 - - Go 版本:1.24 - - tRPC 相关工具:trpc-cli +## 二、开发环境与依赖 -2. **依赖安装** - ```shell - # 安装 tRPC 代码生成工具 - go install trpc.group/trpc-go/trpc-cmdline/trpc@latest - ``` - -## 三、开发过程 +### 基础环境 +- 操作系统:Ubuntu 24.04 +- Go 版本:1.24+ +- 依赖管理:Go Modules -### 1. 协议设计(Protobuf) +### 核心依赖 +- trpc.group/trpc-go/trpc-a2a-go v0.2.2:提供 A2A 协议实现 +- github.com/tmc/langchaingo v0.1.13:AI 交互框架 +- github.com/google/uuid v1.6.0:用户 ID 生成 -根据聊天室场景需求,定义了 `ChatroomMessage` 消息结构和 `ChatroomService` 服务接口,使用 proto3 语法: +## 三、开发过程体验 -```protobuf -syntax = "proto3"; +### 1. 项目结构搭建 -package chat; -option go_package = "chat/protobuf;chat"; +按照 A2A 协议的客户端-服务端模型,设计了清晰的目录结构: -message ChatroomMessage { - string room_id = 1; // 聊天室的唯一标识 - string sender = 2; // 消息发送者 - string content = 3; // 消息内容 -} - -service ChatroomService { - // 双向流式的聊天室通信方法 - rpc Chat(stream ChatroomMessage) returns (stream ChatroomMessage); -} +``` +chat/ + ├── client/ # 聊天室客户端 + │ └── main.go + └── server/ # 聊天室服务端 + └── main.go + ├── go.mod # 依赖管理 + └── README.md # 使用说明 ``` -关键设计说明: -- 采用双向流式 RPC(`stream`)实现实时消息推送 -- 消息包含聊天室 ID、发送者和内容三个核心字段 -- 通过 `go_package` 指定生成代码的 Go 包路径 +### 2. 服务端开发 -### 2. 代码生成 +服务端核心实现了: +- 聊天室管理(创建、用户加入/退出) +- 消息广播机制 +- AI 机器人集成 +- A2A 协议适配 -使用 tRPC 工具根据 proto 文件生成基础代码: +关键代码片段解析: -```makefile -.PHONY: chat-proto -chat-proto: - trpc create -p protobuf/chat.proto -o out -``` +```go +// 聊天室管理实现 +type ChatRoomManager struct { + rooms map[string]*ChatRoom + mu sync.Mutex +} -执行生成命令: -```shell -make chat-proto +// 消息处理核心逻辑 +func (p *chatMessageProcessor) ProcessMessage( + ctx context.Context, + message protocol.Message, + options taskmanager.ProcessOptions, + handler taskmanager.TaskHandler, +) (*taskmanager.MessageProcessingResult, error) { + // 解析上下文获取房间ID和用户信息 + roomID, userID, userName := parseContext(message) + + // 获取或创建聊天室 + room := p.roomMgr.GetOrCreateRoom(roomID) + + // 添加用户到聊天室 + user := &User{ID: userID, Name: userName} + room.AddUser(user) + + // 广播消息 + room.Broadcast(message) + + // 处理AI请求 + if strings.HasPrefix(text, "@ai") { + // 异步调用AI并广播回复 + // ... + } +} ``` -生成结果:在 `out` 目录下自动创建了服务端和客户端的基础框架代码,包括: -- 服务接口定义 -- 消息编解码逻辑 -- 网络传输层封装 - -### 3. 业务逻辑实现 +### 3. 客户端开发 + +客户端主要实现: +- 连接服务端 +- 消息发送 +- 流式消息接收 +- 用户输入处理 + +关键代码片段解析: + +```go +// 发送消息实现 +func sendMessage(ctx context.Context, a2aClient *client.A2AClient, roomID, userID, userName, msg string, streaming bool) { + userMsg := protocol.NewMessage( + protocol.MessageRoleUser, + []protocol.Part{protocol.NewTextPart(msg)}, + ) + userMsg.ContextID = &roomID // 关联到聊天室 + userMsg.Metadata = map[string]interface{}{ + "user_id": userID, + "user_name": userName, + } + + // 发送消息 + _, err := a2aClient.SendMessage(ctx, params) + // ... +} -#### 服务端实现 -服务端需要维护聊天室会话,实现消息转发逻辑: -- 维护房间与连接的映射关系 -- 接收客户端消息并广播给同房间其他用户 -- 处理新用户加入和用户离开事件 +// 流式接收消息 +func receiveStreaming(ctx context.Context, a2aClient *client.A2AClient, roomID, userID, userName string) { + // 启动流式订阅 + eventChan, err := a2aClient.StreamMessage(ctx, params) + // 循环接收消息 + for { + select { + case event, ok := <-eventChan: + if m, ok := event.Result.(*protocol.Message); ok { + printMessage(*m) + } + case <-ctx.Done(): + return + } + } +} +``` -#### 客户端实现 -客户端实现用户交互和消息收发: -- 命令行参数解析(用户名、房间号、服务端地址) -- 从标准输入读取用户消息并发送 -- 监听服务端推送的消息并显示 +### 4. AI 集成 -### 4. 运行与测试 +通过 langchaingo 框架集成 OpenAI API: -1. 启动服务端 -```shell -cd example/chat/out -go run . +```go +func callAI(ctx context.Context, input string) (string, error) { + llm, err := openai.New() + if err != nil { + return "", err + } + resp, err := llm.Call(ctx, input) + return resp, err +} ``` -2. 启动多个客户端(新终端窗口) -```shell -# 客户端1 -go run cmd/client/main.go --name="Alice" --room="anonymous" --target="ip://127.0.0.1:8000" - -# 客户端2 -go run cmd/client/main.go --name="Bob" --room="anonymous" --target="ip://127.0.0.1:8000" -``` +## 四、功能测试与验证 -3. 功能测试 -- 发送消息:在任一客户端输入文本并回车,其他客户端可收到消息 -- 多房间隔离:不同房间的消息不会互相干扰 -- 身份标识:消息会显示发送者名称,区分不同用户 +### 1. 测试步骤 -## 四、A2A 特性体验 +1. 安装依赖:`go mod tidy` +2. 配置环境变量:`export OPENAI_API_KEY=sk-xxxxxx` +3. 启动服务端:`cd server && go run .` +4. 启动多个客户端: + ```bash + cd client && go run . -room=room1 -user=张三 + cd client && go run . -room=room1 -user=李四 + ``` -1. **双向流式通信** - 通过 tRPC 的流式 RPC 实现了全双工通信,客户端和服务端可随时发送消息,满足聊天室实时交互需求。 +### 2. 功能验证 -2. **服务发现与注册** - 体验了 tRPC 内置的服务发现机制,客户端通过 `target` 参数指定服务端地址即可建立连接。 +- **多用户聊天**:成功实现多用户消息实时广播 +- **聊天室隔离**:不同房间消息互不干扰 +- **AI 交互**:通过 "@ai 问题" 成功触发 AI 回复 +- **用户唯一性**:同一用户无法重复加入同一房间 +- **流式传输**:消息实时推送,无明显延迟 -3. **协议兼容性** - 基于 Protobuf 协议实现,具备良好的跨语言兼容性,可扩展支持多语言客户端接入。 +## 五、框架特性体验 -4. **错误处理** - 框架自动处理网络异常和连接断开情况,客户端断开后服务端会自动清理会话。 +### 1. tRPC-A2A-Go 优势 -## 五、问题与解决方案 +1. **协议封装完善**:提供了清晰的消息协议和交互模式,简化了客户端-服务端通信实现 +2. **流式支持良好**:内置的流式消息机制简化了实时通信开发 +3. **任务管理便捷**:TaskManager 组件简化了消息处理和状态管理 +4. **扩展性强**:易于集成第三方服务(如本次集成的 OpenAI) -1. **消息广播效率** - 问题:当房间用户较多时,消息广播可能出现延迟 - 解决方案:实现消息异步转发,使用缓冲通道减少阻塞 +### 2. 可改进点 -2. **客户端重连** - 问题:网络中断后客户端需要手动重启 - 解决方案:在客户端实现自动重连机制,检测连接状态并尝试重新连接 +1. 文档不够丰富,部分 API 需要结合源码理解 +2. 错误处理机制可以更完善 +3. 缺少内置的身份认证机制,需要自行实现 +4. 配置选项可以更灵活 -## 六、总结与展望 +## 六、总结与建议 -### 体验总结 -1. tRPC-A2A-Go 框架提供了简洁的接口定义和代码生成能力,大幅降低了实时通信应用的开发门槛 -2. 双向流式 RPC 机制非常适合聊天室这类需要持续交互的场景 -3. 完善的工具链支持(代码生成、构建部署)简化了开发流程 +tRPC-A2A-Go 框架为构建基于 A2A 协议的应用提供了良好的基础支持,尤其适合开发实时交互类应用。通过本次聊天室开发体验,框架的易用性和扩展性得到了验证。 -### 未来优化方向 -1. 增加用户认证机制,确保消息发送者身份合法性 -2. 实现消息持久化,支持历史消息查询 -3. 扩展支持文件传输、表情等富媒体消息 -4. 优化服务端架构,支持水平扩展以应对高并发场景 +建议: +1. 完善官方文档和示例 +2. 增加更多场景化的示例代码 +3. 提供更多内置中间件(如认证、日志等) +4. 优化错误提示和调试体验 -通过本次体验,深入了解了 tRPC-A2A-Go 在实时通信场景下的应用方式,框架的设计理念和易用性给人留下深刻印象,适合用于构建高性能的分布式应用。 \ No newline at end of file +总体而言,tRPC-A2A-Go 是一个有潜力的框架,适合用于构建分布式、实时交互的应用系统。 \ No newline at end of file diff --git a/examples/chat/go.mod b/examples/chat/go.mod new file mode 100644 index 00000000..6f626530 --- /dev/null +++ b/examples/chat/go.mod @@ -0,0 +1,29 @@ +module chat + +go 1.23.7 + +require ( + github.com/google/uuid v1.6.0 + github.com/tmc/langchaingo v0.1.13 + trpc.group/trpc-go/trpc-a2a-go v0.2.2 +) + +require ( + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect + github.com/dlclark/regexp2 v1.10.0 // indirect + github.com/goccy/go-json v0.10.3 // indirect + github.com/golang-jwt/jwt/v5 v5.2.2 // indirect + github.com/lestrrat-go/blackmagic v1.0.2 // indirect + github.com/lestrrat-go/httpcc v1.0.1 // indirect + github.com/lestrrat-go/httprc v1.0.6 // indirect + github.com/lestrrat-go/iter v1.0.2 // indirect + github.com/lestrrat-go/jwx/v2 v2.1.4 // indirect + github.com/lestrrat-go/option v1.0.1 // indirect + github.com/pkoukk/tiktoken-go v0.1.6 // indirect + github.com/segmentio/asm v1.2.0 // indirect + go.uber.org/multierr v1.10.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.35.0 // indirect + golang.org/x/oauth2 v0.29.0 // indirect + golang.org/x/sys v0.30.0 // indirect +) diff --git a/examples/chat/go.sum b/examples/chat/go.sum new file mode 100644 index 00000000..8c3d7ff5 --- /dev/null +++ b/examples/chat/go.sum @@ -0,0 +1,62 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= +github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= +github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= +github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= +github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= +github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= +github.com/lestrrat-go/httprc v1.0.6 h1:qgmgIRhpvBqexMJjA/PmwSvhNk679oqD1RbovdCGW8k= +github.com/lestrrat-go/httprc v1.0.6/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= +github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= +github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= +github.com/lestrrat-go/jwx/v2 v2.1.4 h1:uBCMmJX8oRZStmKuMMOFb0Yh9xmEMgNJLgjuKKt4/qc= +github.com/lestrrat-go/jwx/v2 v2.1.4/go.mod h1:nWRbDFR1ALG2Z6GJbBXzfQaYyvn751KuuyySN2yR6is= +github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= +github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw= +github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= +github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tmc/langchaingo v0.1.13 h1:rcpMWBIi2y3B90XxfE4Ao8dhCQPVDMaNPnN5cGB1CaA= +github.com/tmc/langchaingo v0.1.13/go.mod h1:vpQ5NOIhpzxDfTZK9B6tf2GM/MoaHewPWM5KXXGh7hg= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= +golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +trpc.group/trpc-go/trpc-a2a-go v0.2.2 h1:+KSxwAvZ3W2iWJR1HVAmgYlQyD4tOKfluFSEJ0bydgs= +trpc.group/trpc-go/trpc-a2a-go v0.2.2/go.mod h1:lu052zH/pTlTBwWMU/E3UckR0U9ajL1NlhiRkIF9R6A= diff --git a/examples/chat/out/chatroom_service.go b/examples/chat/out/chatroom_service.go deleted file mode 100644 index ff3a1b49..00000000 --- a/examples/chat/out/chatroom_service.go +++ /dev/null @@ -1,104 +0,0 @@ -package main - -import ( - "io" - "log" - "strings" - "sync" - - pb "chat/protobuf" -) - -type chatroomServiceImpl struct { - pb.UnimplementedChatroomService - clients map[string]pb.ChatroomService_ChatServer // key: roomId:sender - senderMap map[string]string // sender -> roomId - mu sync.RWMutex -} - -func NewChatroomService() *chatroomServiceImpl { - return &chatroomServiceImpl{ - clients: make(map[string]pb.ChatroomService_ChatServer), - senderMap: make(map[string]string), - } -} - -func (s *chatroomServiceImpl) Chat(stream pb.ChatroomService_ChatServer) error { - firstMsg, err := stream.Recv() - if err != nil { - log.Printf("初始化连接失败: %v", err) - return err - } - clientID := firstMsg.RoomId + ":" + firstMsg.Sender - - s.mu.Lock() - // ✅ 用户唯一性检查 - if oldRoom, exists := s.senderMap[firstMsg.Sender]; exists { - s.mu.Unlock() - log.Printf("用户 %s 已在房间 %s 中活跃,拒绝重复加入", firstMsg.Sender, oldRoom) - _ = stream.Send(&pb.ChatroomMessage{ - RoomId: firstMsg.RoomId, - Sender: "系统", - Content: "你已在其他房间连接,请退出后再加入新房间", - }) - return nil - } - - // 注册 - s.clients[clientID] = stream - s.senderMap[firstMsg.Sender] = firstMsg.RoomId - s.mu.Unlock() - - log.Printf("%s 加入了房间 %s", firstMsg.Sender, firstMsg.RoomId) - - s.broadcast(firstMsg.RoomId, &pb.ChatroomMessage{ - RoomId: firstMsg.RoomId, - Sender: "系统", - Content: firstMsg.Sender + " 加入了聊天室", - }, clientID) - - // 退出处理 - defer func() { - s.mu.Lock() - delete(s.clients, clientID) - delete(s.senderMap, firstMsg.Sender) - s.mu.Unlock() - - log.Printf("%s 离开了房间 %s", firstMsg.Sender, firstMsg.RoomId) - s.broadcast(firstMsg.RoomId, &pb.ChatroomMessage{ - RoomId: firstMsg.RoomId, - Sender: "系统", - Content: firstMsg.Sender + " 离开了聊天室", - }, clientID) - }() - - for { - msg, err := stream.Recv() - if err != nil { - if err == io.EOF { - log.Printf("客户端 %s 主动关闭连接", clientID) - } else { - log.Printf("接收消息失败 (%s): %v", clientID, err) - } - return err - } - log.Printf("[%s] %s", msg.Sender, msg.Content) - s.broadcast(firstMsg.RoomId, msg, clientID) - } -} - -func (s *chatroomServiceImpl) broadcast(roomID string, msg *pb.ChatroomMessage, excludeID string) { - s.mu.RLock() - defer s.mu.RUnlock() - - for id, client := range s.clients { - if id == excludeID { - continue - } - if strings.HasPrefix(id, roomID+":") { - if err := client.Send(msg); err != nil { - log.Printf("广播失败 [%s]: %v", id, err) - } - } - } -} diff --git a/examples/chat/out/cmd/client/main.go b/examples/chat/out/cmd/client/main.go deleted file mode 100644 index 9c8a4ae5..00000000 --- a/examples/chat/out/cmd/client/main.go +++ /dev/null @@ -1,103 +0,0 @@ -package main - -import ( - "bufio" - "context" - "flag" - "fmt" - "io" - "os" - "os/signal" - "strings" - "syscall" - "trpc.group/trpc-go/trpc-go/client" - "trpc.group/trpc-go/trpc-go/log" - - pb "chat/protobuf" - _ "trpc.group/trpc-go/trpc-filter/debuglog" -) - -func main() { - roomID := flag.String("room", "default", "聊天室ID") - sender := flag.String("name", "anonymous", "用户名") - target := flag.String("target", "ip://127.0.0.1:8000", "服务地址") - flag.Parse() - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - cli := pb.NewChatroomServiceClientProxy(client.WithTarget(*target)) - stream, err := cli.Chat(ctx) - if err != nil { - log.Fatalf("连接聊天室失败: %v", err) - } - - // 发送初始化消息 - initMsg := &pb.ChatroomMessage{ - RoomId: *roomID, - Sender: *sender, - Content: "加入聊天室", - } - if err := stream.Send(initMsg); err != nil { - log.Fatalf("发送初始消息失败: %v", err) - } - - // 接收消息协程 - go func() { - for { - msg, err := stream.Recv() - if err != nil { - if err == io.EOF { - log.Infof("服务器关闭了连接") - } else { - log.Infof("接收消息失败: %v", err) - } - cancel() - return - } - - // 特别提示被拒绝加入房间 - if msg.Sender == "系统" && strings.Contains(msg.Content, "已在其他房间连接") { - fmt.Printf("[系统] %s\n", msg.Content) - cancel() - os.Exit(0) - } - - fmt.Printf("[%s] %s\n", msg.Sender, msg.Content) - } - }() - - // 捕获退出信号 - go func() { - sigch := make(chan os.Signal, 1) - signal.Notify(sigch, syscall.SIGINT, syscall.SIGTERM) - <-sigch - fmt.Println("\n已收到退出信号,正在退出...") - _ = stream.CloseSend() - cancel() - os.Exit(0) - }() - - // 控制台输入循环 - fmt.Println("已加入聊天室,输入消息发送(Ctrl+C退出):") - scanner := bufio.NewScanner(os.Stdin) - for scanner.Scan() { - text := strings.TrimSpace(scanner.Text()) - if text == "" { - continue - } - msg := &pb.ChatroomMessage{ - RoomId: *roomID, - Sender: *sender, - Content: text, - } - if err := stream.Send(msg); err != nil { - log.Infof("发送消息失败: %v", err) - break - } - } - - if err := scanner.Err(); err != nil { - log.Infof("读取输入失败: %v", err) - } -} diff --git a/examples/chat/out/go.mod b/examples/chat/out/go.mod deleted file mode 100644 index 5e32da99..00000000 --- a/examples/chat/out/go.mod +++ /dev/null @@ -1,49 +0,0 @@ -module chat - -go 1.24.4 - -replace chat/protobuf;chat => ./stub/chat/protobuf;chat - -replace chat/protobuf => ./stub/chat/protobuf - -require ( - chat/protobuf v0.0.0-00010101000000-000000000000 - trpc.group/trpc-go/trpc-filter/debuglog v1.0.0 - trpc.group/trpc-go/trpc-filter/recovery v1.0.0 - trpc.group/trpc-go/trpc-go v1.0.3 -) - -require ( - github.com/BurntSushi/toml v1.3.2 // indirect - github.com/andybalholm/brotli v1.0.5 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-playground/form/v4 v4.2.0 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/google/flatbuffers v23.5.26+incompatible // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/lestrrat-go/strftime v1.0.6 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/panjf2000/ants/v2 v2.8.1 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/spf13/cast v1.5.1 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.48.0 // indirect - go.uber.org/atomic v1.11.0 // indirect - go.uber.org/automaxprocs v1.5.3 // indirect - go.uber.org/mock v0.5.2 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.25.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - trpc.group/trpc-go/tnet v1.0.1 // indirect - trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0 // indirect -) diff --git a/examples/chat/out/go.sum b/examples/chat/out/go.sum deleted file mode 100644 index 6ef2780c..00000000 --- a/examples/chat/out/go.sum +++ /dev/null @@ -1,128 +0,0 @@ -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= -github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/form/v4 v4.2.0 h1:N1wh+Goz61e6w66vo8vJkQt+uwZSoLz50kZPJWR8eic= -github.com/go-playground/form/v4 v4.2.0/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U= -github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/flatbuffers v23.5.26+incompatible h1:M9dgRyhJemaM4Sw8+66GHBu8ioaQmyPLg1b8VwK5WJg= -github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8= -github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= -github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ= -github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/panjf2000/ants/v2 v2.8.1 h1:C+n/f++aiW8kHCExKlpX6X+okmxKXP7DWLutxuAPuwQ= -github.com/panjf2000/ants/v2 v2.8.1/go.mod h1:KIBmYG9QQX5U2qzFP/yQJaq/nSb6rahS9iEHkrCMgM8= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= -github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.48.0 h1:oJWvHb9BIZToTQS3MuQ2R3bJZiNSa2KiNdeI8A+79Tc= -github.com/valyala/fasthttp v1.48.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= -go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= -go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -trpc.group/trpc-go/tnet v1.0.1 h1:Yzqyrgyfm+W742FzGr39c4+OeQmLi7PWotJxrOBtV9o= -trpc.group/trpc-go/tnet v1.0.1/go.mod h1:s/webUFYWEFBHErKyFmj7LYC7XfC2LTLCcwfSnJ04M0= -trpc.group/trpc-go/trpc-filter/debuglog v1.0.0 h1:mrMpdwfW9KdMOgD17oBGWd8aUpgxkizJQu3wGIZkMP0= -trpc.group/trpc-go/trpc-filter/debuglog v1.0.0/go.mod h1:KjJS8NHv2700k6B8a8h5dTJJYkXxrVZ9vCt2vIDexeY= -trpc.group/trpc-go/trpc-filter/recovery v1.0.0 h1:Mn3eaKxrtDt1Jqdmg6XsA4QMu5OkDTF63g3bNnGZkbM= -trpc.group/trpc-go/trpc-filter/recovery v1.0.0/go.mod h1:+G5aViMmmYLZ6mrqLAQnX4lqKFroNlu9Eb58l9DJAaA= -trpc.group/trpc-go/trpc-go v1.0.3 h1:X4RhPmJOkVoK6EGKoV241dvEpB6EagBeyu3ZrqkYZQY= -trpc.group/trpc-go/trpc-go v1.0.3/go.mod h1:82O+G2rD5ST+JAPuPPSqvsr6UI59UxV27iAILSkAIlQ= -trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0 h1:rMtHYzI0ElMJRxHtT5cD99SigFE6XzKK4PFtjcwokI0= -trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0/go.mod h1:K+a1K/Gnlcg9BFHWx30vLBIEDhxODhl25gi1JjA54CQ= diff --git a/examples/chat/out/main.go b/examples/chat/out/main.go deleted file mode 100644 index 54bf0f08..00000000 --- a/examples/chat/out/main.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import ( - pb "chat/protobuf" - - _ "trpc.group/trpc-go/trpc-filter/debuglog" - _ "trpc.group/trpc-go/trpc-filter/recovery" - trpc "trpc.group/trpc-go/trpc-go" - "trpc.group/trpc-go/trpc-go/log" -) - -func main() { - s := trpc.NewServer() - pb.RegisterChatroomServiceService(s.Service("chat.ChatroomService"), NewChatroomService()) - if err := s.Serve(); err != nil { - log.Fatal(err) - } -} diff --git a/examples/chat/out/stub/chat/protobuf/chat.pb.go b/examples/chat/out/stub/chat/protobuf/chat.pb.go deleted file mode 100644 index 146d641a..00000000 --- a/examples/chat/out/stub/chat/protobuf/chat.pb.go +++ /dev/null @@ -1,145 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.6 -// protoc v3.21.12 -// source: protobuf/chat.proto - -package chat - -import ( - reflect "reflect" - sync "sync" - unsafe "unsafe" - - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ChatroomMessage struct { - state protoimpl.MessageState `protogen:"open.v1"` - RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` // 聊天室的唯一标识 - Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"` // 消息发送者 - Content string `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"` // 消息内容 - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ChatroomMessage) Reset() { - *x = ChatroomMessage{} - mi := &file_protobuf_chat_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ChatroomMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ChatroomMessage) ProtoMessage() {} - -func (x *ChatroomMessage) ProtoReflect() protoreflect.Message { - mi := &file_protobuf_chat_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ChatroomMessage.ProtoReflect.Descriptor instead. -func (*ChatroomMessage) Descriptor() ([]byte, []int) { - return file_protobuf_chat_proto_rawDescGZIP(), []int{0} -} - -func (x *ChatroomMessage) GetRoomId() string { - if x != nil { - return x.RoomId - } - return "" -} - -func (x *ChatroomMessage) GetSender() string { - if x != nil { - return x.Sender - } - return "" -} - -func (x *ChatroomMessage) GetContent() string { - if x != nil { - return x.Content - } - return "" -} - -var File_protobuf_chat_proto protoreflect.FileDescriptor - -const file_protobuf_chat_proto_rawDesc = "" + - "\n" + - "\x13protobuf/chat.proto\x12\x04chat\"\\\n" + - "\x0fChatroomMessage\x12\x17\n" + - "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x16\n" + - "\x06sender\x18\x02 \x01(\tR\x06sender\x12\x18\n" + - "\acontent\x18\x03 \x01(\tR\acontent2K\n" + - "\x0fChatroomService\x128\n" + - "\x04Chat\x12\x15.chat.ChatroomMessage\x1a\x15.chat.ChatroomMessage(\x010\x01B\x14Z\x12chat/protobuf;chatb\x06proto3" - -var ( - file_protobuf_chat_proto_rawDescOnce sync.Once - file_protobuf_chat_proto_rawDescData []byte -) - -func file_protobuf_chat_proto_rawDescGZIP() []byte { - file_protobuf_chat_proto_rawDescOnce.Do(func() { - file_protobuf_chat_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_protobuf_chat_proto_rawDesc), len(file_protobuf_chat_proto_rawDesc))) - }) - return file_protobuf_chat_proto_rawDescData -} - -var file_protobuf_chat_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_protobuf_chat_proto_goTypes = []any{ - (*ChatroomMessage)(nil), // 0: chat.ChatroomMessage -} -var file_protobuf_chat_proto_depIdxs = []int32{ - 0, // 0: chat.ChatroomService.Chat:input_type -> chat.ChatroomMessage - 0, // 1: chat.ChatroomService.Chat:output_type -> chat.ChatroomMessage - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_protobuf_chat_proto_init() } -func file_protobuf_chat_proto_init() { - if File_protobuf_chat_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_protobuf_chat_proto_rawDesc), len(file_protobuf_chat_proto_rawDesc)), - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_protobuf_chat_proto_goTypes, - DependencyIndexes: file_protobuf_chat_proto_depIdxs, - MessageInfos: file_protobuf_chat_proto_msgTypes, - }.Build() - File_protobuf_chat_proto = out.File - file_protobuf_chat_proto_goTypes = nil - file_protobuf_chat_proto_depIdxs = nil -} diff --git a/examples/chat/out/stub/chat/protobuf/chat.proto b/examples/chat/out/stub/chat/protobuf/chat.proto deleted file mode 100644 index 7867b3e2..00000000 --- a/examples/chat/out/stub/chat/protobuf/chat.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; - -package chat; -option go_package = "chat/protobuf;chat"; - -message ChatroomMessage { - string room_id = 1; // 聊天室的唯一标识 - string sender = 2; // 消息发送者 - string content = 3; // 消息内容 -} - -service ChatroomService { - // 双向流式的聊天室通信方法 - rpc Chat(stream ChatroomMessage) returns (stream ChatroomMessage); -} diff --git a/examples/chat/out/stub/chat/protobuf/chat.trpc.go b/examples/chat/out/stub/chat/protobuf/chat.trpc.go deleted file mode 100644 index 35d8af0a..00000000 --- a/examples/chat/out/stub/chat/protobuf/chat.trpc.go +++ /dev/null @@ -1,156 +0,0 @@ -// Code generated by trpc-go/trpc-cmdline v1.0.9. DO NOT EDIT. -// source: protobuf/chat.proto - -package chat - -import ( - "context" - "errors" - "fmt" - - _ "trpc.group/trpc-go/trpc-go" - "trpc.group/trpc-go/trpc-go/client" - "trpc.group/trpc-go/trpc-go/codec" - _ "trpc.group/trpc-go/trpc-go/http" - "trpc.group/trpc-go/trpc-go/server" - "trpc.group/trpc-go/trpc-go/stream" -) - -// START ======================================= Server Service Definition ======================================= START - -// ChatroomServiceService defines service. -type ChatroomServiceService interface { - // Chat 双向流式的聊天室通信方法 - Chat(ChatroomService_ChatServer) error -} - -func ChatroomServiceService_Chat_Handler(srv interface{}, stream server.Stream) error { - return srv.(ChatroomServiceService).Chat(&chatroomServiceChatServer{stream}) -} - -type ChatroomService_ChatServer interface { - Send(*ChatroomMessage) error - Recv() (*ChatroomMessage, error) - server.Stream -} - -type chatroomServiceChatServer struct { - server.Stream -} - -func (x *chatroomServiceChatServer) Send(m *ChatroomMessage) error { - return x.Stream.SendMsg(m) -} - -func (x *chatroomServiceChatServer) Recv() (*ChatroomMessage, error) { - m := new(ChatroomMessage) - if err := x.Stream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// ChatroomServiceServer_ServiceDesc descriptor for server.RegisterService. -var ChatroomServiceServer_ServiceDesc = server.ServiceDesc{ - ServiceName: "chat.ChatroomService", - HandlerType: ((*ChatroomServiceService)(nil)), - StreamHandle: stream.NewStreamDispatcher(), - Methods: []server.Method{}, - Streams: []server.StreamDesc{ - { - StreamName: "/chat.ChatroomService/Chat", - Handler: ChatroomServiceService_Chat_Handler, - ServerStreams: true, - }, - }, -} - -// RegisterChatroomServiceService registers service. -func RegisterChatroomServiceService(s server.Service, svr ChatroomServiceService) { - if err := s.Register(&ChatroomServiceServer_ServiceDesc, svr); err != nil { - panic(fmt.Sprintf("ChatroomService register error:%v", err)) - } -} - -// START --------------------------------- Default Unimplemented Server Service --------------------------------- START - -type UnimplementedChatroomService struct{} - -// Chat 双向流式的聊天室通信方法 -func (s *UnimplementedChatroomService) Chat(stream ChatroomService_ChatServer) error { - return errors.New("rpc Chat of service ChatroomService is not implemented") -} - -// END --------------------------------- Default Unimplemented Server Service --------------------------------- END - -// END ======================================= Server Service Definition ======================================= END - -// START ======================================= Client Service Definition ======================================= START - -// ChatroomServiceClientProxy defines service client proxy -type ChatroomServiceClientProxy interface { - // Chat 双向流式的聊天室通信方法 - Chat(ctx context.Context, opts ...client.Option) (ChatroomService_ChatClient, error) -} - -type ChatroomServiceClientProxyImpl struct { - client client.Client - streamClient stream.Client - opts []client.Option -} - -var NewChatroomServiceClientProxy = func(opts ...client.Option) ChatroomServiceClientProxy { - return &ChatroomServiceClientProxyImpl{client: client.DefaultClient, streamClient: stream.DefaultStreamClient, opts: opts} -} - -func (c *ChatroomServiceClientProxyImpl) Chat(ctx context.Context, opts ...client.Option) (ChatroomService_ChatClient, error) { - ctx, msg := codec.WithCloneMessage(ctx) - - msg.WithClientRPCName("/chat.ChatroomService/Chat") - msg.WithCalleeServiceName(ChatroomServiceServer_ServiceDesc.ServiceName) - msg.WithCalleeApp("") - msg.WithCalleeServer("") - msg.WithCalleeService("ChatroomService") - msg.WithCalleeMethod("Chat") - msg.WithSerializationType(codec.SerializationTypePB) - - clientStreamDesc := &client.ClientStreamDesc{} - clientStreamDesc.StreamName = "/chat.ChatroomService/Chat" - clientStreamDesc.ClientStreams = true - clientStreamDesc.ServerStreams = true - - callopts := make([]client.Option, 0, len(c.opts)+len(opts)) - callopts = append(callopts, c.opts...) - callopts = append(callopts, opts...) - - stream, err := c.streamClient.NewStream(ctx, clientStreamDesc, "/chat.ChatroomService/Chat", callopts...) - if err != nil { - return nil, err - } - x := &chatroomServiceChatClient{stream} - return x, nil -} - -type ChatroomService_ChatClient interface { - Send(*ChatroomMessage) error - Recv() (*ChatroomMessage, error) - client.ClientStream -} - -type chatroomServiceChatClient struct { - client.ClientStream -} - -func (x *chatroomServiceChatClient) Send(m *ChatroomMessage) error { - return x.ClientStream.SendMsg(m) -} - -func (x *chatroomServiceChatClient) Recv() (*ChatroomMessage, error) { - m := new(ChatroomMessage) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// END ======================================= Client Service Definition ======================================= END diff --git a/examples/chat/out/stub/chat/protobuf/chat_mock.go b/examples/chat/out/stub/chat/protobuf/chat_mock.go deleted file mode 100644 index 02b6f955..00000000 --- a/examples/chat/out/stub/chat/protobuf/chat_mock.go +++ /dev/null @@ -1,320 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: stub/chat/protobuf/chat.trpc.go -// -// Generated by this command: -// -// mockgen -destination=stub/chat/protobuf/chat_mock.go -package=chat -self_package=chat/protobuf --source=stub/chat/protobuf/chat.trpc.go -// - -// Package chat is a generated GoMock package. -package chat - -import ( - context "context" - reflect "reflect" - - gomock "go.uber.org/mock/gomock" - client "trpc.group/trpc-go/trpc-go/client" -) - -// MockChatroomServiceService is a mock of ChatroomServiceService interface. -type MockChatroomServiceService struct { - ctrl *gomock.Controller - recorder *MockChatroomServiceServiceMockRecorder -} - -// MockChatroomServiceServiceMockRecorder is the mock recorder for MockChatroomServiceService. -type MockChatroomServiceServiceMockRecorder struct { - mock *MockChatroomServiceService -} - -// NewMockChatroomServiceService creates a new mock instance. -func NewMockChatroomServiceService(ctrl *gomock.Controller) *MockChatroomServiceService { - mock := &MockChatroomServiceService{ctrl: ctrl} - mock.recorder = &MockChatroomServiceServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockChatroomServiceService) EXPECT() *MockChatroomServiceServiceMockRecorder { - return m.recorder -} - -// ISGOMOCK indicates that this struct is a gomock mock. -func (m *MockChatroomServiceService) ISGOMOCK() struct{} { - return struct{}{} -} - -// Chat mocks base method. -func (m *MockChatroomServiceService) Chat(arg0 ChatroomService_ChatServer) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Chat", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Chat indicates an expected call of Chat. -func (mr *MockChatroomServiceServiceMockRecorder) Chat(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Chat", reflect.TypeOf((*MockChatroomServiceService)(nil).Chat), arg0) -} - -// MockChatroomService_ChatServer is a mock of ChatroomService_ChatServer interface. -type MockChatroomService_ChatServer struct { - ctrl *gomock.Controller - recorder *MockChatroomService_ChatServerMockRecorder -} - -// MockChatroomService_ChatServerMockRecorder is the mock recorder for MockChatroomService_ChatServer. -type MockChatroomService_ChatServerMockRecorder struct { - mock *MockChatroomService_ChatServer -} - -// NewMockChatroomService_ChatServer creates a new mock instance. -func NewMockChatroomService_ChatServer(ctrl *gomock.Controller) *MockChatroomService_ChatServer { - mock := &MockChatroomService_ChatServer{ctrl: ctrl} - mock.recorder = &MockChatroomService_ChatServerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockChatroomService_ChatServer) EXPECT() *MockChatroomService_ChatServerMockRecorder { - return m.recorder -} - -// ISGOMOCK indicates that this struct is a gomock mock. -func (m *MockChatroomService_ChatServer) ISGOMOCK() struct{} { - return struct{}{} -} - -// Context mocks base method. -func (m *MockChatroomService_ChatServer) Context() context.Context { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Context") - ret0, _ := ret[0].(context.Context) - return ret0 -} - -// Context indicates an expected call of Context. -func (mr *MockChatroomService_ChatServerMockRecorder) Context() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockChatroomService_ChatServer)(nil).Context)) -} - -// Recv mocks base method. -func (m *MockChatroomService_ChatServer) Recv() (*ChatroomMessage, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Recv") - ret0, _ := ret[0].(*ChatroomMessage) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Recv indicates an expected call of Recv. -func (mr *MockChatroomService_ChatServerMockRecorder) Recv() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockChatroomService_ChatServer)(nil).Recv)) -} - -// RecvMsg mocks base method. -func (m_2 *MockChatroomService_ChatServer) RecvMsg(m any) error { - m_2.ctrl.T.Helper() - ret := m_2.ctrl.Call(m_2, "RecvMsg", m) - ret0, _ := ret[0].(error) - return ret0 -} - -// RecvMsg indicates an expected call of RecvMsg. -func (mr *MockChatroomService_ChatServerMockRecorder) RecvMsg(m any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockChatroomService_ChatServer)(nil).RecvMsg), m) -} - -// Send mocks base method. -func (m *MockChatroomService_ChatServer) Send(arg0 *ChatroomMessage) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Send", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Send indicates an expected call of Send. -func (mr *MockChatroomService_ChatServerMockRecorder) Send(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockChatroomService_ChatServer)(nil).Send), arg0) -} - -// SendMsg mocks base method. -func (m_2 *MockChatroomService_ChatServer) SendMsg(m any) error { - m_2.ctrl.T.Helper() - ret := m_2.ctrl.Call(m_2, "SendMsg", m) - ret0, _ := ret[0].(error) - return ret0 -} - -// SendMsg indicates an expected call of SendMsg. -func (mr *MockChatroomService_ChatServerMockRecorder) SendMsg(m any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockChatroomService_ChatServer)(nil).SendMsg), m) -} - -// MockChatroomServiceClientProxy is a mock of ChatroomServiceClientProxy interface. -type MockChatroomServiceClientProxy struct { - ctrl *gomock.Controller - recorder *MockChatroomServiceClientProxyMockRecorder -} - -// MockChatroomServiceClientProxyMockRecorder is the mock recorder for MockChatroomServiceClientProxy. -type MockChatroomServiceClientProxyMockRecorder struct { - mock *MockChatroomServiceClientProxy -} - -// NewMockChatroomServiceClientProxy creates a new mock instance. -func NewMockChatroomServiceClientProxy(ctrl *gomock.Controller) *MockChatroomServiceClientProxy { - mock := &MockChatroomServiceClientProxy{ctrl: ctrl} - mock.recorder = &MockChatroomServiceClientProxyMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockChatroomServiceClientProxy) EXPECT() *MockChatroomServiceClientProxyMockRecorder { - return m.recorder -} - -// ISGOMOCK indicates that this struct is a gomock mock. -func (m *MockChatroomServiceClientProxy) ISGOMOCK() struct{} { - return struct{}{} -} - -// Chat mocks base method. -func (m *MockChatroomServiceClientProxy) Chat(ctx context.Context, opts ...client.Option) (ChatroomService_ChatClient, error) { - m.ctrl.T.Helper() - varargs := []any{ctx} - for _, a := range opts { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Chat", varargs...) - ret0, _ := ret[0].(ChatroomService_ChatClient) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Chat indicates an expected call of Chat. -func (mr *MockChatroomServiceClientProxyMockRecorder) Chat(ctx any, opts ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx}, opts...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Chat", reflect.TypeOf((*MockChatroomServiceClientProxy)(nil).Chat), varargs...) -} - -// MockChatroomService_ChatClient is a mock of ChatroomService_ChatClient interface. -type MockChatroomService_ChatClient struct { - ctrl *gomock.Controller - recorder *MockChatroomService_ChatClientMockRecorder -} - -// MockChatroomService_ChatClientMockRecorder is the mock recorder for MockChatroomService_ChatClient. -type MockChatroomService_ChatClientMockRecorder struct { - mock *MockChatroomService_ChatClient -} - -// NewMockChatroomService_ChatClient creates a new mock instance. -func NewMockChatroomService_ChatClient(ctrl *gomock.Controller) *MockChatroomService_ChatClient { - mock := &MockChatroomService_ChatClient{ctrl: ctrl} - mock.recorder = &MockChatroomService_ChatClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockChatroomService_ChatClient) EXPECT() *MockChatroomService_ChatClientMockRecorder { - return m.recorder -} - -// ISGOMOCK indicates that this struct is a gomock mock. -func (m *MockChatroomService_ChatClient) ISGOMOCK() struct{} { - return struct{}{} -} - -// CloseSend mocks base method. -func (m *MockChatroomService_ChatClient) CloseSend() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CloseSend") - ret0, _ := ret[0].(error) - return ret0 -} - -// CloseSend indicates an expected call of CloseSend. -func (mr *MockChatroomService_ChatClientMockRecorder) CloseSend() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockChatroomService_ChatClient)(nil).CloseSend)) -} - -// Context mocks base method. -func (m *MockChatroomService_ChatClient) Context() context.Context { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Context") - ret0, _ := ret[0].(context.Context) - return ret0 -} - -// Context indicates an expected call of Context. -func (mr *MockChatroomService_ChatClientMockRecorder) Context() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockChatroomService_ChatClient)(nil).Context)) -} - -// Recv mocks base method. -func (m *MockChatroomService_ChatClient) Recv() (*ChatroomMessage, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Recv") - ret0, _ := ret[0].(*ChatroomMessage) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Recv indicates an expected call of Recv. -func (mr *MockChatroomService_ChatClientMockRecorder) Recv() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockChatroomService_ChatClient)(nil).Recv)) -} - -// RecvMsg mocks base method. -func (m_2 *MockChatroomService_ChatClient) RecvMsg(m any) error { - m_2.ctrl.T.Helper() - ret := m_2.ctrl.Call(m_2, "RecvMsg", m) - ret0, _ := ret[0].(error) - return ret0 -} - -// RecvMsg indicates an expected call of RecvMsg. -func (mr *MockChatroomService_ChatClientMockRecorder) RecvMsg(m any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockChatroomService_ChatClient)(nil).RecvMsg), m) -} - -// Send mocks base method. -func (m *MockChatroomService_ChatClient) Send(arg0 *ChatroomMessage) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Send", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Send indicates an expected call of Send. -func (mr *MockChatroomService_ChatClientMockRecorder) Send(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockChatroomService_ChatClient)(nil).Send), arg0) -} - -// SendMsg mocks base method. -func (m_2 *MockChatroomService_ChatClient) SendMsg(m any) error { - m_2.ctrl.T.Helper() - ret := m_2.ctrl.Call(m_2, "SendMsg", m) - ret0, _ := ret[0].(error) - return ret0 -} - -// SendMsg indicates an expected call of SendMsg. -func (mr *MockChatroomService_ChatClientMockRecorder) SendMsg(m any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockChatroomService_ChatClient)(nil).SendMsg), m) -} diff --git a/examples/chat/out/stub/chat/protobuf/go.mod b/examples/chat/out/stub/chat/protobuf/go.mod deleted file mode 100644 index ec3a38be..00000000 --- a/examples/chat/out/stub/chat/protobuf/go.mod +++ /dev/null @@ -1,42 +0,0 @@ -module chat/protobuf - -go 1.24.4 - -require ( - go.uber.org/mock v0.5.2 - google.golang.org/protobuf v1.36.6 - trpc.group/trpc-go/trpc-go v1.0.3 -) - -require ( - github.com/BurntSushi/toml v0.3.1 // indirect - github.com/andybalholm/brotli v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.4.9 // indirect - github.com/go-playground/form/v4 v4.2.0 // indirect - github.com/golang/snappy v0.0.3 // indirect - github.com/google/flatbuffers v2.0.0+incompatible // indirect - github.com/hashicorp/errwrap v1.0.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.15.9 // indirect - github.com/lestrrat-go/strftime v1.0.6 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/panjf2000/ants/v2 v2.4.6 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/spf13/cast v1.3.1 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.43.0 // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/automaxprocs v1.3.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.24.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - trpc.group/trpc-go/tnet v1.0.1 // indirect - trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0 // indirect -) diff --git a/examples/chat/out/stub/chat/protobuf/go.sum b/examples/chat/out/stub/chat/protobuf/go.sum deleted file mode 100644 index da17164b..00000000 --- a/examples/chat/out/stub/chat/protobuf/go.sum +++ /dev/null @@ -1,139 +0,0 @@ -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= -github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/form/v4 v4.2.0 h1:N1wh+Goz61e6w66vo8vJkQt+uwZSoLz50kZPJWR8eic= -github.com/go-playground/form/v4 v4.2.0/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U= -github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/flatbuffers v2.0.0+incompatible h1:dicJ2oXwypfwUGnB2/TYWYEKiuk9eYQlQO/AnOHl5mI= -github.com/google/flatbuffers v2.0.0+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= -github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8= -github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= -github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ= -github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/panjf2000/ants/v2 v2.4.6 h1:drmj9mcygn2gawZ155dRbo+NfXEfAssjZNU1qoIb4gQ= -github.com/panjf2000/ants/v2 v2.4.6/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.43.0 h1:Gy4sb32C98fbzVWZlTM1oTMdLWGyvxR03VhM6cBIU4g= -github.com/valyala/fasthttp v1.43.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/automaxprocs v1.3.0 h1:II28aZoGdaglS5vVNnspf28lnZpXScxtIozx1lAjdb0= -go.uber.org/automaxprocs v1.3.0/go.mod h1:9CWT6lKIep8U41DDaPiH6eFscnTyjfTANNQNx6LrIcA= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= -go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -trpc.group/trpc-go/tnet v1.0.1 h1:Yzqyrgyfm+W742FzGr39c4+OeQmLi7PWotJxrOBtV9o= -trpc.group/trpc-go/tnet v1.0.1/go.mod h1:s/webUFYWEFBHErKyFmj7LYC7XfC2LTLCcwfSnJ04M0= -trpc.group/trpc-go/trpc-go v1.0.3 h1:X4RhPmJOkVoK6EGKoV241dvEpB6EagBeyu3ZrqkYZQY= -trpc.group/trpc-go/trpc-go v1.0.3/go.mod h1:82O+G2rD5ST+JAPuPPSqvsr6UI59UxV27iAILSkAIlQ= -trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0 h1:rMtHYzI0ElMJRxHtT5cD99SigFE6XzKK4PFtjcwokI0= -trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0/go.mod h1:K+a1K/Gnlcg9BFHWx30vLBIEDhxODhl25gi1JjA54CQ= diff --git a/examples/chat/out/trpc.log b/examples/chat/out/trpc.log deleted file mode 100644 index b235f144..00000000 --- a/examples/chat/out/trpc.log +++ /dev/null @@ -1,29 +0,0 @@ -2025-07-23 10:38:30.645 INFO client/client_linux.go:35 client chat.ChatroomService is empowered with tnet! 🤩 -2025-07-23 10:38:30.646 INFO client/client_linux.go:35 client is empowered with tnet! 🤩 -2025-07-23 10:38:30.646 INFO server/service_linux.go:21 service chat.ChatroomService with network tcp and protocol trpc is empowered with tnet! 🤩 you can set 'transport: go-net' in your trpc_go.yaml's service configuration to switch to the golang net framework -2025-07-23 10:38:30.646 INFO tnet/server_transport.go:66 service:chat.ChatroomService is using tnet transport, current number of pollers: 1 -2025-07-23 10:38:30.646 INFO server/service.go:168 process:349337, trpc service:chat.ChatroomService launch success, tcp:127.0.0.1:8000, serving ... -2025-07-23 10:40:34.142 INFO client/client_linux.go:35 client chat.ChatroomService is empowered with tnet! 🤩 -2025-07-23 10:40:34.142 INFO client/client_linux.go:35 client is empowered with tnet! 🤩 -2025-07-23 10:40:34.143 INFO server/service_linux.go:21 service chat.ChatroomService with network tcp and protocol trpc is empowered with tnet! 🤩 you can set 'transport: go-net' in your trpc_go.yaml's service configuration to switch to the golang net framework -2025-07-23 10:40:34.143 INFO tnet/server_transport.go:66 service:chat.ChatroomService is using tnet transport, current number of pollers: 1 -2025-07-23 10:40:34.143 INFO server/service.go:168 process:350955, trpc service:chat.ChatroomService launch success, tcp:127.0.0.1:8000, serving ... -2025-07-23 10:41:41.710 INFO server/service.go:527 process:350955, trpc service:chat.ChatroomService, closing ... -2025-07-23 10:41:41.710 INFO server/service.go:554 process:350955, trpc service:chat.ChatroomService, closed -2025-07-23 10:41:41.710 INFO admin/admin.go:192 process:350955, admin server, closed -2025-07-23 21:30:00.466 INFO client/client_linux.go:35 client chat.ChatroomService is empowered with tnet! 🤩 -2025-07-23 21:30:00.466 INFO client/client_linux.go:35 client is empowered with tnet! 🤩 -2025-07-23 21:30:00.466 INFO server/service_linux.go:21 service chat.ChatroomService with network tcp and protocol trpc is empowered with tnet! 🤩 you can set 'transport: go-net' in your trpc_go.yaml's service configuration to switch to the golang net framework -2025-07-23 21:30:00.466 INFO tnet/server_transport.go:66 service:chat.ChatroomService is using tnet transport, current number of pollers: 1 -2025-07-23 21:30:00.466 INFO server/service.go:168 process:261444, trpc service:chat.ChatroomService launch success, tcp:127.0.0.1:8000, serving ... -2025-07-23 21:31:32.620 INFO server/service.go:527 process:261444, trpc service:chat.ChatroomService, closing ... -2025-07-23 21:31:32.620 INFO server/service.go:554 process:261444, trpc service:chat.ChatroomService, closed -2025-07-23 21:31:32.620 INFO admin/admin.go:192 process:261444, admin server, closed -2025-07-24 11:08:51.718 INFO client/client_linux.go:35 client chat.ChatroomService is empowered with tnet! 🤩 -2025-07-24 11:08:51.718 INFO client/client_linux.go:35 client is empowered with tnet! 🤩 -2025-07-24 11:08:51.718 INFO server/service_linux.go:21 service chat.ChatroomService with network tcp and protocol trpc is empowered with tnet! 🤩 you can set 'transport: go-net' in your trpc_go.yaml's service configuration to switch to the golang net framework -2025-07-24 11:08:51.718 INFO tnet/server_transport.go:66 service:chat.ChatroomService is using tnet transport, current number of pollers: 1 -2025-07-24 11:08:51.718 INFO server/service.go:168 process:622089, trpc service:chat.ChatroomService launch success, tcp:127.0.0.1:8000, serving ... -2025-07-24 11:10:25.463 INFO admin/admin.go:192 process:622089, admin server, closed -2025-07-24 11:10:25.463 INFO server/service.go:527 process:622089, trpc service:chat.ChatroomService, closing ... -2025-07-24 11:10:25.463 INFO server/service.go:554 process:622089, trpc service:chat.ChatroomService, closed diff --git a/examples/chat/out/trpc_go.yaml b/examples/chat/out/trpc_go.yaml deleted file mode 100644 index e1b0f7c0..00000000 --- a/examples/chat/out/trpc_go.yaml +++ /dev/null @@ -1,49 +0,0 @@ -global: # Global configuration. - namespace: Development # Environment type, either Production or Development. - env_name: test # Environment name for non-production environments. - -server: # Server configuration. - app: chat # Application name for the business. - server: ChatroomService # Process server name. - bin_path: /usr/local/trpc/bin/ # Path to binary executable files and framework configuration files. - conf_path: /usr/local/trpc/conf/ # Path to business configuration files. - data_path: /usr/local/trpc/data/ # Path to business data files. - filter: # List of interceptors for all service handler functions. - - simpledebuglog - - recovery # Intercept panics from business processing goroutines created by the framework. - service: # Services provided by the business, can have multiple. - - name: chat.ChatroomService # Route name for the service. - ip: 127.0.0.1 # Service listening IP address, can use placeholder ${ip}. Use either ip or nic, ip takes priority. - # nic: eth0 - port: 8000 # Service listening port, can use placeholder ${port}. - network: tcp # Network listening type: tcp or udp. - protocol: trpc # Application layer protocol: trpc or http. - timeout: 1000 # Maximum processing time for requests in milliseconds. - -client: # Backend configuration for client calls. - timeout: 1000 # Maximum processing time for all backends. - namespace: Development # Environment for all backends. - filter: # List of interceptors for all backend function calls. - - simpledebuglog - service: # Configuration for individual backends. - - name: chat.ChatroomService # Service name for the backend. - namespace: Development # Environment for the backend. - network: tcp # Network type for the backend: tcp or udp (configuration takes priority). - protocol: trpc # Application layer protocol: trpc or http. - target: ip://127.0.0.1:8000 # Service address for requests. - timeout: 1000 # Maximum processing time for requests. - - -plugins: # Plugin configuration. - log: # Log configuration. - default: # Default log configuration, supports multiple outputs. - - writer: console # Console standard output (default). - level: debug # Log level for standard output. - - writer: file # Local file log. - level: info # Log level for local file rolling logs. - writer_config: - filename: ./trpc.log # Path to store local file rolling logs. - max_size: 10 # Maximum size of local file rolling logs in MB. - max_backups: 10 # Maximum number of log files. - max_age: 7 # Maximum number of days to keep logs. - compress: false # Whether to compress log files. diff --git a/examples/chat/protobuf/chat.proto b/examples/chat/protobuf/chat.proto deleted file mode 100644 index 7867b3e2..00000000 --- a/examples/chat/protobuf/chat.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; - -package chat; -option go_package = "chat/protobuf;chat"; - -message ChatroomMessage { - string room_id = 1; // 聊天室的唯一标识 - string sender = 2; // 消息发送者 - string content = 3; // 消息内容 -} - -service ChatroomService { - // 双向流式的聊天室通信方法 - rpc Chat(stream ChatroomMessage) returns (stream ChatroomMessage); -} diff --git a/examples/chat/server/main.go b/examples/chat/server/main.go new file mode 100644 index 00000000..7e5b13dd --- /dev/null +++ b/examples/chat/server/main.go @@ -0,0 +1,299 @@ +package main + +import ( + "context" + "flag" + "fmt" + "os" + "os/signal" + "strings" + "sync" + "syscall" + + "github.com/tmc/langchaingo/llms/openai" + "trpc.group/trpc-go/trpc-a2a-go/log" + "trpc.group/trpc-go/trpc-a2a-go/protocol" + "trpc.group/trpc-go/trpc-a2a-go/server" + "trpc.group/trpc-go/trpc-a2a-go/taskmanager" +) + +type User struct { + ID string + Name string +} + +type ChatRoom struct { + ID string + users map[string]*User + messages []protocol.Message + mu sync.Mutex +} + +type ChatRoomManager struct { + rooms map[string]*ChatRoom + mu sync.Mutex +} + +func NewChatRoomManager() *ChatRoomManager { + return &ChatRoomManager{ + rooms: make(map[string]*ChatRoom), + } +} + +func (m *ChatRoomManager) GetOrCreateRoom(roomID string) *ChatRoom { + m.mu.Lock() + defer m.mu.Unlock() + room, ok := m.rooms[roomID] + if !ok { + room = &ChatRoom{ + ID: roomID, + users: make(map[string]*User), + } + m.rooms[roomID] = room + } + return room +} + +func (room *ChatRoom) AddUser(user *User) bool { + room.mu.Lock() + defer room.mu.Unlock() + if _, exists := room.users[user.ID]; exists { + return false + } + room.users[user.ID] = user + return true +} + +func (room *ChatRoom) RemoveUser(userID string) { + room.mu.Lock() + defer room.mu.Unlock() + delete(room.users, userID) +} + +func (room *ChatRoom) Broadcast(msg protocol.Message) { + room.mu.Lock() + room.messages = append(room.messages, msg) + room.mu.Unlock() +} + +func (room *ChatRoom) History() []protocol.Message { + room.mu.Lock() + defer room.mu.Unlock() + history := make([]protocol.Message, len(room.messages)) + copy(history, room.messages) + return history +} + +// ----------------- AI ----------------- +func callAI(ctx context.Context, input string) (string, error) { + llm, err := openai.New() + if err != nil { + return "", err + } + resp, err := llm.Call(ctx, input) + if err != nil { + return "", err + } + return resp, nil +} + +// ----------------- Processor ----------------- +type chatMessageProcessor struct { + roomMgr *ChatRoomManager +} + +func (p *chatMessageProcessor) ProcessMessage( + ctx context.Context, + message protocol.Message, + options taskmanager.ProcessOptions, + handler taskmanager.TaskHandler, +) (*taskmanager.MessageProcessingResult, error) { + roomID, userID, userName := parseContext(message) + if roomID == "" || userID == "" { + errMsg := "room_id and user_id required" + log.Errorf(errMsg) + errorMessage := protocol.NewMessage( + protocol.MessageRoleAgent, + []protocol.Part{protocol.NewTextPart(errMsg)}, + ) + return &taskmanager.MessageProcessingResult{Result: &errorMessage}, nil + } + room := p.roomMgr.GetOrCreateRoom(roomID) + user := &User{ID: userID, Name: userName} + room.AddUser(user) + + text := extractText(message) + if text == "" { + errMsg := "input message must contain text." + log.Errorf(errMsg) + errorMessage := protocol.NewMessage( + protocol.MessageRoleAgent, + []protocol.Part{protocol.NewTextPart(errMsg)}, + ) + return &taskmanager.MessageProcessingResult{Result: &errorMessage}, nil + } + fmt.Printf("[%s : %s] message: %s\n", roomID, userID, text) + + // 广播用户消息 + room.Broadcast(message) + + // 检查@ai + if strings.HasPrefix(text, "@ai") { + go func() { + aiInput := strings.TrimSpace(strings.TrimPrefix(text, "@ai")) + aiReply, err := callAI(ctx, aiInput) + if err != nil { + aiReply = "AI error: " + err.Error() + } + aiMsg := protocol.NewMessage( + protocol.MessageRoleAgent, + []protocol.Part{protocol.NewTextPart("[AI] " + aiReply)}, + ) + aiMsg.ContextID = message.ContextID + room.Broadcast(aiMsg) + }() + } + + // 流式推送 + if options.Streaming { + taskID, err := handler.BuildTask(nil, nil) + if err != nil { + return nil, fmt.Errorf("failed to build task: %w", err) + } + subscriber, err := handler.SubscribeTask(&taskID) + if err != nil { + return nil, fmt.Errorf("failed to subscribe to task: %w", err) + } + // 首次推送历史 + go func() { + defer subscriber.Close() + for _, msg := range room.History() { + _ = subscriber.Send(protocol.StreamingMessageEvent{Result: &msg}) + } + // 可选:阻塞直到 context 被取消 + <-ctx.Done() + }() + return &taskmanager.MessageProcessingResult{ + StreamingEvents: subscriber, + }, nil + } + + // 非流式,返回历史 + history := room.History() + resp := protocol.NewMessage( + protocol.MessageRoleAgent, + []protocol.Part{protocol.NewTextPart(formatHistory(history))}, + ) + return &taskmanager.MessageProcessingResult{ + Result: &resp, + }, nil +} + +func parseContext(msg protocol.Message) (roomID, userID, userName string) { + if msg.ContextID != nil { + roomID = *msg.ContextID + } + if msg.Metadata != nil { + if v, ok := msg.Metadata["user_id"].(string); ok { + userID = v + } + if v, ok := msg.Metadata["user_name"].(string); ok { + userName = v + } + } + return +} + +func extractText(message protocol.Message) string { + for _, part := range message.Parts { + if textPart, ok := part.(*protocol.TextPart); ok { + return textPart.Text + } + } + return "" +} + +func formatHistory(messages []protocol.Message) string { + var sb strings.Builder + sb.WriteString("Chat History:\n") + for i, msg := range messages { + var user string + if msg.Metadata != nil { + if v, ok := msg.Metadata["user_name"]; ok { + if name, ok := v.(string); ok && name != "" { + user = name + } + } + } + if user == "" { + user = string(msg.Role) + } + sb.WriteString(fmt.Sprintf("[%d][%s]: %s\n", i+1, user, extractText(msg))) + } + return sb.String() +} + +func stringPtr(s string) *string { return &s } +func boolPtr(b bool) *bool { return &b } + +func main() { + host := flag.String("host", "localhost", "Host to listen on") + port := flag.Int("port", 8080, "Port to listen on") + flag.Parse() + + agentCard := server.AgentCard{ + Name: "AI Chat Room", + Description: "A simple chat room with AI bot", + URL: fmt.Sprintf("http://%s:%d/", *host, *port), + Version: "1.0.0", + Provider: &server.AgentProvider{ + Organization: "tRPC-A2A-Go Examples", + }, + Capabilities: server.AgentCapabilities{ + Streaming: boolPtr(true), + PushNotifications: boolPtr(false), + StateTransitionHistory: boolPtr(true), + }, + DefaultInputModes: []string{"text"}, + DefaultOutputModes: []string{"text"}, + Skills: []server.AgentSkill{ + { + ID: "chat", + Name: "Chat Room", + Description: stringPtr("Group chat with AI bot"), + Tags: []string{"chat", "ai"}, + Examples: []string{"@ai 你好", "大家好"}, + InputModes: []string{"text"}, + OutputModes: []string{"text"}, + }, + }, + } + + processor := &chatMessageProcessor{ + roomMgr: NewChatRoomManager(), + } + + taskManager, err := taskmanager.NewMemoryTaskManager(processor) + if err != nil { + log.Fatalf("Failed to create task manager: %v", err) + } + + srv, err := server.NewA2AServer(agentCard, taskManager) + if err != nil { + log.Fatalf("Failed to create server: %v", err) + } + + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + + go func() { + serverAddr := fmt.Sprintf("%s:%d", *host, *port) + log.Infof("Starting server on %s...", serverAddr) + if err := srv.Start(serverAddr); err != nil { + log.Fatalf("Server failed: %v", err) + } + }() + + sig := <-sigChan + log.Infof("Received signal %v, shutting down...", sig) +}