This project demonstrates how to set up a simple gRPC communication between a web client and server with an Envoy proxy.
I’m using the gRPC-Web library for this purpose. gRPC-Web is a JavaScript client library that allows web applications to interact with gRPC services. Since browsers don't support HTTP/2 or the binary protocol used by standard gRPC, gRPC-Web provides a way to bridge the gap by using HTTP/1.1 or HTTP/2 and encoding gRPC messages in a way that browsers can handle. Here's how gRPC-Web works:
The request is encoded in a gRPC-Web format, typically using base64 encoding for the binary gRPC payload. The client sends this request over HTTP/1.1 or HTTP/2.
The gRPC server processes the request as if it were a native gRPC request, using HTTP/2 for communication.
The gRPC server processes the incoming gRPC request, performs the necessary business logic, and generates a response (in this example it’s the Go written application). The response is encoded in the standard gRPC format and sent back to Envoy.
Envoy receives the gRPC response, encodes it in the gRPC-Web format (typically using base64), and sends it back to the gRPC-Web client over HTTP/1.1 or HTTP/2. Any metadata included in the gRPC response, such as status codes, is translated appropriately.
The gRPC-Web client decodes the response and converts it into a usable format within the web application. The web application processes the response, updating the UI or handling errors as needed.
NOTE: client-side and bi-directional streaming is not currently supported (see streaming roadmap)
Here is a GitHub project for it:
https://github.com/ehsaniara/gRPC-web-example
syntax = "proto3"; package helloworld; option go_package = "./proto"; // Add this line service Greeter { rpc SayHello (HelloRequest) returns (HelloReply); } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
package main import ( "context" "google.golang.org/grpc/reflection" "log" "net" pb "github.com/ehsaniara/gRPC-web-example/proto" "google.golang.org/grpc" ) type server struct { pb.UnimplementedGreeterServer } func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { return &pb.HelloReply{Message: "Hello " + in.Name}, nil } func main() { lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterGreeterServer(s, &server{}) // Register reflection service on gRPC server. reflection.Register(s) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } log.Println("Server is running on port 50051") if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }
... http_filters: - name: envoy.filters.http.grpc_web typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb - name: envoy.filters.http.cors typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router ...
// Import the generated gRPC-Web client stubs and message classes import {GreeterClient} from './generated/helloworld_grpc_web_pb'; import {HelloRequest} from './generated/helloworld_pb'; // Create an instance of the Greeter client const client = new GreeterClient('http://localhost:8080'); // Function to send a greeting request function sayHello(name) { // Create a new request const request = new HelloRequest(); request.setName(name); // Call the sayHello method on the Greeter client client.sayHello(request, {}, (err, response) => { if (err) { console.error('Error:', err.message); document.getElementById('output').textContent = 'Error: ' + err.message; } else { console.log('Greeting:', response.getMessage()); document.getElementById('output').textContent = 'Greeting: ' + response.getMessage(); } }); } // Example usage: sending a request when the page loads document.addEventListener('DOMContentLoaded', () => { const name = 'World'; sayHello(name); });
Here is a GitHub project related to this project
https://github.com/ehsaniara/gRPC-web-example
The above is the detailed content of gRPC between Web and Server.. For more information, please follow other related articles on the PHP Chinese website!