Last active
June 24, 2020 03:37
-
-
Save jhump/3b29dbc042b9ce97536680046202f066 to your computer and use it in GitHub Desktop.
Example of using grpcui standalone package
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Code generated by protoc-gen-go. DO NOT EDIT. | |
// versions: | |
// protoc-gen-go v1.24.0-devel | |
// protoc v3.11.3 | |
// source: foo.proto | |
package main | |
import ( | |
context "context" | |
proto "github.com/golang/protobuf/proto" | |
empty "github.com/golang/protobuf/ptypes/empty" | |
grpc "google.golang.org/grpc" | |
codes "google.golang.org/grpc/codes" | |
status "google.golang.org/grpc/status" | |
protoreflect "google.golang.org/protobuf/reflect/protoreflect" | |
protoimpl "google.golang.org/protobuf/runtime/protoimpl" | |
reflect "reflect" | |
) | |
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) | |
) | |
// This is a compile-time assertion that a sufficiently up-to-date version | |
// of the legacy proto package is being used. | |
const _ = proto.ProtoPackageIsVersion4 | |
var File_foo_proto protoreflect.FileDescriptor | |
var file_foo_proto_rawDesc = []byte{ | |
0x0a, 0x09, 0x66, 0x6f, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x6d, 0x61, 0x69, | |
0x6e, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, | |
0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x3c, | |
0x0a, 0x03, 0x46, 0x6f, 0x6f, 0x12, 0x35, 0x0a, 0x03, 0x46, 0x6f, 0x6f, 0x12, 0x16, 0x2e, 0x67, | |
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, | |
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, | |
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x32, 0x3c, 0x0a, 0x03, | |
0x42, 0x61, 0x72, 0x12, 0x35, 0x0a, 0x03, 0x42, 0x61, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, | |
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, | |
0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, | |
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x32, 0x3c, 0x0a, 0x03, 0x42, 0x61, | |
0x7a, 0x12, 0x35, 0x0a, 0x03, 0x42, 0x61, 0x7a, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, | |
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, | |
0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, | |
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, | |
} | |
var file_foo_proto_goTypes = []interface{}{ | |
(*empty.Empty)(nil), // 0: google.protobuf.Empty | |
} | |
var file_foo_proto_depIdxs = []int32{ | |
0, // 0: main.Foo.Foo:input_type -> google.protobuf.Empty | |
0, // 1: main.Bar.Bar:input_type -> google.protobuf.Empty | |
0, // 2: main.Baz.Baz:input_type -> google.protobuf.Empty | |
0, // 3: main.Foo.Foo:output_type -> google.protobuf.Empty | |
0, // 4: main.Bar.Bar:output_type -> google.protobuf.Empty | |
0, // 5: main.Baz.Baz:output_type -> google.protobuf.Empty | |
3, // [3:6] is the sub-list for method output_type | |
0, // [0:3] 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_foo_proto_init() } | |
func file_foo_proto_init() { | |
if File_foo_proto != nil { | |
return | |
} | |
type x struct{} | |
out := protoimpl.TypeBuilder{ | |
File: protoimpl.DescBuilder{ | |
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), | |
RawDescriptor: file_foo_proto_rawDesc, | |
NumEnums: 0, | |
NumMessages: 0, | |
NumExtensions: 0, | |
NumServices: 3, | |
}, | |
GoTypes: file_foo_proto_goTypes, | |
DependencyIndexes: file_foo_proto_depIdxs, | |
}.Build() | |
File_foo_proto = out.File | |
file_foo_proto_rawDesc = nil | |
file_foo_proto_goTypes = nil | |
file_foo_proto_depIdxs = nil | |
} | |
// Reference imports to suppress errors if they are not otherwise used. | |
var _ context.Context | |
var _ grpc.ClientConnInterface | |
// 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.SupportPackageIsVersion6 | |
// FooClient is the client API for Foo service. | |
// | |
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. | |
type FooClient interface { | |
Foo(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*empty.Empty, error) | |
} | |
type fooClient struct { | |
cc grpc.ClientConnInterface | |
} | |
func NewFooClient(cc grpc.ClientConnInterface) FooClient { | |
return &fooClient{cc} | |
} | |
func (c *fooClient) Foo(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*empty.Empty, error) { | |
out := new(empty.Empty) | |
err := c.cc.Invoke(ctx, "/main.Foo/Foo", in, out, opts...) | |
if err != nil { | |
return nil, err | |
} | |
return out, nil | |
} | |
// FooServer is the server API for Foo service. | |
type FooServer interface { | |
Foo(context.Context, *empty.Empty) (*empty.Empty, error) | |
} | |
// UnimplementedFooServer can be embedded to have forward compatible implementations. | |
type UnimplementedFooServer struct { | |
} | |
func (*UnimplementedFooServer) Foo(context.Context, *empty.Empty) (*empty.Empty, error) { | |
return nil, status.Errorf(codes.Unimplemented, "method Foo not implemented") | |
} | |
func RegisterFooServer(s *grpc.Server, srv FooServer) { | |
s.RegisterService(&_Foo_serviceDesc, srv) | |
} | |
func _Foo_Foo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { | |
in := new(empty.Empty) | |
if err := dec(in); err != nil { | |
return nil, err | |
} | |
if interceptor == nil { | |
return srv.(FooServer).Foo(ctx, in) | |
} | |
info := &grpc.UnaryServerInfo{ | |
Server: srv, | |
FullMethod: "/main.Foo/Foo", | |
} | |
handler := func(ctx context.Context, req interface{}) (interface{}, error) { | |
return srv.(FooServer).Foo(ctx, req.(*empty.Empty)) | |
} | |
return interceptor(ctx, in, info, handler) | |
} | |
var _Foo_serviceDesc = grpc.ServiceDesc{ | |
ServiceName: "main.Foo", | |
HandlerType: (*FooServer)(nil), | |
Methods: []grpc.MethodDesc{ | |
{ | |
MethodName: "Foo", | |
Handler: _Foo_Foo_Handler, | |
}, | |
}, | |
Streams: []grpc.StreamDesc{}, | |
Metadata: "foo.proto", | |
} | |
// BarClient is the client API for Bar service. | |
// | |
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. | |
type BarClient interface { | |
Bar(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*empty.Empty, error) | |
} | |
type barClient struct { | |
cc grpc.ClientConnInterface | |
} | |
func NewBarClient(cc grpc.ClientConnInterface) BarClient { | |
return &barClient{cc} | |
} | |
func (c *barClient) Bar(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*empty.Empty, error) { | |
out := new(empty.Empty) | |
err := c.cc.Invoke(ctx, "/main.Bar/Bar", in, out, opts...) | |
if err != nil { | |
return nil, err | |
} | |
return out, nil | |
} | |
// BarServer is the server API for Bar service. | |
type BarServer interface { | |
Bar(context.Context, *empty.Empty) (*empty.Empty, error) | |
} | |
// UnimplementedBarServer can be embedded to have forward compatible implementations. | |
type UnimplementedBarServer struct { | |
} | |
func (*UnimplementedBarServer) Bar(context.Context, *empty.Empty) (*empty.Empty, error) { | |
return nil, status.Errorf(codes.Unimplemented, "method Bar not implemented") | |
} | |
func RegisterBarServer(s *grpc.Server, srv BarServer) { | |
s.RegisterService(&_Bar_serviceDesc, srv) | |
} | |
func _Bar_Bar_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { | |
in := new(empty.Empty) | |
if err := dec(in); err != nil { | |
return nil, err | |
} | |
if interceptor == nil { | |
return srv.(BarServer).Bar(ctx, in) | |
} | |
info := &grpc.UnaryServerInfo{ | |
Server: srv, | |
FullMethod: "/main.Bar/Bar", | |
} | |
handler := func(ctx context.Context, req interface{}) (interface{}, error) { | |
return srv.(BarServer).Bar(ctx, req.(*empty.Empty)) | |
} | |
return interceptor(ctx, in, info, handler) | |
} | |
var _Bar_serviceDesc = grpc.ServiceDesc{ | |
ServiceName: "main.Bar", | |
HandlerType: (*BarServer)(nil), | |
Methods: []grpc.MethodDesc{ | |
{ | |
MethodName: "Bar", | |
Handler: _Bar_Bar_Handler, | |
}, | |
}, | |
Streams: []grpc.StreamDesc{}, | |
Metadata: "foo.proto", | |
} | |
// BazClient is the client API for Baz service. | |
// | |
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. | |
type BazClient interface { | |
Baz(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*empty.Empty, error) | |
} | |
type bazClient struct { | |
cc grpc.ClientConnInterface | |
} | |
func NewBazClient(cc grpc.ClientConnInterface) BazClient { | |
return &bazClient{cc} | |
} | |
func (c *bazClient) Baz(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*empty.Empty, error) { | |
out := new(empty.Empty) | |
err := c.cc.Invoke(ctx, "/main.Baz/Baz", in, out, opts...) | |
if err != nil { | |
return nil, err | |
} | |
return out, nil | |
} | |
// BazServer is the server API for Baz service. | |
type BazServer interface { | |
Baz(context.Context, *empty.Empty) (*empty.Empty, error) | |
} | |
// UnimplementedBazServer can be embedded to have forward compatible implementations. | |
type UnimplementedBazServer struct { | |
} | |
func (*UnimplementedBazServer) Baz(context.Context, *empty.Empty) (*empty.Empty, error) { | |
return nil, status.Errorf(codes.Unimplemented, "method Baz not implemented") | |
} | |
func RegisterBazServer(s *grpc.Server, srv BazServer) { | |
s.RegisterService(&_Baz_serviceDesc, srv) | |
} | |
func _Baz_Baz_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { | |
in := new(empty.Empty) | |
if err := dec(in); err != nil { | |
return nil, err | |
} | |
if interceptor == nil { | |
return srv.(BazServer).Baz(ctx, in) | |
} | |
info := &grpc.UnaryServerInfo{ | |
Server: srv, | |
FullMethod: "/main.Baz/Baz", | |
} | |
handler := func(ctx context.Context, req interface{}) (interface{}, error) { | |
return srv.(BazServer).Baz(ctx, req.(*empty.Empty)) | |
} | |
return interceptor(ctx, in, info, handler) | |
} | |
var _Baz_serviceDesc = grpc.ServiceDesc{ | |
ServiceName: "main.Baz", | |
HandlerType: (*BazServer)(nil), | |
Methods: []grpc.MethodDesc{ | |
{ | |
MethodName: "Baz", | |
Handler: _Baz_Baz_Handler, | |
}, | |
}, | |
Streams: []grpc.StreamDesc{}, | |
Metadata: "foo.proto", | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
syntax = "proto3"; | |
package main; | |
import "google/protobuf/empty.proto"; | |
service Foo { | |
rpc Foo(google.protobuf.Empty) returns (google.protobuf.Empty); | |
} | |
service Bar { | |
rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); | |
} | |
service Baz { | |
rpc Baz(google.protobuf.Empty) returns (google.protobuf.Empty); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
//go:generate protoc --go_out=plugins=grpc:./ foo.proto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"flag" | |
"fmt" | |
"net" | |
"net/http" | |
"os" | |
"path/filepath" | |
"github.com/fullstorydev/grpcui/standalone" | |
"github.com/golang/protobuf/ptypes/empty" | |
"google.golang.org/grpc" | |
"google.golang.org/grpc/reflection" | |
) | |
var grpcPort, httpPort int | |
func main() { | |
flag.IntVar(&grpcPort, "grpc-port", 1234, "port on which grpc server will listen") | |
flag.IntVar(&httpPort, "http-port", 1235, "port on which http server will listen") | |
flag.Parse() | |
run(context.Background()) | |
} | |
func run(ctx context.Context) { | |
//---------------------------- | |
// Start up our gRPC server | |
//---------------------------- | |
fmt.Printf("Starting gRPC server on port %d...\n", grpcPort) | |
svr := grpc.NewServer() | |
// register some gRPC services | |
RegisterFooServer(svr, newFooImpl()) | |
RegisterBarServer(svr, newBarImpl()) | |
RegisterBazServer(svr, newBazImpl()) | |
// also need the reflection service! | |
reflection.Register(svr) | |
l, err := net.Listen("tcp", fmt.Sprintf(":%d", grpcPort)) | |
if err != nil { | |
exitWithError("failed to open listen socket on port %d: %v", grpcPort, err) | |
} | |
go func() { | |
err := svr.Serve(l) | |
if err != nil { | |
exitWithError("failed to serve gRPC: %v", err) | |
} | |
}() | |
//---------------------------- | |
// Create a client | |
//---------------------------- | |
cc, err := grpc.Dial(fmt.Sprintf("127.0.0.1:%d", grpcPort), grpc.WithInsecure()) | |
if err != nil { | |
exitWithError("failed to create client to local server: %v", err) | |
} | |
//---------------------------- | |
// Create gRPCui handler | |
//---------------------------- | |
target := fmt.Sprintf("%s:%d", filepath.Base(os.Args[0]), grpcPort) | |
// This is all there is to it! | |
h, err := standalone.HandlerViaReflection(ctx, cc, target) | |
if err != nil { | |
exitWithError("failed to create client to local server: %v", err) | |
} | |
//---------------------------- | |
// Start up HTTP server | |
//---------------------------- | |
fmt.Printf("Starting HTTP server on port %d...\n", httpPort) | |
serveMux := http.NewServeMux() | |
// register the grpcui | |
serveMux.Handle("/grpcui/", http.StripPrefix("/grpcui", h)) | |
// register other handlers... | |
serveMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | |
w.Header().Set("content-type", "html") | |
_, _ = fmt.Fprintf(w, ` | |
<html> | |
<head><title>Example server</title></head> | |
<body> | |
<h1>Hello, world!</h1> | |
<p>Check out the gRPC UI <a href="/grpcui/">here</a>.</p> | |
</body> | |
</html> | |
`) | |
}) | |
l, err = net.Listen("tcp", fmt.Sprintf(":%d", httpPort)) | |
if err != nil { | |
exitWithError("failed to open listen socket on port %d: %v", httpPort, err) | |
} | |
err = http.Serve(l, serveMux) | |
if err != nil { | |
exitWithError("failed to serve HTTP: %v", err) | |
} | |
} | |
func exitWithError(msgFormat string, args ...interface{}) { | |
_, _ = fmt.Fprintf(os.Stderr, msgFormat, args...) | |
_, _ = fmt.Fprintln(os.Stderr) | |
os.Exit(1) | |
} | |
func newFooImpl() FooServer { | |
return impl{} | |
} | |
func newBarImpl() BarServer { | |
return impl{} | |
} | |
func newBazImpl() BazServer { | |
return impl{} | |
} | |
type impl struct { | |
} | |
func (i impl) Foo(context.Context, *empty.Empty) (*empty.Empty, error) { | |
return &empty.Empty{}, nil | |
} | |
func (i impl) Bar(context.Context, *empty.Empty) (*empty.Empty, error) { | |
return &empty.Empty{}, nil | |
} | |
func (i impl) Baz(context.Context, *empty.Empty) (*empty.Empty, error) { | |
return &empty.Empty{}, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment