func (s *_ABitOfEverythingServer) BulkCreate(stream examples.StreamService_BulkCreateServer) error { count := 0 ctx := stream.Context() for { msg, err := stream.Recv() if err == io.EOF { break } if err != nil { return err } count++ glog.Error(msg) if _, err = s.Create(ctx, msg); err != nil { return err } } err := stream.SendHeader(metadata.New(map[string]string{ "count": fmt.Sprintf("%d", count), })) if err != nil { return nil } stream.SetTrailer(metadata.New(map[string]string{ "foo": "foo2", "bar": "bar2", })) return stream.SendAndClose(new(empty.Empty)) }
func (s *_ABitOfEverythingServer) BulkEcho(stream examples.StreamService_BulkEchoServer) error { var msgs []*sub.StringMessage for { msg, err := stream.Recv() if err == io.EOF { break } if err != nil { return err } msgs = append(msgs, msg) } hmd := metadata.New(map[string]string{ "foo": "foo1", "bar": "bar1", }) if err := stream.SendHeader(hmd); err != nil { return err } for _, msg := range msgs { glog.Info(msg) if err := stream.Send(msg); err != nil { return err } } stream.SetTrailer(metadata.New(map[string]string{ "foo": "foo2", "bar": "bar2", })) return nil }
func (s *_ABitOfEverythingServer) List(_ *empty.Empty, stream examples.StreamService_ListServer) error { s.m.Lock() defer s.m.Unlock() err := stream.SendHeader(metadata.New(map[string]string{ "count": fmt.Sprintf("%d", len(s.v)), })) if err != nil { return nil } for _, msg := range s.v { if err := stream.Send(msg); err != nil { return err } } // return error when metadata includes error header if header, ok := metadata.FromContext(stream.Context()); ok { if v, ok := header["error"]; ok { stream.SetTrailer(metadata.New(map[string]string{ "foo": "foo2", "bar": "bar2", })) return grpc.Errorf(codes.InvalidArgument, "error metadata: %v", v) } } return nil }
func (s *echoServer) EchoBody(ctx context.Context, msg *examples.SimpleMessage) (*examples.SimpleMessage, error) { glog.Info(msg) grpc.SendHeader(ctx, metadata.New(map[string]string{ "foo": "foo1", "bar": "bar1", })) grpc.SetTrailer(ctx, metadata.New(map[string]string{ "foo": "foo2", "bar": "bar2", })) return msg, nil }
func NewRaftProxyHealthServer(local HealthServer, connSelector raftpicker.Interface, cluster raftpicker.RaftCluster, ctxMod func(context.Context) (context.Context, error)) HealthServer { redirectChecker := func(ctx context.Context) (context.Context, error) { s, ok := transport.StreamFromContext(ctx) if !ok { return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context") } addr := s.ServerTransport().RemoteAddr().String() md, ok := metadata.FromContext(ctx) if ok && len(md["redirect"]) != 0 { return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"]) } if !ok { md = metadata.New(map[string]string{}) } md["redirect"] = append(md["redirect"], addr) return metadata.NewContext(ctx, md), nil } mods := []func(context.Context) (context.Context, error){redirectChecker} mods = append(mods, ctxMod) return &raftProxyHealthServer{ local: local, cluster: cluster, connSelector: connSelector, ctxMods: mods, } }
func NewRaftProxyResourceAllocatorServer(local ResourceAllocatorServer, connSelector raftselector.ConnProvider, localCtxMod, remoteCtxMod func(context.Context) (context.Context, error)) ResourceAllocatorServer { redirectChecker := func(ctx context.Context) (context.Context, error) { s, ok := transport.StreamFromContext(ctx) if !ok { return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context") } addr := s.ServerTransport().RemoteAddr().String() md, ok := metadata.FromContext(ctx) if ok && len(md["redirect"]) != 0 { return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"]) } if !ok { md = metadata.New(map[string]string{}) } md["redirect"] = append(md["redirect"], addr) return metadata.NewContext(ctx, md), nil } remoteMods := []func(context.Context) (context.Context, error){redirectChecker} remoteMods = append(remoteMods, remoteCtxMod) var localMods []func(context.Context) (context.Context, error) if localCtxMod != nil { localMods = []func(context.Context) (context.Context, error){localCtxMod} } return &raftProxyResourceAllocatorServer{ local: local, connSelector: connSelector, localCtxMods: localMods, remoteCtxMods: remoteMods, } }
// TestTraces makes sure we pass traces via metadata and can decode it back func (s *TrailSuite) TestTraces(c *C) { err := trace.BadParameter("param") meta := metadata.New(nil) SetDebugInfo(err, meta) err2 := FromGRPC(ToGRPC(err), meta) c.Assert(line(trace.DebugReport(err)), Matches, ".*trail_test.go.*") c.Assert(line(trace.DebugReport(err2)), Matches, ".*trail_test.go.*") }
func (s *_ABitOfEverythingServer) Lookup(ctx context.Context, msg *sub2.IdMessage) (*examples.ABitOfEverything, error) { s.m.Lock() defer s.m.Unlock() glog.Info(msg) err := grpc.SendHeader(ctx, metadata.New(map[string]string{ "uuid": msg.Uuid, })) if err != nil { return nil, err } if a, ok := s.v[msg.Uuid]; ok { return a, nil } grpc.SetTrailer(ctx, metadata.New(map[string]string{ "foo": "foo2", "bar": "bar2", })) return nil, grpc.Errorf(codes.NotFound, "not found") }
// Send is a high level function that: // * converts error to GRPC error // * attaches debug metadata to existing metadata if possible // * sends the header to GRPC func Send(ctx context.Context, err error) error { meta, ok := metadata.FromContext(ctx) if !ok { meta = metadata.New(nil) } if trace.IsDebug() { SetDebugInfo(err, meta) } if len(meta) != 0 { sendErr := grpc.SendHeader(ctx, meta) if sendErr != nil { return trace.NewAggregate(err, sendErr) } } return ToGRPC(err) }
// 玩家登陆过程 func P_user_login_req(sess *Session, reader *packet.Packet) []byte { // TODO: 登陆鉴权 // 简单鉴权可以在agent直接完成,通常公司都存在一个用户中心服务器用于鉴权 sess.UserId = 1 // TODO: 选择GAME服务器 // 选服策略依据业务进行,比如小服可以固定选取某台,大服可以采用HASH或一致性HASH sess.GSID = DEFAULT_GSID // 连接到已选定GAME服务器 conn := sp.GetServiceWithId(sp.DEFAULT_SERVICE_PATH+"/game", sess.GSID) if conn == nil { log.Critical("cannot get game service:", sess.GSID) return nil } cli := pb.NewGameServiceClient(conn) // 开启到游戏服的流 ctx := metadata.NewContext(context.Background(), metadata.New(map[string]string{"userid": fmt.Sprint(sess.UserId)})) stream, err := cli.Stream(ctx) if err != nil { log.Critical(err) return nil } sess.Stream = stream // 读取GAME返回消息的goroutine fetcher_task := func(sess *Session) { for { in, err := sess.Stream.Recv() if err == io.EOF { // 流关闭 log.Trace(err) return } if err != nil { log.Error(err) return } select { case sess.MQ <- *in: case <-sess.Die: } } } go fetcher_task(sess) return packet.Pack(Code["user_login_succeed_ack"], S_user_snapshot{F_uid: sess.UserId}, nil) }
func (g *grpcClient) stream(ctx context.Context, address string, req client.Request, opts client.CallOptions) (client.Streamer, error) { header := make(map[string]string) if md, ok := metadata.FromContext(ctx); ok { for k, v := range md { header[k] = v } } // set timeout in nanoseconds header["timeout"] = fmt.Sprintf("%d", opts.RequestTimeout) // set the content type for the request header["x-content-type"] = req.ContentType() md := gmetadata.New(header) ctx = gmetadata.NewContext(ctx, md) cf, err := g.newGRPCCodec(req.ContentType()) if err != nil { return nil, errors.InternalServerError("go.micro.client", err.Error()) } // TODO: do not use insecure cc, err := grpc.Dial(address, grpc.WithCodec(cf), grpc.WithTimeout(opts.DialTimeout), grpc.WithInsecure()) if err != nil { return nil, errors.InternalServerError("go.micro.client", fmt.Sprintf("Error sending request: %v", err)) } desc := &grpc.StreamDesc{ StreamName: req.Service() + req.Method(), ClientStreams: true, ServerStreams: true, } st, err := grpc.NewClientStream(ctx, desc, cc, req.Method()) if err != nil { return nil, errors.InternalServerError("go.micro.client", fmt.Sprintf("Error creating stream: %v", err)) } return &grpcStream{ context: ctx, request: req, closed: make(chan bool), stream: st, conn: cc, }, nil }
func (g *grpcClient) call(ctx context.Context, address string, req client.Request, rsp interface{}, opts client.CallOptions) error { header := make(map[string]string) if md, ok := metadata.FromContext(ctx); ok { for k, v := range md { header[k] = v } } // set timeout in nanoseconds header["timeout"] = fmt.Sprintf("%d", opts.RequestTimeout) // set the content type for the request header["x-content-type"] = req.ContentType() md := gmetadata.New(header) ctx = gmetadata.NewContext(ctx, md) cf, err := g.newGRPCCodec(req.ContentType()) if err != nil { return errors.InternalServerError("go.micro.client", err.Error()) } var grr error // TODO: do not use insecure cc, err := grpc.Dial(address, grpc.WithCodec(cf), grpc.WithTimeout(opts.DialTimeout), grpc.WithInsecure()) if err != nil { return errors.InternalServerError("go.micro.client", fmt.Sprintf("Error sending request: %v", err)) } defer cc.Close() ch := make(chan error, 1) go func() { ch <- grpc.Invoke(ctx, req.Method(), req.Request(), rsp, cc) }() select { case err := <-ch: grr = err case <-ctx.Done(): grr = ctx.Err() } return grr }