Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EOF is received after one request #1071

Closed
DieYoungWsn opened this issue Oct 31, 2019 · 1 comment
Closed

EOF is received after one request #1071

DieYoungWsn opened this issue Oct 31, 2019 · 1 comment

Comments

@DieYoungWsn
Copy link

Hi,
After a normal HTTP request, the GRPC receives the EOF. Can't the gateway maintain a long connection to the gRPC?

gateway code:

var (
	// command-line options:
	// gRPC server endpoint
	grpcServerEndpoint = flag.String("grpc-server-endpoint", "localhost:9090", "gRPC server endpoint")
)

func run() error {
	ctx := context.Background()
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	// Register gRPC server endpoint
	// Note: Make sure the gRPC server is running properly and accessible
	mux := runtime.NewServeMux()
	opts := []grpc.DialOption{grpc.WithInsecure()}
	err := gw.RegisterDieYoungServiceHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts)
	if err != nil {
		return err
	}

	// Start HTTP server (and proxy calls to gRPC server endpoint)
	return http.ListenAndServe(":8081", mux)
}

func main() {
	flag.Parse()

	if err := run(); err != nil {
		fmt.Println("run err :", err)
		return
	}
}

gRPC server code:

type GRPCServer struct {
	// Listen address for the server specified as hostname:port
	address string
	// Listener for handling network requests
	listener net.Listener
	// GRPC server
	server *grpc.Server
}

type GrpcServerImpl struct {
	proto.DieYoungService_DieYoungSearchServer
}

func (gs *GrpcServerImpl) DieYoungSearch(stream proto.DieYoungService_DieYoungSearchServer) error {
	for {
		in, err := stream.Recv()
		if err == io.EOF {
			fmt.Println("server recv eof")
			return nil
		}
		if err != nil {
			fmt.Printf("failed to recv: %v\n", err)
			return err
		}
		fmt.Println(in.Foo)
		stream.Send(&proto.DieYoungMsg{Foo: "bar Server"})
	}
	return nil
}
func main() {
	address := "127.0.0.1:9090"
	listener, err := net.Listen("tcp", address)
	if err != nil {
		fmt.Println("lis err: ", err)
		return
	}
	var serverOpts []grpc.ServerOption
	grpcServer := &GRPCServer{
		address:  listener.Addr().String(),
		listener: listener,
	}
	grpcServer.server = grpc.NewServer(serverOpts...)
	proto.RegisterDieYoungServiceServer(grpcServer.server, &GrpcServerImpl{})

	if err := grpcServer.server.Serve(grpcServer.listener); err != nil {
		fmt.Println("failed to start server")
	}
}

protobuf:

syntax = "proto3";

package protos;
import "google/api/annotations.proto";

message DieYoungMsg {
    string foo = 1;
}

service DieYoungService {
    rpc DieYoungSearch(stream DieYoungMsg) returns (stream DieYoungMsg) {
        option (google.api.http) = {
              post: "/v1/example/echo"
              body: "*"
            };
    }
}

request and output:

curl -XPOST localhost:8081/v1/example/echo -d '{"foo":"wsn"}'

{"result":{"foo":"bar Server"}}

gRPC server output:

wsn
server recv eof
@johanbrandhorst
Copy link
Collaborator

This is a misunderstanding of gRPC semantics. io.EOF is always returned at the succesful end of a streaming call. It doesn't imply that the underlying HTTP/2 connection is closed, just that the stream has ended. See https://www.grpc.io/docs/tutorials/basic/go/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants