mirror of
https://github.com/go-micro/go-micro.git
synced 2024-11-24 08:02:32 +02:00
[feature] stream CloseSend (#2323)
* support stream CloseSend * move CloseSend into Closer
This commit is contained in:
parent
af3cfa0a4c
commit
d2a51d05c4
@ -64,6 +64,7 @@ type Response interface {
|
||||
|
||||
// Stream is the inteface for a bidirectional synchronous stream
|
||||
type Stream interface {
|
||||
Closer
|
||||
// Context for the stream
|
||||
Context() context.Context
|
||||
// The request made
|
||||
@ -80,6 +81,12 @@ type Stream interface {
|
||||
Close() error
|
||||
}
|
||||
|
||||
// Closer handle client close
|
||||
type Closer interface {
|
||||
// CloseSend closes the send direction of the stream.
|
||||
CloseSend() error
|
||||
}
|
||||
|
||||
// Option used by the Client
|
||||
type Option func(*Options)
|
||||
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"go-micro.dev/v4/broker"
|
||||
"go-micro.dev/v4/codec"
|
||||
raw "go-micro.dev/v4/codec/bytes"
|
||||
@ -17,7 +18,6 @@ import (
|
||||
"go-micro.dev/v4/util/buf"
|
||||
"go-micro.dev/v4/util/net"
|
||||
"go-micro.dev/v4/util/pool"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type rpcClient struct {
|
||||
@ -60,7 +60,7 @@ func (r *rpcClient) newCodec(contentType string) (codec.NewCodec, error) {
|
||||
if cf, ok := DefaultCodecs[contentType]; ok {
|
||||
return cf, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Unsupported Content-Type: %s", contentType)
|
||||
return nil, fmt.Errorf("unsupported Content-Type: %s", contentType)
|
||||
}
|
||||
|
||||
func (r *rpcClient) call(ctx context.Context, node *registry.Node, req Request, resp interface{}, opts CallOptions) error {
|
||||
|
@ -2,6 +2,7 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
@ -129,6 +130,10 @@ func (r *rpcStream) Error() error {
|
||||
return r.err
|
||||
}
|
||||
|
||||
func (r *rpcStream) CloseSend() error {
|
||||
return errors.New("streamer not implemented")
|
||||
}
|
||||
|
||||
func (r *rpcStream) Close() error {
|
||||
r.Lock()
|
||||
|
||||
|
@ -3,7 +3,7 @@ module github.com/asim/go-micro/cmd/protoc-gen-micro/v4
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
go-micro.dev/v4 v4.1.0
|
||||
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8
|
||||
go-micro.dev/v4 v4.2.1
|
||||
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c
|
||||
google.golang.org/protobuf v1.27.1
|
||||
)
|
||||
|
@ -301,11 +301,9 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labbsr0x/bindman-dns-webhook v1.0.2/go.mod h1:p6b+VCXIR8NYKpDr8/dg1HKfQoRHCdcsROXKvmoehKA=
|
||||
github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w=
|
||||
@ -490,9 +488,8 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go-micro.dev/v4 v4.1.0 h1:XXZWlKhSpkQZTvPKcXRP5JvJoqbVhV+p/UUIfdVgN7E=
|
||||
go-micro.dev/v4 v4.1.0/go.mod h1:XTEJj5ILOBW+2ndGDG56r8fBXZ8hmsVaIaS1K5zwj+s=
|
||||
go-micro.dev/v4 v4.2.1 h1:1E+zymteWxvDLpo4EDixRmXC+ELOAyFGfOdO60ScVbU=
|
||||
go-micro.dev/v4 v4.2.1/go.mod h1:XTEJj5ILOBW+2ndGDG56r8fBXZ8hmsVaIaS1K5zwj+s=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
@ -546,7 +543,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
@ -555,7 +551,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -724,7 +719,6 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -766,8 +760,8 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfG
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8 h1:XosVttQUxX8erNhEruTu053/VchgYuksoS9Bj/OITjU=
|
||||
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c h1:FqrtZMB5Wr+/RecOM3uPJNPfWR8Upb5hAPnt7PU6i4k=
|
||||
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
@ -800,7 +794,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
|
@ -363,6 +363,8 @@ func (g *micro) generateClientMethod(reqServ, servName, serviceDescVar string, m
|
||||
|
||||
if !method.GetClientStreaming() {
|
||||
g.P("if err := stream.Send(in); err != nil { return nil, err }")
|
||||
// TODO: currently only grpc support CloseSend
|
||||
// g.P("if err := stream.CloseSend(); err != nil { return nil, err }")
|
||||
}
|
||||
|
||||
g.P("return &", streamType, "{stream}, nil")
|
||||
@ -377,6 +379,7 @@ func (g *micro) generateClientMethod(reqServ, servName, serviceDescVar string, m
|
||||
g.P("Context() context.Context")
|
||||
g.P("SendMsg(interface{}) error")
|
||||
g.P("RecvMsg(interface{}) error")
|
||||
g.P("CloseSend() error")
|
||||
g.P("Close() error")
|
||||
|
||||
if genSend {
|
||||
@ -393,6 +396,11 @@ func (g *micro) generateClientMethod(reqServ, servName, serviceDescVar string, m
|
||||
g.P("}")
|
||||
g.P()
|
||||
|
||||
g.P("func (x *", streamType, ") CloseSend() error {")
|
||||
g.P("return x.stream.CloseSend()")
|
||||
g.P("}")
|
||||
g.P()
|
||||
|
||||
g.P("func (x *", streamType, ") Close() error {")
|
||||
g.P("return x.stream.Close()")
|
||||
g.P("}")
|
||||
|
@ -4,25 +4,35 @@ go 1.16
|
||||
|
||||
replace (
|
||||
github.com/asim/go-micro/plugins/client/grpc/v4 => ../plugins/client/grpc
|
||||
github.com/asim/go-micro/plugins/client/http/v4 => ../plugins/client/http
|
||||
github.com/asim/go-micro/plugins/config/encoder/toml/v4 => ../plugins/config/encoder/toml
|
||||
github.com/asim/go-micro/plugins/config/encoder/yaml/v4 => ../plugins/config/encoder/yaml
|
||||
github.com/asim/go-micro/plugins/config/source/grpc/v4 => ../plugins/config/source/grpc
|
||||
github.com/asim/go-micro/plugins/server/grpc/v4 => ../plugins/server/grpc
|
||||
github.com/asim/go-micro/plugins/server/http/v4 => ../plugins/server/http
|
||||
github.com/asim/go-micro/plugins/transport/grpc/v4 => ../plugins/transport/grpc
|
||||
github.com/asim/go-micro/plugins/wrapper/select/roundrobin/v4 => ../plugins/wrapper/select/roundrobin
|
||||
github.com/asim/go-micro/plugins/wrapper/select/shard/v4 => ../plugins/wrapper/select/shard
|
||||
go-micro.dev/v4 => ../../go-micro
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/asim/go-micro/plugins/client/http/v4 v4.0.0-20211022143028-f96b48dad9f9
|
||||
github.com/asim/go-micro/plugins/config/encoder/toml/v4 v4.0.0-20211022143028-f96b48dad9f9
|
||||
github.com/asim/go-micro/plugins/config/encoder/yaml/v4 v4.0.0-20211022143028-f96b48dad9f9
|
||||
github.com/asim/go-micro/plugins/config/source/grpc/v4 v4.0.0-20211022143028-f96b48dad9f9
|
||||
github.com/asim/go-micro/plugins/server/http/v4 v4.0.0-20211022143028-f96b48dad9f9
|
||||
github.com/asim/go-micro/plugins/wrapper/select/roundrobin/v4 v4.0.0-20211022143028-f96b48dad9f9
|
||||
github.com/asim/go-micro/plugins/wrapper/select/shard/v4 v4.0.0-20211022143028-f96b48dad9f9
|
||||
github.com/asim/go-micro/plugins/client/grpc/v4 v4.0.0-20211019191242-9edc569e68bb
|
||||
github.com/asim/go-micro/plugins/client/http/v4 v4.0.0-00010101000000-000000000000
|
||||
github.com/asim/go-micro/plugins/config/encoder/toml/v4 v4.0.0-00010101000000-000000000000
|
||||
github.com/asim/go-micro/plugins/config/encoder/yaml/v4 v4.0.0-00010101000000-000000000000
|
||||
github.com/asim/go-micro/plugins/config/source/grpc/v4 v4.0.0-00010101000000-000000000000
|
||||
github.com/asim/go-micro/plugins/server/grpc/v4 v4.0.0-00010101000000-000000000000
|
||||
github.com/asim/go-micro/plugins/server/http/v4 v4.0.0-00010101000000-000000000000
|
||||
github.com/asim/go-micro/plugins/wrapper/select/roundrobin/v4 v4.0.0-00010101000000-000000000000
|
||||
github.com/asim/go-micro/plugins/wrapper/select/shard/v4 v4.0.0-00010101000000-000000000000
|
||||
github.com/gin-gonic/gin v1.7.4
|
||||
github.com/golang/glog v1.0.0
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||
github.com/pborman/uuid v1.2.1
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
go-micro.dev/v4 v4.1.0
|
||||
go-micro.dev/v4 v4.2.1
|
||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309
|
||||
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c
|
||||
google.golang.org/grpc v1.41.0
|
||||
|
@ -70,22 +70,6 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/asim/go-micro/plugins/client/http/v4 v4.0.0-20211022143028-f96b48dad9f9 h1:17x43QitBDfbMjtFcpI2ecAc5PpEDdhNjtiotjqYKq8=
|
||||
github.com/asim/go-micro/plugins/client/http/v4 v4.0.0-20211022143028-f96b48dad9f9/go.mod h1:eCRnBm4m255UbIZw2tabc+wVZQ3ZRP8MWkRbn0MhMbE=
|
||||
github.com/asim/go-micro/plugins/config/encoder/toml/v4 v4.0.0-20211022143028-f96b48dad9f9 h1:OCoe8T41NrRb8gL/2Q3norzCFVubygzzkoeF46YU+XI=
|
||||
github.com/asim/go-micro/plugins/config/encoder/toml/v4 v4.0.0-20211022143028-f96b48dad9f9/go.mod h1:Hi2yzGSStKJbJo+9+EpXMwUi8KPd4hLgX4mOrz8c0oA=
|
||||
github.com/asim/go-micro/plugins/config/encoder/yaml/v4 v4.0.0-20211022143028-f96b48dad9f9 h1:n8EoXmlUJp0IkdUiPUysNM6bJ0QFWdM18oY6EOTy5PY=
|
||||
github.com/asim/go-micro/plugins/config/encoder/yaml/v4 v4.0.0-20211022143028-f96b48dad9f9/go.mod h1:DJsLvPsBo+CNTCPLejskeLjRupUWFF+ypQAEkUhw4iI=
|
||||
github.com/asim/go-micro/plugins/config/source/grpc/v4 v4.0.0-20211022143028-f96b48dad9f9 h1:mIgRuPdmQJbQKY7wkRRPyzKbcSEwkO1x8C9T9EOp1Bo=
|
||||
github.com/asim/go-micro/plugins/config/source/grpc/v4 v4.0.0-20211022143028-f96b48dad9f9/go.mod h1:8WKLbh9L7FP4RViRq3S1CZ7nv0mdapt1Al9w91j0Cjk=
|
||||
github.com/asim/go-micro/plugins/registry/memory/v4 v4.0.0-20211013123123-62801c3d6883 h1:Kt/XROVWpqglcjjiEq26KSwDYhSLsGL6NAEaukteuvc=
|
||||
github.com/asim/go-micro/plugins/registry/memory/v4 v4.0.0-20211013123123-62801c3d6883/go.mod h1:cSvG1suZrBwXQZm1H+v4ZHSrDxmGqJO4RV5O1gpmllM=
|
||||
github.com/asim/go-micro/plugins/server/http/v4 v4.0.0-20211022143028-f96b48dad9f9 h1:SW0nzvYDIyBFMp3ssny7+rtBcbNPQfpMYTXegnJ1Wt0=
|
||||
github.com/asim/go-micro/plugins/server/http/v4 v4.0.0-20211022143028-f96b48dad9f9/go.mod h1:IJBO19ayd3T0SO72e7kcW2zN3RxaeI1zYEtWvQfc67M=
|
||||
github.com/asim/go-micro/plugins/wrapper/select/roundrobin/v4 v4.0.0-20211022143028-f96b48dad9f9 h1:RBORITx0x74gDZTk+tohG+nbDFIhgcyPmLUqflWSxGA=
|
||||
github.com/asim/go-micro/plugins/wrapper/select/roundrobin/v4 v4.0.0-20211022143028-f96b48dad9f9/go.mod h1:g3/YAex/PPKlfludcWp/NLqHbTUUQY5HGjCgsKGgOok=
|
||||
github.com/asim/go-micro/plugins/wrapper/select/shard/v4 v4.0.0-20211022143028-f96b48dad9f9 h1:53epXCMQs/5BEHxoV4C0HxQhEcMB+eoiiU5ic0uosHQ=
|
||||
github.com/asim/go-micro/plugins/wrapper/select/shard/v4 v4.0.0-20211022143028-f96b48dad9f9/go.mod h1:V0bMYEIWuaB+TdpgrsYiLUg708JwSeX8whK65tT0J6g=
|
||||
github.com/aws/aws-sdk-go v1.37.27/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
@ -842,6 +826,8 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfG
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20211020151524-b7c3a969101a/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c h1:FqrtZMB5Wr+/RecOM3uPJNPfWR8Upb5hAPnt7PU6i4k=
|
||||
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
@ -861,6 +847,8 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E=
|
||||
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
||||
google.golang.org/grpc/examples v0.0.0-20211020220737-f00baa6c3c84 h1:vTEaoYojw/smuQT/Fva/AX+2Bnla97/oRbY75XFhg40=
|
||||
google.golang.org/grpc/examples v0.0.0-20211020220737-f00baa6c3c84/go.mod h1:gID3PKrg7pWKntu9Ss6zTLJ0ttC0X9IHgREOCZwbCVU=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@ -869,6 +857,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
|
26
examples/stream/grpc/README.md
Normal file
26
examples/stream/grpc/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Description
|
||||
|
||||
This example is translate [go grpc example](https://grpc.io/docs/languages/go/basics/) into go-micro.
|
||||
You can also find the orignal codes in [github.com/grpc/grpc-go](https://github.com/grpc/grpc-go/tree/master/examples/route_guide).
|
||||
|
||||
# Run the sample code
|
||||
|
||||
## Protobuf
|
||||
|
||||
```shell
|
||||
protoc --go_out=proto --micro_out=proto proto/route_guide.proto
|
||||
```
|
||||
|
||||
## Server
|
||||
|
||||
```shell
|
||||
cd stream/gprc/server
|
||||
go run .
|
||||
```
|
||||
|
||||
## Client
|
||||
|
||||
```shell
|
||||
cd stream/client
|
||||
go run main.go
|
||||
```
|
161
examples/stream/grpc/client/main.go
Normal file
161
examples/stream/grpc/client/main.go
Normal file
@ -0,0 +1,161 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
pb "github.com/asim/go-micro/examples/v4/stream/grpc/proto"
|
||||
"github.com/asim/go-micro/plugins/client/grpc/v4"
|
||||
"go-micro.dev/v4"
|
||||
"go-micro.dev/v4/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
srv := micro.NewService(
|
||||
micro.Client(grpc.NewClient()),
|
||||
micro.Name("stream-client"),
|
||||
)
|
||||
srv.Init()
|
||||
client := pb.NewRouteGuideService("stream-server", srv.Client())
|
||||
|
||||
for {
|
||||
// Looking for a valid feature
|
||||
printFeature(client, &pb.Point{Latitude: 409146138, Longitude: -746188906})
|
||||
// Feature missing.
|
||||
printFeature(client, &pb.Point{Latitude: 0, Longitude: 0})
|
||||
// Looking for features between 40, -75 and 42, -73.
|
||||
printFeatures(client, &pb.Rectangle{
|
||||
Lo: &pb.Point{Latitude: 400000000, Longitude: -750000000},
|
||||
Hi: &pb.Point{Latitude: 420000000, Longitude: -730000000},
|
||||
})
|
||||
|
||||
// RecordRoute
|
||||
runRecordRoute(client)
|
||||
|
||||
// RouteChat
|
||||
runRouteChat(client)
|
||||
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// printFeature gets the feature for the given point.
|
||||
func printFeature(client pb.RouteGuideService, point *pb.Point) {
|
||||
logger.Info("Getting feature for point (%d, %d)", point.Latitude, point.Longitude)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
feature, err := client.GetFeature(ctx, point)
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
logger.Info(feature)
|
||||
}
|
||||
|
||||
// printFeatures lists all the features within the given bounding Rectangle.
|
||||
func printFeatures(client pb.RouteGuideService, rect *pb.Rectangle) {
|
||||
logger.Infof("Looking for features within %v", rect)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
stream, err := client.ListFeatures(ctx, rect)
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
// IMPORTANT: do not forgot to close stream
|
||||
defer stream.Close()
|
||||
for {
|
||||
feature, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
logger.Infof("Feature: name: %q, point:(%v, %v)", feature.GetName(),
|
||||
feature.GetLocation().GetLatitude(), feature.GetLocation().GetLongitude())
|
||||
}
|
||||
}
|
||||
|
||||
// runRecordRoute sends a sequence of points to server and expects to get a RouteSummary from server.
|
||||
func runRecordRoute(client pb.RouteGuideService) {
|
||||
// Create a random number of random points
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
pointCount := int(r.Int31n(100)) + 2 // Traverse at least two points
|
||||
var points []*pb.Point
|
||||
for i := 0; i < pointCount; i++ {
|
||||
points = append(points, randomPoint(r))
|
||||
}
|
||||
logger.Infof("Traversing %d points.", len(points))
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
stream, err := client.RecordRoute(ctx)
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
// IMPORTANT: do not forgot to close stream
|
||||
defer stream.Close()
|
||||
for _, point := range points {
|
||||
if err := stream.Send(point); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := stream.CloseSend(); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
summary := pb.RouteSummary{}
|
||||
if err := stream.RecvMsg(&summary); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
logger.Infof("Route summary: %v", &summary)
|
||||
}
|
||||
|
||||
// runRouteChat receives a sequence of route notes, while sending notes for various locations.
|
||||
func runRouteChat(client pb.RouteGuideService) {
|
||||
notes := []*pb.RouteNote{
|
||||
{Location: &pb.Point{Latitude: 0, Longitude: 1}, Message: "First message"},
|
||||
{Location: &pb.Point{Latitude: 0, Longitude: 2}, Message: "Second message"},
|
||||
{Location: &pb.Point{Latitude: 0, Longitude: 3}, Message: "Third message"},
|
||||
{Location: &pb.Point{Latitude: 0, Longitude: 1}, Message: "Fourth message"},
|
||||
{Location: &pb.Point{Latitude: 0, Longitude: 2}, Message: "Fifth message"},
|
||||
{Location: &pb.Point{Latitude: 0, Longitude: 3}, Message: "Sixth message"},
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
stream, err := client.RouteChat(ctx)
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
// IMPORTANT: do not forgot to close stream
|
||||
defer stream.Close()
|
||||
waitc := make(chan struct{})
|
||||
go func() {
|
||||
for {
|
||||
in, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
// read done.
|
||||
close(waitc)
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
logger.Infof("Got message %s at point(%d, %d)", in.Message, in.Location.Latitude, in.Location.Longitude)
|
||||
}
|
||||
}()
|
||||
for _, note := range notes {
|
||||
if err := stream.Send(note); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := stream.CloseSend(); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
<-waitc
|
||||
}
|
||||
|
||||
func randomPoint(r *rand.Rand) *pb.Point {
|
||||
lat := (r.Int31n(180) - 90) * 1e7
|
||||
long := (r.Int31n(360) - 180) * 1e7
|
||||
return &pb.Point{Latitude: lat, Longitude: long}
|
||||
}
|
514
examples/stream/grpc/proto/route_guide.pb.go
Normal file
514
examples/stream/grpc/proto/route_guide.pb.go
Normal file
@ -0,0 +1,514 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.15.6
|
||||
// source: proto/route_guide.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
// Points are represented as latitude-longitude pairs in the E7 representation
|
||||
// (degrees multiplied by 10**7 and rounded to the nearest integer).
|
||||
// Latitudes should be in the range +/- 90 degrees and longitude should be in
|
||||
// the range +/- 180 degrees (inclusive).
|
||||
type Point struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Latitude int32 `protobuf:"varint,1,opt,name=latitude,proto3" json:"latitude,omitempty"`
|
||||
Longitude int32 `protobuf:"varint,2,opt,name=longitude,proto3" json:"longitude,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Point) Reset() {
|
||||
*x = Point{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_route_guide_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Point) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Point) ProtoMessage() {}
|
||||
|
||||
func (x *Point) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_route_guide_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Point.ProtoReflect.Descriptor instead.
|
||||
func (*Point) Descriptor() ([]byte, []int) {
|
||||
return file_proto_route_guide_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Point) GetLatitude() int32 {
|
||||
if x != nil {
|
||||
return x.Latitude
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Point) GetLongitude() int32 {
|
||||
if x != nil {
|
||||
return x.Longitude
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// A latitude-longitude rectangle, represented as two diagonally opposite
|
||||
// points "lo" and "hi".
|
||||
type Rectangle struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// One corner of the rectangle.
|
||||
Lo *Point `protobuf:"bytes,1,opt,name=lo,proto3" json:"lo,omitempty"`
|
||||
// The other corner of the rectangle.
|
||||
Hi *Point `protobuf:"bytes,2,opt,name=hi,proto3" json:"hi,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Rectangle) Reset() {
|
||||
*x = Rectangle{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_route_guide_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Rectangle) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Rectangle) ProtoMessage() {}
|
||||
|
||||
func (x *Rectangle) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_route_guide_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Rectangle.ProtoReflect.Descriptor instead.
|
||||
func (*Rectangle) Descriptor() ([]byte, []int) {
|
||||
return file_proto_route_guide_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Rectangle) GetLo() *Point {
|
||||
if x != nil {
|
||||
return x.Lo
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Rectangle) GetHi() *Point {
|
||||
if x != nil {
|
||||
return x.Hi
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A feature names something at a given point.
|
||||
//
|
||||
// If a feature could not be named, the name is empty.
|
||||
type Feature struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The name of the feature.
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
// The point where the feature is detected.
|
||||
Location *Point `protobuf:"bytes,2,opt,name=location,proto3" json:"location,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Feature) Reset() {
|
||||
*x = Feature{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_route_guide_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Feature) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Feature) ProtoMessage() {}
|
||||
|
||||
func (x *Feature) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_route_guide_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Feature.ProtoReflect.Descriptor instead.
|
||||
func (*Feature) Descriptor() ([]byte, []int) {
|
||||
return file_proto_route_guide_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *Feature) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Feature) GetLocation() *Point {
|
||||
if x != nil {
|
||||
return x.Location
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A RouteNote is a message sent while at a given point.
|
||||
type RouteNote struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The location from which the message is sent.
|
||||
Location *Point `protobuf:"bytes,1,opt,name=location,proto3" json:"location,omitempty"`
|
||||
// The message to be sent.
|
||||
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RouteNote) Reset() {
|
||||
*x = RouteNote{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_route_guide_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RouteNote) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RouteNote) ProtoMessage() {}
|
||||
|
||||
func (x *RouteNote) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_route_guide_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RouteNote.ProtoReflect.Descriptor instead.
|
||||
func (*RouteNote) Descriptor() ([]byte, []int) {
|
||||
return file_proto_route_guide_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *RouteNote) GetLocation() *Point {
|
||||
if x != nil {
|
||||
return x.Location
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *RouteNote) GetMessage() string {
|
||||
if x != nil {
|
||||
return x.Message
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// A RouteSummary is received in response to a RecordRoute rpc.
|
||||
//
|
||||
// It contains the number of individual points received, the number of
|
||||
// detected features, and the total distance covered as the cumulative sum of
|
||||
// the distance between each point.
|
||||
type RouteSummary struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The number of points received.
|
||||
PointCount int32 `protobuf:"varint,1,opt,name=point_count,json=pointCount,proto3" json:"point_count,omitempty"`
|
||||
// The number of known features passed while traversing the route.
|
||||
FeatureCount int32 `protobuf:"varint,2,opt,name=feature_count,json=featureCount,proto3" json:"feature_count,omitempty"`
|
||||
// The distance covered in metres.
|
||||
Distance int32 `protobuf:"varint,3,opt,name=distance,proto3" json:"distance,omitempty"`
|
||||
// The duration of the traversal in seconds.
|
||||
ElapsedTime int32 `protobuf:"varint,4,opt,name=elapsed_time,json=elapsedTime,proto3" json:"elapsed_time,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RouteSummary) Reset() {
|
||||
*x = RouteSummary{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_route_guide_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RouteSummary) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RouteSummary) ProtoMessage() {}
|
||||
|
||||
func (x *RouteSummary) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_route_guide_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RouteSummary.ProtoReflect.Descriptor instead.
|
||||
func (*RouteSummary) Descriptor() ([]byte, []int) {
|
||||
return file_proto_route_guide_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *RouteSummary) GetPointCount() int32 {
|
||||
if x != nil {
|
||||
return x.PointCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RouteSummary) GetFeatureCount() int32 {
|
||||
if x != nil {
|
||||
return x.FeatureCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RouteSummary) GetDistance() int32 {
|
||||
if x != nil {
|
||||
return x.Distance
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RouteSummary) GetElapsedTime() int32 {
|
||||
if x != nil {
|
||||
return x.ElapsedTime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_proto_route_guide_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_proto_route_guide_proto_rawDesc = []byte{
|
||||
0x0a, 0x17, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x67, 0x75,
|
||||
0x69, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x22, 0x41, 0x0a, 0x05, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x74,
|
||||
0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6c, 0x61, 0x74,
|
||||
0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75,
|
||||
0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74,
|
||||
0x75, 0x64, 0x65, 0x22, 0x47, 0x0a, 0x09, 0x52, 0x65, 0x63, 0x74, 0x61, 0x6e, 0x67, 0x6c, 0x65,
|
||||
0x12, 0x1c, 0x0a, 0x02, 0x6c, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x02, 0x6c, 0x6f, 0x12, 0x1c,
|
||||
0x0a, 0x02, 0x68, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x02, 0x68, 0x69, 0x22, 0x47, 0x0a, 0x07,
|
||||
0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x08, 0x6c,
|
||||
0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x08, 0x6c, 0x6f, 0x63,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x4f, 0x0a, 0x09, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x6f,
|
||||
0x74, 0x65, 0x12, 0x28, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x6f, 0x69,
|
||||
0x6e, 0x74, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07,
|
||||
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x93, 0x01, 0x0a, 0x0c, 0x52, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x69, 0x6e, 0x74,
|
||||
0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x70, 0x6f,
|
||||
0x69, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x65, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x0c, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a,
|
||||
0x08, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x08, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x6c, 0x61,
|
||||
0x70, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x0b, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x32, 0xdd, 0x01, 0x0a,
|
||||
0x0a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x47, 0x75, 0x69, 0x64, 0x65, 0x12, 0x2c, 0x0a, 0x0a, 0x47,
|
||||
0x65, 0x74, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
|
||||
0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x0c, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2e, 0x52, 0x65, 0x63, 0x74, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x1a, 0x0e, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12,
|
||||
0x34, 0x0a, 0x0b, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x0c,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x1a, 0x13, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72,
|
||||
0x79, 0x22, 0x00, 0x28, 0x01, 0x12, 0x35, 0x0a, 0x09, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x43, 0x68,
|
||||
0x61, 0x74, 0x12, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x4e, 0x6f, 0x74, 0x65, 0x1a, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x0a, 0x5a, 0x08,
|
||||
0x2e, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_proto_route_guide_proto_rawDescOnce sync.Once
|
||||
file_proto_route_guide_proto_rawDescData = file_proto_route_guide_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_proto_route_guide_proto_rawDescGZIP() []byte {
|
||||
file_proto_route_guide_proto_rawDescOnce.Do(func() {
|
||||
file_proto_route_guide_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_route_guide_proto_rawDescData)
|
||||
})
|
||||
return file_proto_route_guide_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_route_guide_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_proto_route_guide_proto_goTypes = []interface{}{
|
||||
(*Point)(nil), // 0: proto.Point
|
||||
(*Rectangle)(nil), // 1: proto.Rectangle
|
||||
(*Feature)(nil), // 2: proto.Feature
|
||||
(*RouteNote)(nil), // 3: proto.RouteNote
|
||||
(*RouteSummary)(nil), // 4: proto.RouteSummary
|
||||
}
|
||||
var file_proto_route_guide_proto_depIdxs = []int32{
|
||||
0, // 0: proto.Rectangle.lo:type_name -> proto.Point
|
||||
0, // 1: proto.Rectangle.hi:type_name -> proto.Point
|
||||
0, // 2: proto.Feature.location:type_name -> proto.Point
|
||||
0, // 3: proto.RouteNote.location:type_name -> proto.Point
|
||||
0, // 4: proto.RouteGuide.GetFeature:input_type -> proto.Point
|
||||
1, // 5: proto.RouteGuide.ListFeatures:input_type -> proto.Rectangle
|
||||
0, // 6: proto.RouteGuide.RecordRoute:input_type -> proto.Point
|
||||
3, // 7: proto.RouteGuide.RouteChat:input_type -> proto.RouteNote
|
||||
2, // 8: proto.RouteGuide.GetFeature:output_type -> proto.Feature
|
||||
2, // 9: proto.RouteGuide.ListFeatures:output_type -> proto.Feature
|
||||
4, // 10: proto.RouteGuide.RecordRoute:output_type -> proto.RouteSummary
|
||||
3, // 11: proto.RouteGuide.RouteChat:output_type -> proto.RouteNote
|
||||
8, // [8:12] is the sub-list for method output_type
|
||||
4, // [4:8] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
4, // [4:4] is the sub-list for extension extendee
|
||||
0, // [0:4] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_route_guide_proto_init() }
|
||||
func file_proto_route_guide_proto_init() {
|
||||
if File_proto_route_guide_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_proto_route_guide_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Point); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_route_guide_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Rectangle); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_route_guide_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Feature); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_route_guide_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RouteNote); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_route_guide_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RouteSummary); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_route_guide_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 5,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_proto_route_guide_proto_goTypes,
|
||||
DependencyIndexes: file_proto_route_guide_proto_depIdxs,
|
||||
MessageInfos: file_proto_route_guide_proto_msgTypes,
|
||||
}.Build()
|
||||
File_proto_route_guide_proto = out.File
|
||||
file_proto_route_guide_proto_rawDesc = nil
|
||||
file_proto_route_guide_proto_goTypes = nil
|
||||
file_proto_route_guide_proto_depIdxs = nil
|
||||
}
|
420
examples/stream/grpc/proto/route_guide.pb.micro.go
Normal file
420
examples/stream/grpc/proto/route_guide.pb.micro.go
Normal file
@ -0,0 +1,420 @@
|
||||
// Code generated by protoc-gen-micro. DO NOT EDIT.
|
||||
// source: proto/route_guide.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "google.golang.org/protobuf/proto"
|
||||
math "math"
|
||||
)
|
||||
|
||||
import (
|
||||
context "context"
|
||||
api "go-micro.dev/v4/api"
|
||||
client "go-micro.dev/v4/client"
|
||||
server "go-micro.dev/v4/server"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ api.Endpoint
|
||||
var _ context.Context
|
||||
var _ client.Option
|
||||
var _ server.Option
|
||||
|
||||
// Api Endpoints for RouteGuide service
|
||||
|
||||
func NewRouteGuideEndpoints() []*api.Endpoint {
|
||||
return []*api.Endpoint{}
|
||||
}
|
||||
|
||||
// Client API for RouteGuide service
|
||||
|
||||
type RouteGuideService interface {
|
||||
// A simple RPC.
|
||||
//
|
||||
// Obtains the feature at a given position.
|
||||
//
|
||||
// A feature with an empty name is returned if there's no feature at the given
|
||||
// position.
|
||||
GetFeature(ctx context.Context, in *Point, opts ...client.CallOption) (*Feature, error)
|
||||
// A server-to-client streaming RPC.
|
||||
//
|
||||
// Obtains the Features available within the given Rectangle. Results are
|
||||
// streamed rather than returned at once (e.g. in a response message with a
|
||||
// repeated field), as the rectangle may cover a large area and contain a
|
||||
// huge number of features.
|
||||
ListFeatures(ctx context.Context, in *Rectangle, opts ...client.CallOption) (RouteGuide_ListFeaturesService, error)
|
||||
// A client-to-server streaming RPC.
|
||||
//
|
||||
// Accepts a stream of Points on a route being traversed, returning a
|
||||
// RouteSummary when traversal is completed.
|
||||
RecordRoute(ctx context.Context, opts ...client.CallOption) (RouteGuide_RecordRouteService, error)
|
||||
// A Bidirectional streaming RPC.
|
||||
//
|
||||
// Accepts a stream of RouteNotes sent while a route is being traversed,
|
||||
// while receiving other RouteNotes (e.g. from other users).
|
||||
RouteChat(ctx context.Context, opts ...client.CallOption) (RouteGuide_RouteChatService, error)
|
||||
}
|
||||
|
||||
type routeGuideService struct {
|
||||
c client.Client
|
||||
name string
|
||||
}
|
||||
|
||||
func NewRouteGuideService(name string, c client.Client) RouteGuideService {
|
||||
return &routeGuideService{
|
||||
c: c,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *routeGuideService) GetFeature(ctx context.Context, in *Point, opts ...client.CallOption) (*Feature, error) {
|
||||
req := c.c.NewRequest(c.name, "RouteGuide.GetFeature", in)
|
||||
out := new(Feature)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *routeGuideService) ListFeatures(ctx context.Context, in *Rectangle, opts ...client.CallOption) (RouteGuide_ListFeaturesService, error) {
|
||||
req := c.c.NewRequest(c.name, "RouteGuide.ListFeatures", &Rectangle{})
|
||||
stream, err := c.c.Stream(ctx, req, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := stream.Send(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := stream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &routeGuideServiceListFeatures{stream}, nil
|
||||
}
|
||||
|
||||
type RouteGuide_ListFeaturesService interface {
|
||||
Context() context.Context
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
CloseSend() error
|
||||
Close() error
|
||||
Recv() (*Feature, error)
|
||||
}
|
||||
|
||||
type routeGuideServiceListFeatures struct {
|
||||
stream client.Stream
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceListFeatures) CloseSend() error {
|
||||
return x.stream.CloseSend()
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceListFeatures) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceListFeatures) Context() context.Context {
|
||||
return x.stream.Context()
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceListFeatures) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceListFeatures) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceListFeatures) Recv() (*Feature, error) {
|
||||
m := new(Feature)
|
||||
err := x.stream.Recv(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *routeGuideService) RecordRoute(ctx context.Context, opts ...client.CallOption) (RouteGuide_RecordRouteService, error) {
|
||||
req := c.c.NewRequest(c.name, "RouteGuide.RecordRoute", &Point{})
|
||||
stream, err := c.c.Stream(ctx, req, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &routeGuideServiceRecordRoute{stream}, nil
|
||||
}
|
||||
|
||||
type RouteGuide_RecordRouteService interface {
|
||||
Context() context.Context
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
CloseSend() error
|
||||
Close() error
|
||||
Send(*Point) error
|
||||
}
|
||||
|
||||
type routeGuideServiceRecordRoute struct {
|
||||
stream client.Stream
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRecordRoute) CloseSend() error {
|
||||
return x.stream.CloseSend()
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRecordRoute) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRecordRoute) Context() context.Context {
|
||||
return x.stream.Context()
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRecordRoute) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRecordRoute) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRecordRoute) Send(m *Point) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (c *routeGuideService) RouteChat(ctx context.Context, opts ...client.CallOption) (RouteGuide_RouteChatService, error) {
|
||||
req := c.c.NewRequest(c.name, "RouteGuide.RouteChat", &RouteNote{})
|
||||
stream, err := c.c.Stream(ctx, req, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &routeGuideServiceRouteChat{stream}, nil
|
||||
}
|
||||
|
||||
type RouteGuide_RouteChatService interface {
|
||||
Context() context.Context
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
CloseSend() error
|
||||
Close() error
|
||||
Send(*RouteNote) error
|
||||
Recv() (*RouteNote, error)
|
||||
}
|
||||
|
||||
type routeGuideServiceRouteChat struct {
|
||||
stream client.Stream
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRouteChat) CloseSend() error {
|
||||
return x.stream.CloseSend()
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRouteChat) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRouteChat) Context() context.Context {
|
||||
return x.stream.Context()
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRouteChat) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRouteChat) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRouteChat) Send(m *RouteNote) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideServiceRouteChat) Recv() (*RouteNote, error) {
|
||||
m := new(RouteNote)
|
||||
err := x.stream.Recv(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// Server API for RouteGuide service
|
||||
|
||||
type RouteGuideHandler interface {
|
||||
// A simple RPC.
|
||||
//
|
||||
// Obtains the feature at a given position.
|
||||
//
|
||||
// A feature with an empty name is returned if there's no feature at the given
|
||||
// position.
|
||||
GetFeature(context.Context, *Point, *Feature) error
|
||||
// A server-to-client streaming RPC.
|
||||
//
|
||||
// Obtains the Features available within the given Rectangle. Results are
|
||||
// streamed rather than returned at once (e.g. in a response message with a
|
||||
// repeated field), as the rectangle may cover a large area and contain a
|
||||
// huge number of features.
|
||||
ListFeatures(context.Context, *Rectangle, RouteGuide_ListFeaturesStream) error
|
||||
// A client-to-server streaming RPC.
|
||||
//
|
||||
// Accepts a stream of Points on a route being traversed, returning a
|
||||
// RouteSummary when traversal is completed.
|
||||
RecordRoute(context.Context, RouteGuide_RecordRouteStream) error
|
||||
// A Bidirectional streaming RPC.
|
||||
//
|
||||
// Accepts a stream of RouteNotes sent while a route is being traversed,
|
||||
// while receiving other RouteNotes (e.g. from other users).
|
||||
RouteChat(context.Context, RouteGuide_RouteChatStream) error
|
||||
}
|
||||
|
||||
func RegisterRouteGuideHandler(s server.Server, hdlr RouteGuideHandler, opts ...server.HandlerOption) error {
|
||||
type routeGuide interface {
|
||||
GetFeature(ctx context.Context, in *Point, out *Feature) error
|
||||
ListFeatures(ctx context.Context, stream server.Stream) error
|
||||
RecordRoute(ctx context.Context, stream server.Stream) error
|
||||
RouteChat(ctx context.Context, stream server.Stream) error
|
||||
}
|
||||
type RouteGuide struct {
|
||||
routeGuide
|
||||
}
|
||||
h := &routeGuideHandler{hdlr}
|
||||
return s.Handle(s.NewHandler(&RouteGuide{h}, opts...))
|
||||
}
|
||||
|
||||
type routeGuideHandler struct {
|
||||
RouteGuideHandler
|
||||
}
|
||||
|
||||
func (h *routeGuideHandler) GetFeature(ctx context.Context, in *Point, out *Feature) error {
|
||||
return h.RouteGuideHandler.GetFeature(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *routeGuideHandler) ListFeatures(ctx context.Context, stream server.Stream) error {
|
||||
m := new(Rectangle)
|
||||
if err := stream.Recv(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return h.RouteGuideHandler.ListFeatures(ctx, m, &routeGuideListFeaturesStream{stream})
|
||||
}
|
||||
|
||||
type RouteGuide_ListFeaturesStream interface {
|
||||
Context() context.Context
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
Close() error
|
||||
Send(*Feature) error
|
||||
}
|
||||
|
||||
type routeGuideListFeaturesStream struct {
|
||||
stream server.Stream
|
||||
}
|
||||
|
||||
func (x *routeGuideListFeaturesStream) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *routeGuideListFeaturesStream) Context() context.Context {
|
||||
return x.stream.Context()
|
||||
}
|
||||
|
||||
func (x *routeGuideListFeaturesStream) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideListFeaturesStream) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideListFeaturesStream) Send(m *Feature) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (h *routeGuideHandler) RecordRoute(ctx context.Context, stream server.Stream) error {
|
||||
return h.RouteGuideHandler.RecordRoute(ctx, &routeGuideRecordRouteStream{stream})
|
||||
}
|
||||
|
||||
type RouteGuide_RecordRouteStream interface {
|
||||
Context() context.Context
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
Close() error
|
||||
Recv() (*Point, error)
|
||||
}
|
||||
|
||||
type routeGuideRecordRouteStream struct {
|
||||
stream server.Stream
|
||||
}
|
||||
|
||||
func (x *routeGuideRecordRouteStream) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *routeGuideRecordRouteStream) Context() context.Context {
|
||||
return x.stream.Context()
|
||||
}
|
||||
|
||||
func (x *routeGuideRecordRouteStream) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideRecordRouteStream) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideRecordRouteStream) Recv() (*Point, error) {
|
||||
m := new(Point)
|
||||
if err := x.stream.Recv(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (h *routeGuideHandler) RouteChat(ctx context.Context, stream server.Stream) error {
|
||||
return h.RouteGuideHandler.RouteChat(ctx, &routeGuideRouteChatStream{stream})
|
||||
}
|
||||
|
||||
type RouteGuide_RouteChatStream interface {
|
||||
Context() context.Context
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
Close() error
|
||||
Send(*RouteNote) error
|
||||
Recv() (*RouteNote, error)
|
||||
}
|
||||
|
||||
type routeGuideRouteChatStream struct {
|
||||
stream server.Stream
|
||||
}
|
||||
|
||||
func (x *routeGuideRouteChatStream) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *routeGuideRouteChatStream) Context() context.Context {
|
||||
return x.stream.Context()
|
||||
}
|
||||
|
||||
func (x *routeGuideRouteChatStream) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideRouteChatStream) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideRouteChatStream) Send(m *RouteNote) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *routeGuideRouteChatStream) Recv() (*RouteNote, error) {
|
||||
m := new(RouteNote)
|
||||
if err := x.stream.Recv(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
94
examples/stream/grpc/proto/route_guide.proto
Normal file
94
examples/stream/grpc/proto/route_guide.proto
Normal file
@ -0,0 +1,94 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option go_package = "../proto";
|
||||
|
||||
package proto;
|
||||
|
||||
// Interface exported by the server.
|
||||
service RouteGuide {
|
||||
// A simple RPC.
|
||||
//
|
||||
// Obtains the feature at a given position.
|
||||
//
|
||||
// A feature with an empty name is returned if there's no feature at the given
|
||||
// position.
|
||||
rpc GetFeature(Point) returns (Feature) {}
|
||||
|
||||
// A server-to-client streaming RPC.
|
||||
//
|
||||
// Obtains the Features available within the given Rectangle. Results are
|
||||
// streamed rather than returned at once (e.g. in a response message with a
|
||||
// repeated field), as the rectangle may cover a large area and contain a
|
||||
// huge number of features.
|
||||
rpc ListFeatures(Rectangle) returns (stream Feature) {}
|
||||
|
||||
// A client-to-server streaming RPC.
|
||||
//
|
||||
// Accepts a stream of Points on a route being traversed, returning a
|
||||
// RouteSummary when traversal is completed.
|
||||
rpc RecordRoute(stream Point) returns (RouteSummary) {}
|
||||
|
||||
// A Bidirectional streaming RPC.
|
||||
//
|
||||
// Accepts a stream of RouteNotes sent while a route is being traversed,
|
||||
// while receiving other RouteNotes (e.g. from other users).
|
||||
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
|
||||
}
|
||||
|
||||
// Points are represented as latitude-longitude pairs in the E7 representation
|
||||
// (degrees multiplied by 10**7 and rounded to the nearest integer).
|
||||
// Latitudes should be in the range +/- 90 degrees and longitude should be in
|
||||
// the range +/- 180 degrees (inclusive).
|
||||
message Point {
|
||||
int32 latitude = 1;
|
||||
int32 longitude = 2;
|
||||
}
|
||||
|
||||
// A latitude-longitude rectangle, represented as two diagonally opposite
|
||||
// points "lo" and "hi".
|
||||
message Rectangle {
|
||||
// One corner of the rectangle.
|
||||
Point lo = 1;
|
||||
|
||||
// The other corner of the rectangle.
|
||||
Point hi = 2;
|
||||
}
|
||||
|
||||
// A feature names something at a given point.
|
||||
//
|
||||
// If a feature could not be named, the name is empty.
|
||||
message Feature {
|
||||
// The name of the feature.
|
||||
string name = 1;
|
||||
|
||||
// The point where the feature is detected.
|
||||
Point location = 2;
|
||||
}
|
||||
|
||||
// A RouteNote is a message sent while at a given point.
|
||||
message RouteNote {
|
||||
// The location from which the message is sent.
|
||||
Point location = 1;
|
||||
|
||||
// The message to be sent.
|
||||
string message = 2;
|
||||
}
|
||||
|
||||
// A RouteSummary is received in response to a RecordRoute rpc.
|
||||
//
|
||||
// It contains the number of individual points received, the number of
|
||||
// detected features, and the total distance covered as the cumulative sum of
|
||||
// the distance between each point.
|
||||
message RouteSummary {
|
||||
// The number of points received.
|
||||
int32 point_count = 1;
|
||||
|
||||
// The number of known features passed while traversing the route.
|
||||
int32 feature_count = 2;
|
||||
|
||||
// The distance covered in metres.
|
||||
int32 distance = 3;
|
||||
|
||||
// The duration of the traversal in seconds.
|
||||
int32 elapsed_time = 4;
|
||||
}
|
661
examples/stream/grpc/server/data.go
Normal file
661
examples/stream/grpc/server/data.go
Normal file
@ -0,0 +1,661 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
pb "github.com/asim/go-micro/examples/v4/stream/grpc/proto"
|
||||
)
|
||||
|
||||
var features []*pb.Feature
|
||||
|
||||
func init() {
|
||||
if err := json.Unmarshal(testingData, &features); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func inRange(point *pb.Point, rect *pb.Rectangle) bool {
|
||||
left := math.Min(float64(rect.Lo.Longitude), float64(rect.Hi.Longitude))
|
||||
right := math.Max(float64(rect.Lo.Longitude), float64(rect.Hi.Longitude))
|
||||
top := math.Max(float64(rect.Lo.Latitude), float64(rect.Hi.Latitude))
|
||||
bottom := math.Min(float64(rect.Lo.Latitude), float64(rect.Hi.Latitude))
|
||||
|
||||
if float64(point.Longitude) >= left &&
|
||||
float64(point.Longitude) <= right &&
|
||||
float64(point.Latitude) >= bottom &&
|
||||
float64(point.Latitude) <= top {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func calcDistance(p1 *pb.Point, p2 *pb.Point) int32 {
|
||||
const CordFactor float64 = 1e7
|
||||
const R = float64(6371000) // earth radius in metres
|
||||
lat1 := toRadians(float64(p1.Latitude) / CordFactor)
|
||||
lat2 := toRadians(float64(p2.Latitude) / CordFactor)
|
||||
lng1 := toRadians(float64(p1.Longitude) / CordFactor)
|
||||
lng2 := toRadians(float64(p2.Longitude) / CordFactor)
|
||||
dlat := lat2 - lat1
|
||||
dlng := lng2 - lng1
|
||||
|
||||
a := math.Sin(dlat/2)*math.Sin(dlat/2) +
|
||||
math.Cos(lat1)*math.Cos(lat2)*
|
||||
math.Sin(dlng/2)*math.Sin(dlng/2)
|
||||
c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
|
||||
|
||||
distance := R * c
|
||||
return int32(distance)
|
||||
}
|
||||
|
||||
func toRadians(num float64) float64 {
|
||||
return num * math.Pi / float64(180)
|
||||
}
|
||||
|
||||
func serialize(point *pb.Point) string {
|
||||
return fmt.Sprintf("%d %d", point.Latitude, point.Longitude)
|
||||
}
|
||||
|
||||
var testingData = []byte(`[{
|
||||
"location": {
|
||||
"latitude": 407838351,
|
||||
"longitude": -746143763
|
||||
},
|
||||
"name": "Patriots Path, Mendham, NJ 07945, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408122808,
|
||||
"longitude": -743999179
|
||||
},
|
||||
"name": "101 New Jersey 10, Whippany, NJ 07981, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413628156,
|
||||
"longitude": -749015468
|
||||
},
|
||||
"name": "U.S. 6, Shohola, PA 18458, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419999544,
|
||||
"longitude": -740371136
|
||||
},
|
||||
"name": "5 Conners Road, Kingston, NY 12401, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414008389,
|
||||
"longitude": -743951297
|
||||
},
|
||||
"name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419611318,
|
||||
"longitude": -746524769
|
||||
},
|
||||
"name": "287 Flugertown Road, Livingston Manor, NY 12758, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406109563,
|
||||
"longitude": -742186778
|
||||
},
|
||||
"name": "4001 Tremley Point Road, Linden, NJ 07036, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416802456,
|
||||
"longitude": -742370183
|
||||
},
|
||||
"name": "352 South Mountain Road, Wallkill, NY 12589, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412950425,
|
||||
"longitude": -741077389
|
||||
},
|
||||
"name": "Bailey Turn Road, Harriman, NY 10926, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412144655,
|
||||
"longitude": -743949739
|
||||
},
|
||||
"name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415736605,
|
||||
"longitude": -742847522
|
||||
},
|
||||
"name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413843930,
|
||||
"longitude": -740501726
|
||||
},
|
||||
"name": "162 Merrill Road, Highland Mills, NY 10930, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410873075,
|
||||
"longitude": -744459023
|
||||
},
|
||||
"name": "Clinton Road, West Milford, NJ 07480, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412346009,
|
||||
"longitude": -744026814
|
||||
},
|
||||
"name": "16 Old Brook Lane, Warwick, NY 10990, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402948455,
|
||||
"longitude": -747903913
|
||||
},
|
||||
"name": "3 Drake Lane, Pennington, NJ 08534, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406337092,
|
||||
"longitude": -740122226
|
||||
},
|
||||
"name": "6324 8th Avenue, Brooklyn, NY 11220, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406421967,
|
||||
"longitude": -747727624
|
||||
},
|
||||
"name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416318082,
|
||||
"longitude": -749677716
|
||||
},
|
||||
"name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415301720,
|
||||
"longitude": -748416257
|
||||
},
|
||||
"name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402647019,
|
||||
"longitude": -747071791
|
||||
},
|
||||
"name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412567807,
|
||||
"longitude": -741058078
|
||||
},
|
||||
"name": "New York State Reference Route 987E, Southfields, NY 10975, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416855156,
|
||||
"longitude": -744420597
|
||||
},
|
||||
"name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404663628,
|
||||
"longitude": -744820157
|
||||
},
|
||||
"name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407113723,
|
||||
"longitude": -749746483
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402133926,
|
||||
"longitude": -743613249
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400273442,
|
||||
"longitude": -741220915
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411236786,
|
||||
"longitude": -744070769
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411633782,
|
||||
"longitude": -746784970
|
||||
},
|
||||
"name": "211-225 Plains Road, Augusta, NJ 07822, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415830701,
|
||||
"longitude": -742952812
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413447164,
|
||||
"longitude": -748712898
|
||||
},
|
||||
"name": "165 Pedersen Ridge Road, Milford, PA 18337, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405047245,
|
||||
"longitude": -749800722
|
||||
},
|
||||
"name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418858923,
|
||||
"longitude": -746156790
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 417951888,
|
||||
"longitude": -748484944
|
||||
},
|
||||
"name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407033786,
|
||||
"longitude": -743977337
|
||||
},
|
||||
"name": "26 East 3rd Street, New Providence, NJ 07974, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 417548014,
|
||||
"longitude": -740075041
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410395868,
|
||||
"longitude": -744972325
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404615353,
|
||||
"longitude": -745129803
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406589790,
|
||||
"longitude": -743560121
|
||||
},
|
||||
"name": "611 Lawrence Avenue, Westfield, NJ 07090, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414653148,
|
||||
"longitude": -740477477
|
||||
},
|
||||
"name": "18 Lannis Avenue, New Windsor, NY 12553, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405957808,
|
||||
"longitude": -743255336
|
||||
},
|
||||
"name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411733589,
|
||||
"longitude": -741648093
|
||||
},
|
||||
"name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412676291,
|
||||
"longitude": -742606606
|
||||
},
|
||||
"name": "1270 Lakes Road, Monroe, NY 10950, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409224445,
|
||||
"longitude": -748286738
|
||||
},
|
||||
"name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406523420,
|
||||
"longitude": -742135517
|
||||
},
|
||||
"name": "652 Garden Street, Elizabeth, NJ 07202, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401827388,
|
||||
"longitude": -740294537
|
||||
},
|
||||
"name": "349 Sea Spray Court, Neptune City, NJ 07753, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410564152,
|
||||
"longitude": -743685054
|
||||
},
|
||||
"name": "13-17 Stanley Street, West Milford, NJ 07480, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408472324,
|
||||
"longitude": -740726046
|
||||
},
|
||||
"name": "47 Industrial Avenue, Teterboro, NJ 07608, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412452168,
|
||||
"longitude": -740214052
|
||||
},
|
||||
"name": "5 White Oak Lane, Stony Point, NY 10980, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409146138,
|
||||
"longitude": -746188906
|
||||
},
|
||||
"name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404701380,
|
||||
"longitude": -744781745
|
||||
},
|
||||
"name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409642566,
|
||||
"longitude": -746017679
|
||||
},
|
||||
"name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408031728,
|
||||
"longitude": -748645385
|
||||
},
|
||||
"name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413700272,
|
||||
"longitude": -742135189
|
||||
},
|
||||
"name": "367 Prospect Road, Chester, NY 10918, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404310607,
|
||||
"longitude": -740282632
|
||||
},
|
||||
"name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409319800,
|
||||
"longitude": -746201391
|
||||
},
|
||||
"name": "11 Ward Street, Mount Arlington, NJ 07856, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406685311,
|
||||
"longitude": -742108603
|
||||
},
|
||||
"name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419018117,
|
||||
"longitude": -749142781
|
||||
},
|
||||
"name": "43 Dreher Road, Roscoe, NY 12776, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412856162,
|
||||
"longitude": -745148837
|
||||
},
|
||||
"name": "Swan Street, Pine Island, NY 10969, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416560744,
|
||||
"longitude": -746721964
|
||||
},
|
||||
"name": "66 Pleasantview Avenue, Monticello, NY 12701, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405314270,
|
||||
"longitude": -749836354
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414219548,
|
||||
"longitude": -743327440
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415534177,
|
||||
"longitude": -742900616
|
||||
},
|
||||
"name": "565 Winding Hills Road, Montgomery, NY 12549, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406898530,
|
||||
"longitude": -749127080
|
||||
},
|
||||
"name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407586880,
|
||||
"longitude": -741670168
|
||||
},
|
||||
"name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400106455,
|
||||
"longitude": -742870190
|
||||
},
|
||||
"name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400066188,
|
||||
"longitude": -746793294
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418803880,
|
||||
"longitude": -744102673
|
||||
},
|
||||
"name": "40 Mountain Road, Napanoch, NY 12458, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414204288,
|
||||
"longitude": -747895140
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414777405,
|
||||
"longitude": -740615601
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415464475,
|
||||
"longitude": -747175374
|
||||
},
|
||||
"name": "48 North Road, Forestburgh, NY 12777, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404062378,
|
||||
"longitude": -746376177
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405688272,
|
||||
"longitude": -749285130
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400342070,
|
||||
"longitude": -748788996
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401809022,
|
||||
"longitude": -744157964
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404226644,
|
||||
"longitude": -740517141
|
||||
},
|
||||
"name": "9 Thompson Avenue, Leonardo, NJ 07737, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410322033,
|
||||
"longitude": -747871659
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407100674,
|
||||
"longitude": -747742727
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418811433,
|
||||
"longitude": -741718005
|
||||
},
|
||||
"name": "213 Bush Road, Stone Ridge, NY 12484, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415034302,
|
||||
"longitude": -743850945
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411349992,
|
||||
"longitude": -743694161
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404839914,
|
||||
"longitude": -744759616
|
||||
},
|
||||
"name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414638017,
|
||||
"longitude": -745957854
|
||||
},
|
||||
"name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412127800,
|
||||
"longitude": -740173578
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401263460,
|
||||
"longitude": -747964303
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412843391,
|
||||
"longitude": -749086026
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418512773,
|
||||
"longitude": -743067823
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404318328,
|
||||
"longitude": -740835638
|
||||
},
|
||||
"name": "42-102 Main Street, Belford, NJ 07718, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419020746,
|
||||
"longitude": -741172328
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404080723,
|
||||
"longitude": -746119569
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401012643,
|
||||
"longitude": -744035134
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404306372,
|
||||
"longitude": -741079661
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 403966326,
|
||||
"longitude": -748519297
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405002031,
|
||||
"longitude": -748407866
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409532885,
|
||||
"longitude": -742200683
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416851321,
|
||||
"longitude": -742674555
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406411633,
|
||||
"longitude": -741722051
|
||||
},
|
||||
"name": "3387 Richmond Terrace, Staten Island, NY 10303, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413069058,
|
||||
"longitude": -744597778
|
||||
},
|
||||
"name": "261 Van Sickle Road, Goshen, NY 10924, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418465462,
|
||||
"longitude": -746859398
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411733222,
|
||||
"longitude": -744228360
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410248224,
|
||||
"longitude": -747127767
|
||||
},
|
||||
"name": "3 Hasta Way, Newton, NJ 07860, USA"
|
||||
}]`)
|
114
examples/stream/grpc/server/main.go
Normal file
114
examples/stream/grpc/server/main.go
Normal file
@ -0,0 +1,114 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
pb "github.com/asim/go-micro/examples/v4/stream/grpc/proto"
|
||||
"github.com/asim/go-micro/plugins/server/grpc/v4"
|
||||
"go-micro.dev/v4"
|
||||
"go-micro.dev/v4/logger"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type server struct {
|
||||
mu sync.Mutex
|
||||
routeNotes map[string][]*pb.RouteNote
|
||||
}
|
||||
|
||||
func main() {
|
||||
srv := micro.NewService(
|
||||
micro.Server(grpc.NewServer()),
|
||||
micro.Name("stream-server"),
|
||||
)
|
||||
srv.Init()
|
||||
pb.RegisterRouteGuideHandler(srv.Server(), &server{routeNotes: make(map[string][]*pb.RouteNote)})
|
||||
if err := srv.Run(); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *server) GetFeature(ctx context.Context, in *pb.Point, out *pb.Feature) error {
|
||||
for _, f := range features {
|
||||
if proto.Equal(f.Location, in) {
|
||||
out.Location = f.Location
|
||||
out.Name = f.Name
|
||||
return nil
|
||||
}
|
||||
}
|
||||
out.Location = in
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) ListFeatures(ctx context.Context, in *pb.Rectangle, stream pb.RouteGuide_ListFeaturesStream) error {
|
||||
for _, feature := range features {
|
||||
if inRange(feature.Location, in) {
|
||||
if err := stream.Send(feature); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) RecordRoute(ctx context.Context, stream pb.RouteGuide_RecordRouteStream) error {
|
||||
var pointCount, featureCount, distance int32
|
||||
var lastPoint *pb.Point
|
||||
startTime := time.Now()
|
||||
for {
|
||||
point, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pointCount++
|
||||
for _, feature := range features {
|
||||
if proto.Equal(feature.Location, point) {
|
||||
featureCount++
|
||||
}
|
||||
}
|
||||
if lastPoint != nil {
|
||||
distance += calcDistance(lastPoint, point)
|
||||
}
|
||||
lastPoint = point
|
||||
}
|
||||
return stream.SendMsg(&pb.RouteSummary{
|
||||
PointCount: pointCount,
|
||||
FeatureCount: featureCount,
|
||||
Distance: distance,
|
||||
ElapsedTime: int32(time.Since(startTime).Seconds()),
|
||||
})
|
||||
}
|
||||
|
||||
func (s *server) RouteChat(ctx context.Context, stream pb.RouteGuide_RouteChatStream) error {
|
||||
for {
|
||||
in, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key := serialize(in.Location)
|
||||
|
||||
s.mu.Lock()
|
||||
s.routeNotes[key] = append(s.routeNotes[key], in)
|
||||
// Note: this copy prevents blocking other clients while serving this one.
|
||||
// We don't need to do a deep copy, because elements in the slice are
|
||||
// insert-only and never modified.
|
||||
rn := make([]*pb.RouteNote, len(s.routeNotes[key]))
|
||||
copy(rn, s.routeNotes[key])
|
||||
s.mu.Unlock()
|
||||
|
||||
for _, note := range rn {
|
||||
if err := stream.Send(note); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -2,10 +2,12 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"context"
|
||||
proto "github.com/asim/go-micro/examples/v4/stream/server/proto"
|
||||
|
||||
proto "github.com/asim/go-micro/examples/v4/stream/rpc/server/proto"
|
||||
"go-micro.dev/v4"
|
||||
)
|
||||
|
||||
@ -25,6 +27,9 @@ func bidirectional(cl proto.StreamerService) {
|
||||
return
|
||||
}
|
||||
rsp, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println("recv err", err)
|
||||
break
|
||||
@ -52,6 +57,9 @@ func serverStream(cl proto.StreamerService) {
|
||||
// receive messages for a 10 count
|
||||
for {
|
||||
rsp, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println("recv err", err)
|
||||
break
|
@ -6,7 +6,7 @@ import (
|
||||
"io"
|
||||
"log"
|
||||
|
||||
proto "github.com/asim/go-micro/examples/v4/stream/server/proto"
|
||||
proto "github.com/asim/go-micro/examples/v4/stream/rpc/server/proto"
|
||||
"go-micro.dev/v4"
|
||||
)
|
||||
|
213
examples/stream/rpc/server/proto/stream.pb.go
Normal file
213
examples/stream/rpc/server/proto/stream.pb.go
Normal file
@ -0,0 +1,213 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.15.6
|
||||
// source: proto/stream.proto
|
||||
|
||||
package stream
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
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 Request struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Request) Reset() {
|
||||
*x = Request{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_stream_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Request) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Request) ProtoMessage() {}
|
||||
|
||||
func (x *Request) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_stream_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Request.ProtoReflect.Descriptor instead.
|
||||
func (*Request) Descriptor() ([]byte, []int) {
|
||||
return file_proto_stream_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Request) GetCount() int64 {
|
||||
if x != nil {
|
||||
return x.Count
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Response) Reset() {
|
||||
*x = Response{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_stream_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Response) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Response) ProtoMessage() {}
|
||||
|
||||
func (x *Response) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_stream_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Response.ProtoReflect.Descriptor instead.
|
||||
func (*Response) Descriptor() ([]byte, []int) {
|
||||
return file_proto_stream_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Response) GetCount() int64 {
|
||||
if x != nil {
|
||||
return x.Count
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_proto_stream_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_proto_stream_proto_rawDesc = []byte{
|
||||
0x0a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1f, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x20, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0x58, 0x0a, 0x08, 0x53, 0x74, 0x72, 0x65, 0x61,
|
||||
0x6d, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x08, 0x2e,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x27, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76,
|
||||
0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x08, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30,
|
||||
0x01, 0x42, 0x10, 0x5a, 0x0e, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x73, 0x74, 0x72,
|
||||
0x65, 0x61, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_proto_stream_proto_rawDescOnce sync.Once
|
||||
file_proto_stream_proto_rawDescData = file_proto_stream_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_proto_stream_proto_rawDescGZIP() []byte {
|
||||
file_proto_stream_proto_rawDescOnce.Do(func() {
|
||||
file_proto_stream_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_stream_proto_rawDescData)
|
||||
})
|
||||
return file_proto_stream_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_stream_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_proto_stream_proto_goTypes = []interface{}{
|
||||
(*Request)(nil), // 0: Request
|
||||
(*Response)(nil), // 1: Response
|
||||
}
|
||||
var file_proto_stream_proto_depIdxs = []int32{
|
||||
0, // 0: Streamer.Stream:input_type -> Request
|
||||
0, // 1: Streamer.ServerStream:input_type -> Request
|
||||
1, // 2: Streamer.Stream:output_type -> Response
|
||||
1, // 3: Streamer.ServerStream:output_type -> Response
|
||||
2, // [2:4] is the sub-list for method output_type
|
||||
0, // [0:2] 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_proto_stream_proto_init() }
|
||||
func file_proto_stream_proto_init() {
|
||||
if File_proto_stream_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_proto_stream_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Request); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_stream_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Response); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_stream_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_proto_stream_proto_goTypes,
|
||||
DependencyIndexes: file_proto_stream_proto_depIdxs,
|
||||
MessageInfos: file_proto_stream_proto_msgTypes,
|
||||
}.Build()
|
||||
File_proto_stream_proto = out.File
|
||||
file_proto_stream_proto_rawDesc = nil
|
||||
file_proto_stream_proto_goTypes = nil
|
||||
file_proto_stream_proto_depIdxs = nil
|
||||
}
|
@ -1,24 +1,17 @@
|
||||
// Code generated by protoc-gen-micro. DO NOT EDIT.
|
||||
// source: github.com/asim/go-micro/examples/v4/stream/server/proto/stream.proto
|
||||
// source: proto/stream.proto
|
||||
|
||||
/*
|
||||
Package stream is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
github.com/asim/go-micro/examples/v4/stream/server/proto/stream.proto
|
||||
|
||||
It has these top-level messages:
|
||||
Request
|
||||
Response
|
||||
*/
|
||||
package stream
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "google.golang.org/protobuf/proto"
|
||||
math "math"
|
||||
)
|
||||
|
||||
import (
|
||||
context "context"
|
||||
api "go-micro.dev/v4/api"
|
||||
client "go-micro.dev/v4/client"
|
||||
server "go-micro.dev/v4/server"
|
||||
)
|
||||
@ -28,17 +21,18 @@ var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ api.Endpoint
|
||||
var _ context.Context
|
||||
var _ client.Option
|
||||
var _ server.Option
|
||||
|
||||
// Api Endpoints for Streamer service
|
||||
|
||||
func NewStreamerEndpoints() []*api.Endpoint {
|
||||
return []*api.Endpoint{}
|
||||
}
|
||||
|
||||
// Client API for Streamer service
|
||||
|
||||
type StreamerService interface {
|
||||
@ -47,61 +41,65 @@ type StreamerService interface {
|
||||
}
|
||||
|
||||
type streamerService struct {
|
||||
c client.Client
|
||||
serviceName string
|
||||
c client.Client
|
||||
name string
|
||||
}
|
||||
|
||||
func NewStreamerService(serviceName string, c client.Client) StreamerService {
|
||||
if c == nil {
|
||||
c = client.NewClient()
|
||||
}
|
||||
if len(serviceName) == 0 {
|
||||
serviceName = "streamer"
|
||||
}
|
||||
func NewStreamerService(name string, c client.Client) StreamerService {
|
||||
return &streamerService{
|
||||
c: c,
|
||||
serviceName: serviceName,
|
||||
c: c,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *streamerService) Stream(ctx context.Context, opts ...client.CallOption) (Streamer_StreamService, error) {
|
||||
req := c.c.NewRequest(c.serviceName, "Streamer.Stream", &Request{})
|
||||
req := c.c.NewRequest(c.name, "Streamer.Stream", &Request{})
|
||||
stream, err := c.c.Stream(ctx, req, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &streamerStreamService{stream}, nil
|
||||
return &streamerServiceStream{stream}, nil
|
||||
}
|
||||
|
||||
type Streamer_StreamService interface {
|
||||
Context() context.Context
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
CloseSend() error
|
||||
Close() error
|
||||
Send(*Request) error
|
||||
Recv() (*Response, error)
|
||||
}
|
||||
|
||||
type streamerStreamService struct {
|
||||
type streamerServiceStream struct {
|
||||
stream client.Stream
|
||||
}
|
||||
|
||||
func (x *streamerStreamService) Close() error {
|
||||
func (x *streamerServiceStream) CloseSend() error {
|
||||
return x.stream.CloseSend()
|
||||
}
|
||||
|
||||
func (x *streamerServiceStream) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *streamerStreamService) SendMsg(m interface{}) error {
|
||||
func (x *streamerServiceStream) Context() context.Context {
|
||||
return x.stream.Context()
|
||||
}
|
||||
|
||||
func (x *streamerServiceStream) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *streamerStreamService) RecvMsg(m interface{}) error {
|
||||
func (x *streamerServiceStream) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *streamerStreamService) Send(m *Request) error {
|
||||
func (x *streamerServiceStream) Send(m *Request) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *streamerStreamService) Recv() (*Response, error) {
|
||||
func (x *streamerServiceStream) Recv() (*Response, error) {
|
||||
m := new(Response)
|
||||
err := x.stream.Recv(m)
|
||||
if err != nil {
|
||||
@ -111,7 +109,7 @@ func (x *streamerStreamService) Recv() (*Response, error) {
|
||||
}
|
||||
|
||||
func (c *streamerService) ServerStream(ctx context.Context, in *Request, opts ...client.CallOption) (Streamer_ServerStreamService, error) {
|
||||
req := c.c.NewRequest(c.serviceName, "Streamer.ServerStream", &Request{})
|
||||
req := c.c.NewRequest(c.name, "Streamer.ServerStream", &Request{})
|
||||
stream, err := c.c.Stream(ctx, req, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -119,33 +117,43 @@ func (c *streamerService) ServerStream(ctx context.Context, in *Request, opts ..
|
||||
if err := stream.Send(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &streamerServerStreamService{stream}, nil
|
||||
return &streamerServiceServerStream{stream}, nil
|
||||
}
|
||||
|
||||
type Streamer_ServerStreamService interface {
|
||||
Context() context.Context
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
CloseSend() error
|
||||
Close() error
|
||||
Recv() (*Response, error)
|
||||
}
|
||||
|
||||
type streamerServerStreamService struct {
|
||||
type streamerServiceServerStream struct {
|
||||
stream client.Stream
|
||||
}
|
||||
|
||||
func (x *streamerServerStreamService) Close() error {
|
||||
func (x *streamerServiceServerStream) CloseSend() error {
|
||||
return x.stream.CloseSend()
|
||||
}
|
||||
|
||||
func (x *streamerServiceServerStream) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *streamerServerStreamService) SendMsg(m interface{}) error {
|
||||
func (x *streamerServiceServerStream) Context() context.Context {
|
||||
return x.stream.Context()
|
||||
}
|
||||
|
||||
func (x *streamerServiceServerStream) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *streamerServerStreamService) RecvMsg(m interface{}) error {
|
||||
func (x *streamerServiceServerStream) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *streamerServerStreamService) Recv() (*Response, error) {
|
||||
func (x *streamerServiceServerStream) Recv() (*Response, error) {
|
||||
m := new(Response)
|
||||
err := x.stream.Recv(m)
|
||||
if err != nil {
|
||||
@ -161,7 +169,7 @@ type StreamerHandler interface {
|
||||
ServerStream(context.Context, *Request, Streamer_ServerStreamStream) error
|
||||
}
|
||||
|
||||
func RegisterStreamerHandler(s server.Server, hdlr StreamerHandler, opts ...server.HandlerOption) {
|
||||
func RegisterStreamerHandler(s server.Server, hdlr StreamerHandler, opts ...server.HandlerOption) error {
|
||||
type streamer interface {
|
||||
Stream(ctx context.Context, stream server.Stream) error
|
||||
ServerStream(ctx context.Context, stream server.Stream) error
|
||||
@ -170,7 +178,7 @@ func RegisterStreamerHandler(s server.Server, hdlr StreamerHandler, opts ...serv
|
||||
streamer
|
||||
}
|
||||
h := &streamerHandler{hdlr}
|
||||
s.Handle(s.NewHandler(&Streamer{h}, opts...))
|
||||
return s.Handle(s.NewHandler(&Streamer{h}, opts...))
|
||||
}
|
||||
|
||||
type streamerHandler struct {
|
||||
@ -182,6 +190,7 @@ func (h *streamerHandler) Stream(ctx context.Context, stream server.Stream) erro
|
||||
}
|
||||
|
||||
type Streamer_StreamStream interface {
|
||||
Context() context.Context
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
Close() error
|
||||
@ -197,6 +206,10 @@ func (x *streamerStreamStream) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *streamerStreamStream) Context() context.Context {
|
||||
return x.stream.Context()
|
||||
}
|
||||
|
||||
func (x *streamerStreamStream) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
@ -226,6 +239,7 @@ func (h *streamerHandler) ServerStream(ctx context.Context, stream server.Stream
|
||||
}
|
||||
|
||||
type Streamer_ServerStreamStream interface {
|
||||
Context() context.Context
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
Close() error
|
||||
@ -240,6 +254,10 @@ func (x *streamerServerStreamStream) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *streamerServerStreamStream) Context() context.Context {
|
||||
return x.stream.Context()
|
||||
}
|
||||
|
||||
func (x *streamerServerStreamStream) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option go_package = "./proto;stream";
|
||||
|
||||
service Streamer {
|
||||
rpc Stream(stream Request) returns (stream Response) {}
|
||||
rpc ServerStream(Request) returns (stream Response) {}
|
@ -1,254 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/asim/go-micro/examples/v4/stream/server/proto/stream.proto
|
||||
|
||||
/*
|
||||
Package stream is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
github.com/asim/go-micro/examples/v4/stream/server/proto/stream.proto
|
||||
|
||||
It has these top-level messages:
|
||||
Request
|
||||
Response
|
||||
*/
|
||||
package stream
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
import (
|
||||
context "golang.org/x/net/context"
|
||||
grpc "google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type Request struct {
|
||||
Count int64 `protobuf:"varint,1,opt,name=count" json:"count,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Request) Reset() { *m = Request{} }
|
||||
func (m *Request) String() string { return proto.CompactTextString(m) }
|
||||
func (*Request) ProtoMessage() {}
|
||||
func (*Request) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||
|
||||
func (m *Request) GetCount() int64 {
|
||||
if m != nil {
|
||||
return m.Count
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Count int64 `protobuf:"varint,1,opt,name=count" json:"count,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Response) Reset() { *m = Response{} }
|
||||
func (m *Response) String() string { return proto.CompactTextString(m) }
|
||||
func (*Response) ProtoMessage() {}
|
||||
func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
||||
|
||||
func (m *Response) GetCount() int64 {
|
||||
if m != nil {
|
||||
return m.Count
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Request)(nil), "Request")
|
||||
proto.RegisterType((*Response)(nil), "Response")
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConn
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion4
|
||||
|
||||
// Client API for Streamer service
|
||||
|
||||
type StreamerClient interface {
|
||||
Stream(ctx context.Context, opts ...grpc.CallOption) (Streamer_StreamClient, error)
|
||||
ServerStream(ctx context.Context, in *Request, opts ...grpc.CallOption) (Streamer_ServerStreamClient, error)
|
||||
}
|
||||
|
||||
type streamerClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewStreamerClient(cc *grpc.ClientConn) StreamerClient {
|
||||
return &streamerClient{cc}
|
||||
}
|
||||
|
||||
func (c *streamerClient) Stream(ctx context.Context, opts ...grpc.CallOption) (Streamer_StreamClient, error) {
|
||||
stream, err := grpc.NewClientStream(ctx, &_Streamer_serviceDesc.Streams[0], c.cc, "/Streamer/Stream", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &streamerStreamClient{stream}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type Streamer_StreamClient interface {
|
||||
Send(*Request) error
|
||||
Recv() (*Response, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type streamerStreamClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *streamerStreamClient) Send(m *Request) error {
|
||||
return x.ClientStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *streamerStreamClient) Recv() (*Response, error) {
|
||||
m := new(Response)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *streamerClient) ServerStream(ctx context.Context, in *Request, opts ...grpc.CallOption) (Streamer_ServerStreamClient, error) {
|
||||
stream, err := grpc.NewClientStream(ctx, &_Streamer_serviceDesc.Streams[1], c.cc, "/Streamer/ServerStream", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &streamerServerStreamClient{stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type Streamer_ServerStreamClient interface {
|
||||
Recv() (*Response, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type streamerServerStreamClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *streamerServerStreamClient) Recv() (*Response, error) {
|
||||
m := new(Response)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// Server API for Streamer service
|
||||
|
||||
type StreamerServer interface {
|
||||
Stream(Streamer_StreamServer) error
|
||||
ServerStream(*Request, Streamer_ServerStreamServer) error
|
||||
}
|
||||
|
||||
func RegisterStreamerServer(s *grpc.Server, srv StreamerServer) {
|
||||
s.RegisterService(&_Streamer_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Streamer_Stream_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
return srv.(StreamerServer).Stream(&streamerStreamServer{stream})
|
||||
}
|
||||
|
||||
type Streamer_StreamServer interface {
|
||||
Send(*Response) error
|
||||
Recv() (*Request, error)
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type streamerStreamServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *streamerStreamServer) Send(m *Response) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *streamerStreamServer) Recv() (*Request, error) {
|
||||
m := new(Request)
|
||||
if err := x.ServerStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func _Streamer_ServerStream_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(Request)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(StreamerServer).ServerStream(m, &streamerServerStreamServer{stream})
|
||||
}
|
||||
|
||||
type Streamer_ServerStreamServer interface {
|
||||
Send(*Response) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type streamerServerStreamServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *streamerServerStreamServer) Send(m *Response) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
var _Streamer_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "Streamer",
|
||||
HandlerType: (*StreamerServer)(nil),
|
||||
Methods: []grpc.MethodDesc{},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "Stream",
|
||||
Handler: _Streamer_Stream_Handler,
|
||||
ServerStreams: true,
|
||||
ClientStreams: true,
|
||||
},
|
||||
{
|
||||
StreamName: "ServerStream",
|
||||
Handler: _Streamer_ServerStream_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "github.com/asim/go-micro/examples/v4/stream/server/proto/stream.proto",
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("github.com/asim/go-micro/examples/v4/stream/server/proto/stream.proto", fileDescriptor0)
|
||||
}
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 167 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xb2, 0x4a, 0xcf, 0x2c, 0xc9,
|
||||
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0xcd, 0x4c, 0x2e, 0xca, 0xd7, 0x4f, 0xad, 0x48,
|
||||
0xcc, 0x2d, 0xc8, 0x49, 0x2d, 0xd6, 0x2f, 0x2e, 0x29, 0x4a, 0x4d, 0xcc, 0xd5, 0x2f, 0x4e, 0x2d,
|
||||
0x2a, 0x4b, 0x2d, 0xd2, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x87, 0x8a, 0xe9, 0x81, 0x39, 0x4a, 0xf2,
|
||||
0x5c, 0xec, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x22, 0x5c, 0xac, 0xc9, 0xf9, 0xa5,
|
||||
0x79, 0x25, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xcc, 0x41, 0x10, 0x8e, 0x92, 0x02, 0x17, 0x47, 0x50,
|
||||
0x6a, 0x71, 0x41, 0x7e, 0x5e, 0x71, 0x2a, 0x76, 0x15, 0x46, 0x11, 0x5c, 0x1c, 0xc1, 0x60, 0x23,
|
||||
0x53, 0x8b, 0x84, 0x94, 0xb9, 0xd8, 0x20, 0x6c, 0x21, 0x0e, 0x3d, 0xa8, 0xb9, 0x52, 0x9c, 0x7a,
|
||||
0x30, 0x03, 0x94, 0x18, 0x34, 0x18, 0x0d, 0x18, 0x85, 0xd4, 0xb9, 0x78, 0x82, 0xc1, 0x0e, 0xc2,
|
||||
0xab, 0xd4, 0x80, 0x31, 0x89, 0x0d, 0xec, 0x46, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x16,
|
||||
0x4a, 0x84, 0x3f, 0xe1, 0x00, 0x00, 0x00,
|
||||
}
|
@ -1,19 +1,17 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
b "bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
b "bytes"
|
||||
|
||||
"github.com/golang/protobuf/jsonpb"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"go-micro.dev/v4/codec"
|
||||
"go-micro.dev/v4/codec/bytes"
|
||||
"github.com/oxtoacart/bpool"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/encoding"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type jsonCodec struct{}
|
||||
@ -21,12 +19,8 @@ type protoCodec struct{}
|
||||
type bytesCodec struct{}
|
||||
type wrapCodec struct{ encoding.Codec }
|
||||
|
||||
var jsonpbMarshaler = &jsonpb.Marshaler{}
|
||||
var useNumber bool
|
||||
|
||||
// create buffer pool with 16 instances each preallocated with 256 bytes
|
||||
var bufferPool = bpool.NewSizedBufferPool(16, 256)
|
||||
|
||||
var (
|
||||
defaultGRPCCodecs = map[string]encoding.Codec{
|
||||
"application/json": jsonCodec{},
|
||||
@ -115,12 +109,11 @@ func (jsonCodec) Marshal(v interface{}) ([]byte, error) {
|
||||
}
|
||||
|
||||
if pb, ok := v.(proto.Message); ok {
|
||||
buf := bufferPool.Get()
|
||||
defer bufferPool.Put(buf)
|
||||
if err := jsonpbMarshaler.Marshal(buf, pb); err != nil {
|
||||
bytes, err := protojson.Marshal(pb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
return bytes, nil
|
||||
}
|
||||
|
||||
return json.Marshal(v)
|
||||
@ -135,7 +128,7 @@ func (jsonCodec) Unmarshal(data []byte, v interface{}) error {
|
||||
return nil
|
||||
}
|
||||
if pb, ok := v.(proto.Message); ok {
|
||||
return jsonpb.Unmarshal(b.NewReader(data), pb)
|
||||
return protojson.Unmarshal(data, pb)
|
||||
}
|
||||
|
||||
dec := json.NewDecoder(b.NewReader(data))
|
||||
|
@ -3,11 +3,10 @@ module github.com/asim/go-micro/plugins/client/grpc/v4
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c
|
||||
go-micro.dev/v4 v4.2.1
|
||||
google.golang.org/grpc v1.41.0
|
||||
google.golang.org/grpc/examples v0.0.0-20211020220737-f00baa6c3c84
|
||||
google.golang.org/protobuf v1.26.0
|
||||
)
|
||||
|
||||
replace go-micro.dev/v4 => ../../../../go-micro
|
||||
|
@ -12,15 +12,14 @@ import (
|
||||
"time"
|
||||
|
||||
"go-micro.dev/v4/broker"
|
||||
"go-micro.dev/v4/cmd"
|
||||
"go-micro.dev/v4/client"
|
||||
"go-micro.dev/v4/cmd"
|
||||
raw "go-micro.dev/v4/codec/bytes"
|
||||
"go-micro.dev/v4/errors"
|
||||
"go-micro.dev/v4/metadata"
|
||||
"go-micro.dev/v4/registry"
|
||||
"go-micro.dev/v4/selector"
|
||||
pnet "go-micro.dev/v4/util/net"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/encoding"
|
||||
@ -104,7 +103,6 @@ func (g *grpcClient) call(ctx context.Context, node *registry.Node, req client.R
|
||||
|
||||
address := node.Address
|
||||
|
||||
header = make(map[string]string)
|
||||
if md, ok := metadata.FromContext(ctx); ok {
|
||||
header = make(map[string]string, len(md))
|
||||
for k, v := range md {
|
||||
@ -132,8 +130,16 @@ func (g *grpcClient) call(ctx context.Context, node *registry.Node, req client.R
|
||||
|
||||
var grr error
|
||||
|
||||
var dialCtx context.Context
|
||||
var cancel context.CancelFunc
|
||||
if opts.DialTimeout > 0 {
|
||||
dialCtx, cancel = context.WithTimeout(ctx, opts.DialTimeout)
|
||||
} else {
|
||||
dialCtx, cancel = context.WithCancel(ctx)
|
||||
}
|
||||
defer cancel()
|
||||
|
||||
grpcDialOptions := []grpc.DialOption{
|
||||
grpc.WithTimeout(opts.DialTimeout),
|
||||
g.secure(address),
|
||||
grpc.WithDefaultCallOptions(
|
||||
grpc.MaxCallRecvMsgSize(maxRecvMsgSize),
|
||||
@ -145,7 +151,7 @@ func (g *grpcClient) call(ctx context.Context, node *registry.Node, req client.R
|
||||
grpcDialOptions = append(grpcDialOptions, opts...)
|
||||
}
|
||||
|
||||
cc, err := g.pool.getConn(address, grpcDialOptions...)
|
||||
cc, err := g.pool.getConn(dialCtx, address, grpcDialOptions...)
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.client", fmt.Sprintf("Error sending request: %v", err))
|
||||
}
|
||||
@ -208,7 +214,7 @@ func (g *grpcClient) stream(ctx context.Context, node *registry.Node, req client
|
||||
|
||||
var dialCtx context.Context
|
||||
var cancel context.CancelFunc
|
||||
if opts.DialTimeout >= 0 {
|
||||
if opts.DialTimeout > 0 {
|
||||
dialCtx, cancel = context.WithTimeout(ctx, opts.DialTimeout)
|
||||
} else {
|
||||
dialCtx, cancel = context.WithCancel(ctx)
|
||||
@ -218,7 +224,6 @@ func (g *grpcClient) stream(ctx context.Context, node *registry.Node, req client
|
||||
wc := wrapCodec{cf}
|
||||
|
||||
grpcDialOptions := []grpc.DialOption{
|
||||
grpc.WithTimeout(opts.DialTimeout),
|
||||
g.secure(address),
|
||||
}
|
||||
|
||||
@ -226,7 +231,7 @@ func (g *grpcClient) stream(ctx context.Context, node *registry.Node, req client
|
||||
grpcDialOptions = append(grpcDialOptions, opts...)
|
||||
}
|
||||
|
||||
cc, err := grpc.DialContext(dialCtx, address, grpcDialOptions...)
|
||||
cc, err := g.pool.getConn(dialCtx, address, grpcDialOptions...)
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.client", fmt.Sprintf("Error sending request: %v", err))
|
||||
}
|
||||
@ -274,14 +279,16 @@ func (g *grpcClient) stream(ctx context.Context, node *registry.Node, req client
|
||||
context: ctx,
|
||||
request: req,
|
||||
response: &response{
|
||||
conn: cc,
|
||||
conn: cc.ClientConn,
|
||||
stream: st,
|
||||
codec: cf,
|
||||
gcodec: codec,
|
||||
},
|
||||
stream: st,
|
||||
conn: cc,
|
||||
cancel: cancel,
|
||||
release: func(err error) {
|
||||
g.pool.release(address, cc, err)
|
||||
},
|
||||
}
|
||||
|
||||
// set the stream as the response
|
||||
@ -347,7 +354,7 @@ func (g *grpcClient) newGRPCCodec(contentType string) (encoding.Codec, error) {
|
||||
if c, ok := defaultGRPCCodecs[contentType]; ok {
|
||||
return wrapCodec{c}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Unsupported Content-Type: %s", contentType)
|
||||
return nil, fmt.Errorf("unsupported Content-Type: %s", contentType)
|
||||
}
|
||||
|
||||
func (g *grpcClient) Init(opts ...client.Option) error {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -66,7 +67,7 @@ func newPool(size int, ttl time.Duration, idle int, ms int) *pool {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *pool) getConn(addr string, opts ...grpc.DialOption) (*poolConn, error) {
|
||||
func (p *pool) getConn(dialCtx context.Context, addr string, opts ...grpc.DialOption) (*poolConn, error) {
|
||||
now := time.Now().Unix()
|
||||
p.Lock()
|
||||
sp, ok := p.conns[addr]
|
||||
@ -135,7 +136,7 @@ func (p *pool) getConn(addr string, opts ...grpc.DialOption) (*poolConn, error)
|
||||
p.Unlock()
|
||||
|
||||
// create new conn
|
||||
cc, err := grpc.Dial(addr, opts...)
|
||||
cc, err := grpc.DialContext(dialCtx, addr, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -184,7 +185,6 @@ func (p *pool) release(addr string, conn *poolConn, err error) {
|
||||
sp.idle++
|
||||
}
|
||||
p.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
func (conn *poolConn) Close() {
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
pgrpc "google.golang.org/grpc"
|
||||
pb "google.golang.org/grpc/examples/helloworld/helloworld"
|
||||
)
|
||||
|
||||
@ -19,7 +18,7 @@ func testPool(t *testing.T, size int, ttl time.Duration, idle int, ms int) {
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
s := pgrpc.NewServer()
|
||||
s := grpc.NewServer()
|
||||
pb.RegisterGreeterServer(s, &greeterServer{})
|
||||
|
||||
go s.Serve(l)
|
||||
@ -30,7 +29,7 @@ func testPool(t *testing.T, size int, ttl time.Duration, idle int, ms int) {
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
// get a conn
|
||||
cc, err := p.getConn(l.Addr().String(), grpc.WithInsecure())
|
||||
cc, err := p.getConn(context.TODO(), l.Addr().String(), grpc.WithInsecure())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ type grpcStream struct {
|
||||
sync.RWMutex
|
||||
closed bool
|
||||
err error
|
||||
conn *grpc.ClientConn
|
||||
stream grpc.ClientStream
|
||||
request client.Request
|
||||
response client.Response
|
||||
context context.Context
|
||||
cancel func()
|
||||
release func(error)
|
||||
}
|
||||
|
||||
func (g *grpcStream) Context() context.Context {
|
||||
@ -43,15 +43,11 @@ func (g *grpcStream) Send(msg interface{}) error {
|
||||
}
|
||||
|
||||
func (g *grpcStream) Recv(msg interface{}) (err error) {
|
||||
defer g.setError(err)
|
||||
if err = g.stream.RecvMsg(msg); err != nil {
|
||||
// #202 - inconsistent gRPC stream behavior
|
||||
// the only way to tell if the stream is done is when we get a EOF on the Recv
|
||||
// here we should close the underlying gRPC ClientConn
|
||||
closeErr := g.Close()
|
||||
if err == io.EOF && closeErr != nil {
|
||||
err = closeErr
|
||||
if err != io.EOF {
|
||||
g.setError(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -68,11 +64,10 @@ func (g *grpcStream) setError(e error) {
|
||||
g.Unlock()
|
||||
}
|
||||
|
||||
// Close the gRPC send stream
|
||||
// #202 - inconsistent gRPC stream behavior
|
||||
// The underlying gRPC stream should not be closed here since the
|
||||
// stream should still be able to receive after this function call
|
||||
// TODO: should the conn be closed in another way?
|
||||
func (g *grpcStream) CloseSend() error {
|
||||
return g.stream.CloseSend()
|
||||
}
|
||||
|
||||
func (g *grpcStream) Close() error {
|
||||
g.Lock()
|
||||
defer g.Unlock()
|
||||
@ -83,6 +78,7 @@ func (g *grpcStream) Close() error {
|
||||
// cancel the context
|
||||
g.cancel()
|
||||
g.closed = true
|
||||
g.stream.CloseSend()
|
||||
return g.conn.Close()
|
||||
// release back to pool
|
||||
g.release(g.err)
|
||||
return nil
|
||||
}
|
||||
|
@ -120,6 +120,10 @@ func (h *httpStream) Error() error {
|
||||
return h.err
|
||||
}
|
||||
|
||||
func (h *httpStream) CloseSend() error {
|
||||
return errors.New("streamer not implemented")
|
||||
}
|
||||
|
||||
func (h *httpStream) Close() error {
|
||||
select {
|
||||
case <-h.closed:
|
||||
|
Loading…
Reference in New Issue
Block a user