第22章:实战二 —— 聊天微服务(双向流)
本章目标
用双向流实现聊天室
Proto 定义
protobuf
service ChatService {
rpc Chat(stream ChatMessage) returns (stream ChatMessage);
}
message ChatMessage {
string user = 1;
string room = 2;
string text = 3;
int64 timestamp = 4;
}Server 核心逻辑
go
type chatServer struct {
pb.UnimplementedChatServiceServer
mu sync.RWMutex
rooms map[string]map[string]chan *pb.ChatMessage // room → user → channel
}
func (s *chatServer) Chat(stream pb.ChatService_ChatServer) error {
// 接收第一条消息获取用户和房间
msg, _ := stream.Recv()
room := msg.GetRoom()
user := msg.GetUser()
ch := make(chan *pb.ChatMessage, 100)
s.joinRoom(room, user, ch)
defer s.leaveRoom(room, user)
// goroutine:广播消息给房间内所有人
go s.broadcast(room, user, ch)
// 主循环:接收消息
for {
msg, err := stream.Recv()
if err == io.EOF { return nil }
if err != nil { return err }
s.sendToRoom(room, msg)
}
}关键技术点
- 双向流实现实时聊天
- goroutine 并发处理收发
- 房间管理(加入/离开/广播)
练习题
- 实现聊天服务(房间加入/发送消息/接收消息)。
- 用多个客户端连接测试消息广播。