使用gRPC实现Go语言双向流式聊天,首先定义proto文件声明流式接口,生成Go代码后编写服务端广播消息逻辑,客户端并发处理收发消息,通过HTTP/2实现实时通信,适用于在线客服等场景。

在Go语言中使用gRPC实现双向流式聊天,可以实现实时通信场景,比如在线客服、多人聊天室等。gRPC默认基于HTTP/2,天然支持双向流(Bidirectional Streaming),非常适合这类需求。
1. 定义Proto文件
首先定义一个.proto文件来描述服务接口和消息格式。创建chat.proto:
syntax = "proto3";package chat;service ChatService { rpc ChatStream(stream Message) returns (stream Message);}message Message { string user = 1; string content = 2; int64 timestamp = 3;}
这里定义了一个ChatStream方法,客户端和服务端都可以发送和接收消息流,实现真正的双向通信。
2. 生成Go代码
安装必要的工具并生成代码:
立即学习“go语言免费学习笔记(深入)”;
确保已安装 Protocol Buffers 编译器 protoc 和 Go 插件:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latestgo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
执行命令生成Go代码:
protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative chat.proto
会生成chat.pb.go和chat_grpc.pb.go两个文件。
3. 实现gRPC服务端
编写服务端逻辑,处理每个连接的双向流:
package mainimport ( "context" "fmt" "log" "net" "your_project/chat" "google.golang.org/grpc")type ChatServer struct { chat.UnimplementedChatServiceServer clients []chat.ChatService_ChatStreamServer}func (s *ChatServer) ChatStream(stream chat.ChatService_ChatStreamServer) error { s.clients = append(s.clients, stream) for { msg, err := stream.Recv() if err != nil { return err } fmt.Printf("[%s]: %sn", msg.User, msg.Content) // 广播给所有其他客户端 for _, client := range s.clients { go func(c chat.ChatService_ChatStreamServer) { _ = c.Send(msg) }(client) } }}func main() { lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) } grpcServer := grpc.NewServer() chat.RegisterChatServiceServer(grpcServer, &ChatServer{}) log.Println("gRPC server running on port 50051...") if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) }}
服务端将所有连接的客户端保存起来,每当收到一条消息,就广播给所有客户端(包括发送者)。
4. 实现gRPC客户端
客户端需要同时读取用户输入并监听来自服务端的消息:
package mainimport ( "bufio" "context" "fmt" "log" "os" "time" "your_project/chat" "google.golang.org/grpc")func main() { conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithBlock()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() client := chat.NewChatServiceClient(conn) stream, err := client.ChatStream(context.Background()) if err != nil { log.Fatal(err) } // 开启协程接收消息 go func() { for { msg, err := stream.Recv() if err != nil { fmt.Printf("receive error: %vn", err) return } fmt.Printf("n[%s] %s: %sn", time.Unix(msg.Timestamp, 0).Format("15:04"), msg.User, msg.Content) } }() // 读取用户输入 scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { text := scanner.Text() if text == "quit" { break } msg := &chat.Message{ User: "Alice", // 可改为从命令行输入 Content: text, Timestamp: time.Now().Unix(), } if err := stream.Send(msg); err != nil { fmt.Printf("send error: %vn", err) break } }}
客户端通过goroutine分离接收和发送逻辑,保证不会阻塞用户输入。
基本上就这些。运行服务端,再启动多个客户端,就能看到实时聊天效果了。这种方式扩展性好,适合构建分布式即时通讯系统。
以上就是Golang使用gRPC实现双向流式聊天示例的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1405552.html
微信扫一扫
支付宝扫一扫