mirror of
https://github.com/taigrr/wasm-experiments
synced 2025-01-18 04:03:21 -08:00
gRPC: Use grpc-wasm as client package
This commit is contained in:
@@ -38,3 +38,7 @@ func (b Backend) GetUser(ctx context.Context, req *server.GetUserRequest) (*serv
|
||||
Id: req.GetUserId(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b Backend) GetUsers(req *server.GetUsersRequest, srv server.Backend_GetUsersServer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
1
grpc/frontend/.gitignore
vendored
1
grpc/frontend/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
html/test.wasm
|
||||
File diff suppressed because one or more lines are too long
@@ -1,28 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
_ "google.golang.org/genproto/googleapis/rpc/errdetails"
|
||||
spb "google.golang.org/genproto/googleapis/rpc/status"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/johanbrandhorst/fetch"
|
||||
"github.com/johanbrandhorst/wasm-experiments/grpc/proto/server"
|
||||
grpc "github.com/johanbrandhorst/grpc-wasm"
|
||||
server "github.com/johanbrandhorst/wasm-experiments/grpc/proto/client"
|
||||
)
|
||||
|
||||
// Build with Go WASM fork
|
||||
@@ -33,220 +19,24 @@ import (
|
||||
//go:generate bash -c "go run assets_generate.go"
|
||||
|
||||
func main() {
|
||||
s := newClientConn("", "web.Backend")
|
||||
req := &server.GetUserRequest{
|
||||
cc, _ := grpc.Dial("")
|
||||
client := server.NewBackendClient(cc)
|
||||
resp, err := client.GetUser(context.Background(), &server.GetUserRequest{
|
||||
UserId: "1234",
|
||||
}
|
||||
resp := new(server.User)
|
||||
err := s.Invoke(context.Background(), "GetUser", req, resp)
|
||||
})
|
||||
if err != nil {
|
||||
st := status.Convert(err)
|
||||
fmt.Println(st.Code(), st.Message(), st.Details())
|
||||
return
|
||||
}
|
||||
fmt.Println(resp.GetId())
|
||||
req.UserId = "123"
|
||||
err = s.Invoke(context.Background(), "GetUser", req, resp)
|
||||
if err != nil {
|
||||
st := status.Convert(err)
|
||||
fmt.Println(st.Code(), st.Message(), st.Details())
|
||||
return
|
||||
}
|
||||
fmt.Println(resp.GetId())
|
||||
}
|
||||
|
||||
type ClientConn struct {
|
||||
client *http.Client
|
||||
service string
|
||||
host string
|
||||
}
|
||||
|
||||
func newClientConn(host, service string) *ClientConn {
|
||||
return &ClientConn{
|
||||
client: &http.Client{
|
||||
Transport: &fetch.Transport{},
|
||||
},
|
||||
service: service,
|
||||
host: host,
|
||||
}
|
||||
}
|
||||
|
||||
func (cc *ClientConn) Invoke(ctx context.Context, method string, in, out proto.Message) error {
|
||||
b, err := proto.Marshal(in)
|
||||
if err != nil {
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
bufHeader := make([]byte, 5)
|
||||
|
||||
// Write length of b into buf
|
||||
binary.BigEndian.PutUint32(bufHeader[1:], uint32(len(b)))
|
||||
|
||||
req, err := http.NewRequest(
|
||||
"POST",
|
||||
strings.Join([]string{cc.host, cc.service, method}, "/"),
|
||||
bytes.NewBuffer(append(bufHeader, b...)),
|
||||
)
|
||||
if err != nil {
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
addHeaders(req)
|
||||
|
||||
resp, err := cc.client.Do(req)
|
||||
if err != nil {
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
st := statusFromHeaders(resp.Header)
|
||||
if st.Code() != codes.OK {
|
||||
return st.Err()
|
||||
}
|
||||
|
||||
msgHeader := make([]byte, 5)
|
||||
for {
|
||||
_, err := resp.Body.Read(msgHeader)
|
||||
if err != nil {
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
// 1 in MSB signifies that this is the trailer. Break loop.
|
||||
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2
|
||||
if msgHeader[0]>>7 == 1 {
|
||||
break
|
||||
}
|
||||
|
||||
msgLen := binary.BigEndian.Uint32(msgHeader[1:])
|
||||
|
||||
msg := make([]byte, msgLen)
|
||||
_, err = resp.Body.Read(msg)
|
||||
if err != nil {
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
err = proto.Unmarshal(msg, out)
|
||||
if err != nil {
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if msgHeader[0]&1 == 0 {
|
||||
trailers, err := readTrailers(resp.Body)
|
||||
if err != nil {
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
st = statusFromHeaders(trailers)
|
||||
if st.Code() != codes.OK {
|
||||
return st.Err()
|
||||
}
|
||||
} else {
|
||||
// TODO(johanbrandhorst): Support compressed trailers
|
||||
fmt.Println(resp.GetId())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func addHeaders(req *http.Request) {
|
||||
// TODO: Add more headers
|
||||
// https://github.com/grpc/grpc-go/blob/590da37e2dfb4705d8ebd9574ce4cb75295d9674/transport/http2_client.go#L356
|
||||
req.Header.Add("content-type", "application/grpc-web+proto")
|
||||
if dl, ok := req.Context().Deadline(); ok {
|
||||
timeout := dl.Sub(time.Now())
|
||||
req.Header.Add("grpc-timeout", encodeTimeout(timeout))
|
||||
}
|
||||
md, ok := metadata.FromOutgoingContext(req.Context())
|
||||
if ok {
|
||||
for h, vs := range md {
|
||||
for _, v := range vs {
|
||||
req.Header.Add(h, v)
|
||||
}
|
||||
}
|
||||
resp, err = client.GetUser(context.Background(), &server.GetUserRequest{
|
||||
UserId: "123",
|
||||
})
|
||||
if err != nil {
|
||||
st := status.Convert(err)
|
||||
fmt.Println(st.Code(), st.Message(), st.Details())
|
||||
} else {
|
||||
fmt.Println(resp.GetId())
|
||||
}
|
||||
}
|
||||
|
||||
const maxTimeoutValue int64 = 100000000 - 1
|
||||
|
||||
// Copied from grpc-go
|
||||
// https://github.com/grpc/grpc-go/blob/590da37e2dfb4705d8ebd9574ce4cb75295d9674/transport/http_util.go#L388
|
||||
// div does integer division and round-up the result. Note that this is
|
||||
// equivalent to (d+r-1)/r but has less chance to overflow.
|
||||
func div(d, r time.Duration) int64 {
|
||||
if m := d % r; m > 0 {
|
||||
return int64(d/r + 1)
|
||||
}
|
||||
return int64(d / r)
|
||||
}
|
||||
|
||||
// Copied from grpc-go
|
||||
// https://github.com/grpc/grpc-go/blob/590da37e2dfb4705d8ebd9574ce4cb75295d9674/transport/http_util.go#L398
|
||||
func encodeTimeout(t time.Duration) string {
|
||||
if t <= 0 {
|
||||
return "0n"
|
||||
}
|
||||
if d := div(t, time.Nanosecond); d <= maxTimeoutValue {
|
||||
return strconv.FormatInt(d, 10) + "n"
|
||||
}
|
||||
if d := div(t, time.Microsecond); d <= maxTimeoutValue {
|
||||
return strconv.FormatInt(d, 10) + "u"
|
||||
}
|
||||
if d := div(t, time.Millisecond); d <= maxTimeoutValue {
|
||||
return strconv.FormatInt(d, 10) + "m"
|
||||
}
|
||||
if d := div(t, time.Second); d <= maxTimeoutValue {
|
||||
return strconv.FormatInt(d, 10) + "S"
|
||||
}
|
||||
if d := div(t, time.Minute); d <= maxTimeoutValue {
|
||||
return strconv.FormatInt(d, 10) + "M"
|
||||
}
|
||||
// Note that maxTimeoutValue * time.Hour > MaxInt64.
|
||||
return strconv.FormatInt(div(t, time.Hour), 10) + "H"
|
||||
}
|
||||
|
||||
// Copied from grpc-go
|
||||
// https://github.com/grpc/grpc-go/blob/b94ea975f3beb73799fac17cc24ee923fcd3cb5c/transport/http_util.go#L213
|
||||
func decodeBinHeader(v string) ([]byte, error) {
|
||||
if len(v)%4 == 0 {
|
||||
// Input was padded, or padding was not necessary.
|
||||
return base64.StdEncoding.DecodeString(v)
|
||||
}
|
||||
return base64.RawStdEncoding.DecodeString(v)
|
||||
}
|
||||
|
||||
func readTrailers(in io.Reader) (http.Header, error) {
|
||||
s := bufio.NewScanner(in)
|
||||
trailers := http.Header{}
|
||||
for s.Scan() {
|
||||
v := s.Text()
|
||||
kv := strings.SplitN(v, ": ", 2)
|
||||
if len(kv) != 2 {
|
||||
return nil, errors.New("malformed header: " + v)
|
||||
}
|
||||
trailers.Add(kv[0], kv[1])
|
||||
}
|
||||
|
||||
return trailers, s.Err()
|
||||
}
|
||||
|
||||
func statusFromHeaders(h http.Header) *status.Status {
|
||||
details := h.Get("grpc-status-details-bin")
|
||||
if details != "" {
|
||||
b, err := decodeBinHeader(details)
|
||||
if err != nil {
|
||||
return status.New(codes.Internal, "malformed grps-status-details-bin header: "+err.Error())
|
||||
}
|
||||
s := &spb.Status{}
|
||||
err = proto.Unmarshal(b, s)
|
||||
if err != nil {
|
||||
return status.New(codes.Internal, "malformed grps-status-details-bin header: "+err.Error())
|
||||
}
|
||||
return status.FromProto(s)
|
||||
}
|
||||
sh := h.Get("grpc-status")
|
||||
if sh != "" {
|
||||
val, err := strconv.Atoi(sh)
|
||||
if err != nil {
|
||||
return status.New(codes.Internal, "malformed grpc-status header: "+err.Error())
|
||||
}
|
||||
return status.New(codes.Code(val), h.Get("grpc-message"))
|
||||
}
|
||||
return status.New(codes.OK, "")
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
import (
|
||||
grpc "github.com/johanbrandhorst/grpc-wasm"
|
||||
context "golang.org/x/net/context"
|
||||
grpc "google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@@ -38,7 +38,7 @@ func (m *GetUserRequest) Reset() { *m = GetUserRequest{} }
|
||||
func (m *GetUserRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetUserRequest) ProtoMessage() {}
|
||||
func (*GetUserRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_web_19a831568a3bf959, []int{0}
|
||||
return fileDescriptor_web_87670d45010119fa, []int{0}
|
||||
}
|
||||
func (m *GetUserRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_GetUserRequest.Unmarshal(m, b)
|
||||
@@ -76,7 +76,7 @@ func (m *User) Reset() { *m = User{} }
|
||||
func (m *User) String() string { return proto.CompactTextString(m) }
|
||||
func (*User) ProtoMessage() {}
|
||||
func (*User) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_web_19a831568a3bf959, []int{1}
|
||||
return fileDescriptor_web_87670d45010119fa, []int{1}
|
||||
}
|
||||
func (m *User) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_User.Unmarshal(m, b)
|
||||
@@ -103,9 +103,48 @@ func (m *User) GetId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetUsersRequest struct {
|
||||
NumUsers int64 `protobuf:"varint,1,opt,name=num_users,json=numUsers" json:"num_users,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *GetUsersRequest) Reset() { *m = GetUsersRequest{} }
|
||||
func (m *GetUsersRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetUsersRequest) ProtoMessage() {}
|
||||
func (*GetUsersRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_web_87670d45010119fa, []int{2}
|
||||
}
|
||||
func (m *GetUsersRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_GetUsersRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *GetUsersRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_GetUsersRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *GetUsersRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GetUsersRequest.Merge(dst, src)
|
||||
}
|
||||
func (m *GetUsersRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_GetUsersRequest.Size(m)
|
||||
}
|
||||
func (m *GetUsersRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GetUsersRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GetUsersRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *GetUsersRequest) GetNumUsers() int64 {
|
||||
if m != nil {
|
||||
return m.NumUsers
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*GetUserRequest)(nil), "web.GetUserRequest")
|
||||
proto.RegisterType((*User)(nil), "web.User")
|
||||
proto.RegisterType((*GetUsersRequest)(nil), "web.GetUsersRequest")
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@@ -121,6 +160,7 @@ const _ = grpc.SupportPackageIsVersion4
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type BackendClient interface {
|
||||
GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*User, error)
|
||||
GetUsers(ctx context.Context, in *GetUsersRequest, opts ...grpc.CallOption) (Backend_GetUsersClient, error)
|
||||
}
|
||||
|
||||
type backendClient struct {
|
||||
@@ -140,9 +180,42 @@ func (c *backendClient) GetUser(ctx context.Context, in *GetUserRequest, opts ..
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *backendClient) GetUsers(ctx context.Context, in *GetUsersRequest, opts ...grpc.CallOption) (Backend_GetUsersClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &_Backend_serviceDesc.Streams[0], "/web.Backend/GetUsers", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &backendGetUsersClient{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 Backend_GetUsersClient interface {
|
||||
Recv() (*User, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type backendGetUsersClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *backendGetUsersClient) Recv() (*User, error) {
|
||||
m := new(User)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// BackendServer is the server API for Backend service.
|
||||
type BackendServer interface {
|
||||
GetUser(context.Context, *GetUserRequest) (*User, error)
|
||||
GetUsers(*GetUsersRequest, Backend_GetUsersServer) error
|
||||
}
|
||||
|
||||
func RegisterBackendServer(s *grpc.Server, srv BackendServer) {
|
||||
@@ -167,6 +240,27 @@ func _Backend_GetUser_Handler(srv interface{}, ctx context.Context, dec func(int
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Backend_GetUsers_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(GetUsersRequest)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(BackendServer).GetUsers(m, &backendGetUsersServer{stream})
|
||||
}
|
||||
|
||||
type Backend_GetUsersServer interface {
|
||||
Send(*User) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type backendGetUsersServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *backendGetUsersServer) Send(m *User) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
var _Backend_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "web.Backend",
|
||||
HandlerType: (*BackendServer)(nil),
|
||||
@@ -176,25 +270,33 @@ var _Backend_serviceDesc = grpc.ServiceDesc{
|
||||
Handler: _Backend_GetUser_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "GetUsers",
|
||||
Handler: _Backend_GetUsers_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "proto/web.proto",
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("proto/web.proto", fileDescriptor_web_19a831568a3bf959) }
|
||||
func init() { proto.RegisterFile("proto/web.proto", fileDescriptor_web_87670d45010119fa) }
|
||||
|
||||
var fileDescriptor_web_19a831568a3bf959 = []byte{
|
||||
// 197 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2f, 0x28, 0xca, 0x2f,
|
||||
0xc9, 0xd7, 0x2f, 0x4f, 0x4d, 0xd2, 0x03, 0xb3, 0x84, 0x98, 0xcb, 0x53, 0x93, 0x94, 0x34, 0xb9,
|
||||
0xf8, 0xdc, 0x53, 0x4b, 0x42, 0x8b, 0x53, 0x8b, 0x82, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84,
|
||||
0xc4, 0xb9, 0xd8, 0x4b, 0x8b, 0x53, 0x8b, 0xe2, 0x33, 0x53, 0x24, 0x18, 0x15, 0x18, 0x35, 0x38,
|
||||
0x83, 0xd8, 0x40, 0x5c, 0xcf, 0x14, 0x25, 0x31, 0x2e, 0x16, 0x90, 0x3a, 0x21, 0x3e, 0x2e, 0x26,
|
||||
0xb8, 0x1c, 0x53, 0x66, 0x8a, 0x91, 0x19, 0x17, 0xbb, 0x53, 0x62, 0x72, 0x76, 0x6a, 0x5e, 0x8a,
|
||||
0x90, 0x36, 0x17, 0x3b, 0xd4, 0x34, 0x21, 0x61, 0x3d, 0x90, 0x4d, 0xa8, 0x66, 0x4b, 0x71, 0x82,
|
||||
0x05, 0x41, 0x22, 0x4a, 0x0c, 0x4e, 0xf6, 0x51, 0xb6, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a,
|
||||
0xc9, 0xf9, 0xb9, 0xfa, 0x59, 0xf9, 0x19, 0x89, 0x79, 0x49, 0x45, 0x89, 0x79, 0x29, 0x19, 0xf9,
|
||||
0x45, 0xc5, 0x25, 0xfa, 0xe5, 0x89, 0xc5, 0xb9, 0xba, 0xa9, 0x15, 0x05, 0xa9, 0x45, 0x99, 0xb9,
|
||||
0xa9, 0x79, 0x25, 0xc5, 0xfa, 0xe9, 0x45, 0x05, 0xc9, 0xfa, 0x10, 0x3f, 0x14, 0xa7, 0x16, 0x95,
|
||||
0xa5, 0x16, 0x25, 0xb1, 0x81, 0x79, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x64, 0xf1,
|
||||
0x41, 0xda, 0x00, 0x00, 0x00,
|
||||
var fileDescriptor_web_87670d45010119fa = []byte{
|
||||
// 236 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xc1, 0x4b, 0xc3, 0x30,
|
||||
0x18, 0xc5, 0xdd, 0x26, 0xeb, 0xfa, 0x1d, 0x36, 0x88, 0xa2, 0xa2, 0x17, 0xe9, 0x49, 0x11, 0x1b,
|
||||
0xd1, 0xb3, 0x08, 0xbb, 0x88, 0xd7, 0x82, 0x17, 0x2f, 0xa3, 0x69, 0x3e, 0xda, 0x2a, 0x49, 0xea,
|
||||
0xf7, 0x25, 0xd6, 0x3f, 0x5f, 0x12, 0x37, 0x51, 0xf0, 0x96, 0xf7, 0xf2, 0x7b, 0x2f, 0x8f, 0xc0,
|
||||
0x6a, 0x20, 0xe7, 0x9d, 0x1c, 0x51, 0x95, 0xe9, 0x24, 0x66, 0x23, 0xaa, 0xe2, 0x12, 0x96, 0x8f,
|
||||
0xe8, 0x9f, 0x19, 0xa9, 0xc2, 0xf7, 0x80, 0xec, 0xc5, 0x31, 0x64, 0x81, 0x91, 0x36, 0xbd, 0x3e,
|
||||
0x99, 0x9c, 0x4f, 0x2e, 0xf2, 0x6a, 0x1e, 0xe5, 0x93, 0x2e, 0x8e, 0x60, 0x3f, 0x72, 0x62, 0x09,
|
||||
0xd3, 0x9f, 0xbb, 0x69, 0xaf, 0x8b, 0x12, 0x56, 0xdb, 0x0a, 0xde, 0x75, 0x9c, 0x41, 0x6e, 0x83,
|
||||
0xd9, 0xc4, 0x20, 0x27, 0x72, 0x56, 0x2d, 0x6c, 0x30, 0x89, 0xb9, 0x6d, 0x21, 0x5b, 0xd7, 0xcd,
|
||||
0x1b, 0x5a, 0x2d, 0xae, 0x20, 0xdb, 0x46, 0xc5, 0x41, 0x19, 0x97, 0xfd, 0xdd, 0x72, 0x9a, 0x27,
|
||||
0x33, 0x3a, 0xc5, 0x9e, 0x90, 0xb0, 0xd8, 0xbd, 0x23, 0x0e, 0x7f, 0xd3, 0xfc, 0x1f, 0x7e, 0x33,
|
||||
0x59, 0x3f, 0xbc, 0xdc, 0xb7, 0xbd, 0xef, 0x82, 0x2a, 0x1b, 0x67, 0xe4, 0xab, 0xeb, 0x6a, 0xab,
|
||||
0xa8, 0xb6, 0xba, 0x73, 0xc4, 0x5e, 0x8e, 0x35, 0x9b, 0x6b, 0xfc, 0x1c, 0x90, 0x7a, 0x83, 0xd6,
|
||||
0xb3, 0x6c, 0x69, 0x68, 0xe4, 0xf7, 0x27, 0x31, 0xd2, 0x07, 0x92, 0x9a, 0x27, 0x75, 0xf7, 0x15,
|
||||
0x00, 0x00, 0xff, 0xff, 0x75, 0x28, 0x26, 0x8f, 0x3b, 0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ func (m *GetUserRequest) Reset() { *m = GetUserRequest{} }
|
||||
func (m *GetUserRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetUserRequest) ProtoMessage() {}
|
||||
func (*GetUserRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_web_19a831568a3bf959, []int{0}
|
||||
return fileDescriptor_web_87670d45010119fa, []int{0}
|
||||
}
|
||||
func (m *GetUserRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_GetUserRequest.Unmarshal(m, b)
|
||||
@@ -76,7 +76,7 @@ func (m *User) Reset() { *m = User{} }
|
||||
func (m *User) String() string { return proto.CompactTextString(m) }
|
||||
func (*User) ProtoMessage() {}
|
||||
func (*User) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_web_19a831568a3bf959, []int{1}
|
||||
return fileDescriptor_web_87670d45010119fa, []int{1}
|
||||
}
|
||||
func (m *User) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_User.Unmarshal(m, b)
|
||||
@@ -103,9 +103,48 @@ func (m *User) GetId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetUsersRequest struct {
|
||||
NumUsers int64 `protobuf:"varint,1,opt,name=num_users,json=numUsers" json:"num_users,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *GetUsersRequest) Reset() { *m = GetUsersRequest{} }
|
||||
func (m *GetUsersRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetUsersRequest) ProtoMessage() {}
|
||||
func (*GetUsersRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_web_87670d45010119fa, []int{2}
|
||||
}
|
||||
func (m *GetUsersRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_GetUsersRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *GetUsersRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_GetUsersRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *GetUsersRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GetUsersRequest.Merge(dst, src)
|
||||
}
|
||||
func (m *GetUsersRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_GetUsersRequest.Size(m)
|
||||
}
|
||||
func (m *GetUsersRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GetUsersRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GetUsersRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *GetUsersRequest) GetNumUsers() int64 {
|
||||
if m != nil {
|
||||
return m.NumUsers
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*GetUserRequest)(nil), "web.GetUserRequest")
|
||||
proto.RegisterType((*User)(nil), "web.User")
|
||||
proto.RegisterType((*GetUsersRequest)(nil), "web.GetUsersRequest")
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@@ -121,6 +160,7 @@ const _ = grpc.SupportPackageIsVersion4
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type BackendClient interface {
|
||||
GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*User, error)
|
||||
GetUsers(ctx context.Context, in *GetUsersRequest, opts ...grpc.CallOption) (Backend_GetUsersClient, error)
|
||||
}
|
||||
|
||||
type backendClient struct {
|
||||
@@ -140,9 +180,42 @@ func (c *backendClient) GetUser(ctx context.Context, in *GetUserRequest, opts ..
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *backendClient) GetUsers(ctx context.Context, in *GetUsersRequest, opts ...grpc.CallOption) (Backend_GetUsersClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &_Backend_serviceDesc.Streams[0], "/web.Backend/GetUsers", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &backendGetUsersClient{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 Backend_GetUsersClient interface {
|
||||
Recv() (*User, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type backendGetUsersClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *backendGetUsersClient) Recv() (*User, error) {
|
||||
m := new(User)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// BackendServer is the server API for Backend service.
|
||||
type BackendServer interface {
|
||||
GetUser(context.Context, *GetUserRequest) (*User, error)
|
||||
GetUsers(*GetUsersRequest, Backend_GetUsersServer) error
|
||||
}
|
||||
|
||||
func RegisterBackendServer(s *grpc.Server, srv BackendServer) {
|
||||
@@ -167,6 +240,27 @@ func _Backend_GetUser_Handler(srv interface{}, ctx context.Context, dec func(int
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Backend_GetUsers_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(GetUsersRequest)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(BackendServer).GetUsers(m, &backendGetUsersServer{stream})
|
||||
}
|
||||
|
||||
type Backend_GetUsersServer interface {
|
||||
Send(*User) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type backendGetUsersServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *backendGetUsersServer) Send(m *User) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
var _Backend_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "web.Backend",
|
||||
HandlerType: (*BackendServer)(nil),
|
||||
@@ -176,25 +270,33 @@ var _Backend_serviceDesc = grpc.ServiceDesc{
|
||||
Handler: _Backend_GetUser_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "GetUsers",
|
||||
Handler: _Backend_GetUsers_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "proto/web.proto",
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("proto/web.proto", fileDescriptor_web_19a831568a3bf959) }
|
||||
func init() { proto.RegisterFile("proto/web.proto", fileDescriptor_web_87670d45010119fa) }
|
||||
|
||||
var fileDescriptor_web_19a831568a3bf959 = []byte{
|
||||
// 197 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2f, 0x28, 0xca, 0x2f,
|
||||
0xc9, 0xd7, 0x2f, 0x4f, 0x4d, 0xd2, 0x03, 0xb3, 0x84, 0x98, 0xcb, 0x53, 0x93, 0x94, 0x34, 0xb9,
|
||||
0xf8, 0xdc, 0x53, 0x4b, 0x42, 0x8b, 0x53, 0x8b, 0x82, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84,
|
||||
0xc4, 0xb9, 0xd8, 0x4b, 0x8b, 0x53, 0x8b, 0xe2, 0x33, 0x53, 0x24, 0x18, 0x15, 0x18, 0x35, 0x38,
|
||||
0x83, 0xd8, 0x40, 0x5c, 0xcf, 0x14, 0x25, 0x31, 0x2e, 0x16, 0x90, 0x3a, 0x21, 0x3e, 0x2e, 0x26,
|
||||
0xb8, 0x1c, 0x53, 0x66, 0x8a, 0x91, 0x19, 0x17, 0xbb, 0x53, 0x62, 0x72, 0x76, 0x6a, 0x5e, 0x8a,
|
||||
0x90, 0x36, 0x17, 0x3b, 0xd4, 0x34, 0x21, 0x61, 0x3d, 0x90, 0x4d, 0xa8, 0x66, 0x4b, 0x71, 0x82,
|
||||
0x05, 0x41, 0x22, 0x4a, 0x0c, 0x4e, 0xf6, 0x51, 0xb6, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a,
|
||||
0xc9, 0xf9, 0xb9, 0xfa, 0x59, 0xf9, 0x19, 0x89, 0x79, 0x49, 0x45, 0x89, 0x79, 0x29, 0x19, 0xf9,
|
||||
0x45, 0xc5, 0x25, 0xfa, 0xe5, 0x89, 0xc5, 0xb9, 0xba, 0xa9, 0x15, 0x05, 0xa9, 0x45, 0x99, 0xb9,
|
||||
0xa9, 0x79, 0x25, 0xc5, 0xfa, 0xe9, 0x45, 0x05, 0xc9, 0xfa, 0x10, 0x3f, 0x14, 0xa7, 0x16, 0x95,
|
||||
0xa5, 0x16, 0x25, 0xb1, 0x81, 0x79, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x64, 0xf1,
|
||||
0x41, 0xda, 0x00, 0x00, 0x00,
|
||||
var fileDescriptor_web_87670d45010119fa = []byte{
|
||||
// 236 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xc1, 0x4b, 0xc3, 0x30,
|
||||
0x18, 0xc5, 0xdd, 0x26, 0xeb, 0xfa, 0x1d, 0x36, 0x88, 0xa2, 0xa2, 0x17, 0xe9, 0x49, 0x11, 0x1b,
|
||||
0xd1, 0xb3, 0x08, 0xbb, 0x88, 0xd7, 0x82, 0x17, 0x2f, 0xa3, 0x69, 0x3e, 0xda, 0x2a, 0x49, 0xea,
|
||||
0xf7, 0x25, 0xd6, 0x3f, 0x5f, 0x12, 0x37, 0x51, 0xf0, 0x96, 0xf7, 0xf2, 0x7b, 0x2f, 0x8f, 0xc0,
|
||||
0x6a, 0x20, 0xe7, 0x9d, 0x1c, 0x51, 0x95, 0xe9, 0x24, 0x66, 0x23, 0xaa, 0xe2, 0x12, 0x96, 0x8f,
|
||||
0xe8, 0x9f, 0x19, 0xa9, 0xc2, 0xf7, 0x80, 0xec, 0xc5, 0x31, 0x64, 0x81, 0x91, 0x36, 0xbd, 0x3e,
|
||||
0x99, 0x9c, 0x4f, 0x2e, 0xf2, 0x6a, 0x1e, 0xe5, 0x93, 0x2e, 0x8e, 0x60, 0x3f, 0x72, 0x62, 0x09,
|
||||
0xd3, 0x9f, 0xbb, 0x69, 0xaf, 0x8b, 0x12, 0x56, 0xdb, 0x0a, 0xde, 0x75, 0x9c, 0x41, 0x6e, 0x83,
|
||||
0xd9, 0xc4, 0x20, 0x27, 0x72, 0x56, 0x2d, 0x6c, 0x30, 0x89, 0xb9, 0x6d, 0x21, 0x5b, 0xd7, 0xcd,
|
||||
0x1b, 0x5a, 0x2d, 0xae, 0x20, 0xdb, 0x46, 0xc5, 0x41, 0x19, 0x97, 0xfd, 0xdd, 0x72, 0x9a, 0x27,
|
||||
0x33, 0x3a, 0xc5, 0x9e, 0x90, 0xb0, 0xd8, 0xbd, 0x23, 0x0e, 0x7f, 0xd3, 0xfc, 0x1f, 0x7e, 0x33,
|
||||
0x59, 0x3f, 0xbc, 0xdc, 0xb7, 0xbd, 0xef, 0x82, 0x2a, 0x1b, 0x67, 0xe4, 0xab, 0xeb, 0x6a, 0xab,
|
||||
0xa8, 0xb6, 0xba, 0x73, 0xc4, 0x5e, 0x8e, 0x35, 0x9b, 0x6b, 0xfc, 0x1c, 0x90, 0x7a, 0x83, 0xd6,
|
||||
0xb3, 0x6c, 0x69, 0x68, 0xe4, 0xf7, 0x27, 0x31, 0xd2, 0x07, 0x92, 0x9a, 0x27, 0x75, 0xf7, 0x15,
|
||||
0x00, 0x00, 0xff, 0xff, 0x75, 0x28, 0x26, 0x8f, 0x3b, 0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ option go_package = "github.com/johanbrandhorst/wasm-experiments/grpc/proto/serv
|
||||
// Backend defines the interface exposed by the backend.
|
||||
service Backend {
|
||||
rpc GetUser(GetUserRequest) returns (User) {}
|
||||
rpc GetUsers(GetUsersRequest) returns (stream User) {}
|
||||
}
|
||||
|
||||
message GetUserRequest {
|
||||
@@ -17,3 +18,7 @@ message GetUserRequest {
|
||||
message User {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message GetUsersRequest {
|
||||
int64 num_users = 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user