grpcweb

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 12, 2024 License: MIT Imports: 19 Imported by: 0

README

Grpc-web-go-client

A grpc-web/http1.1 client for grpc in go, it is based on grpc-web protocol.

It supports only what is supported on grpc-web javascript implementation. It means that it supports only unary calls and server one side streaming calls.

Why in go ?

Grpc-web is a protocol that is already used in javascript and works over http/1.1 instead of http/2. In some environnement you can't use http/2 with this implementation you could use http/1.1 and grpc-web in javascript.

Usage

Envoy configuration

You must have an envoy configured with grpc_web filter, you can use the following configuration:

admin:
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 9901
static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 8080
      filter_chains:
        - filters:
            - name: envoy.http_connection_manager
              typed_config:
                '@type': >-
                  type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                codec_type: auto
                stat_prefix: ingress_http
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: local_service
                      domains:
                        - '*'
                      routes:
                        - match:
                            prefix: /
                          route:
                            cluster: echo_service
                http_filters:
                  - name: envoy.grpc_web
                    typed_config:
                      '@type': >-
                        type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
                  - name: envoy.filters.http.router
                    typed_config:
                      '@type': >-
                        type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
  clusters:
    - name: echo_service
      connect_timeout: 0.25s
      type: LOGICAL_DNS
      typed_extension_protocol_options:
        envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
          '@type': >-
            type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
          explicit_http_config:
            http2_protocol_options: {}
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: echo_service
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: node-server
                      port_value: 9090

Note: Cors are unnecessary if you use this library has cors are only needed for browser client, but you might want to let them to be able to use grpc-web client in browser with javascript implementation.

Example

package main

import (
	"context"
	"fmt"
	"github.com/ArthurHlt/grpc-web-go-client"
	pb "google.golang.org/grpc/examples/features/proto/echo"
)

func main() {

	conn := grpcweb.NewHttp1ClientConn(
		"localhost:8080",
		nil, // if nil it use default http client
		// those next options are optionals
		grpcweb.WithScheme("http"),         // if not set it use https
		grpcweb.WithPerRPCCredentials(nil), // if you want to use grpc auth
	)

	// you can use it like a normal grpc client conn
	// note that all metadate you write become http headers
	echoClient := pb.NewEchoClient(conn)

	resp, err := echoClient.UnaryEcho(context.Background(), &pb.EchoRequest{Message: "hello"})
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Message)

	// and streaming only in one direction works
	stream, err := echoClient.ServerStreamingEcho(context.Background(), &pb.EchoRequest{Message: "hello"})
	if err != nil {
		panic(err)
	}
	for {
		msg, err := stream.Recv()
		if err != nil {
			panic(err)
		}
		fmt.Println(msg.Message)
	}
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ParseLengthPrefixedMessage

func ParseLengthPrefixedMessage(r io.Reader, length uint32) ([]byte, error)

func ParseStatusAndTrailer

func ParseStatusAndTrailer(r io.Reader, length uint32) (*status.Status, metadata.MD, error)

Types

type Header struct {
	ContentLength uint32
	// contains filtered or unexported fields
}

func ParseResponseHeader

func ParseResponseHeader(r io.Reader) (*Header, error)

func (*Header) IsMessageHeader

func (h *Header) IsMessageHeader() bool

func (*Header) IsTrailerHeader

func (h *Header) IsTrailerHeader() bool

type Http1ClientConn

type Http1ClientConn struct {
	// contains filtered or unexported fields
}

func NewHttp1ClientConn

func NewHttp1ClientConn(target string, httpClient *http.Client, opts ...Http1ClientConnOption) *Http1ClientConn

func (*Http1ClientConn) Invoke

func (h *Http1ClientConn) Invoke(ctx context.Context, method string, args interface{}, reply interface{}, opts ...grpc.CallOption) error

func (*Http1ClientConn) NewStream

func (h *Http1ClientConn) NewStream(ctx context.Context, desc *grpc.StreamDesc, method string, opts ...grpc.CallOption) (grpc.ClientStream, error)

func (*Http1ClientConn) Target

func (h *Http1ClientConn) Target() string

type Http1ClientConnOption

type Http1ClientConnOption func(*Http1ClientConn)

func WithPerRPCCredentials

func WithPerRPCCredentials(perRpcCredentials credentials.PerRPCCredentials) Http1ClientConnOption

func WithScheme

func WithScheme(scheme string) Http1ClientConnOption

type Http1ClientStream

type Http1ClientStream struct {
	// contains filtered or unexported fields
}

func NewHttp1ClientStream

func NewHttp1ClientStream(ctx context.Context, url string, httpClient *http.Client, hdrs http.Header) *Http1ClientStream

func (*Http1ClientStream) CloseSend

func (h *Http1ClientStream) CloseSend() error

func (*Http1ClientStream) Context

func (h *Http1ClientStream) Context() context.Context

func (*Http1ClientStream) Header

func (h *Http1ClientStream) Header() (metadata.MD, error)

func (*Http1ClientStream) RecvMsg

func (h *Http1ClientStream) RecvMsg(m any) error

func (*Http1ClientStream) SendMsg

func (h *Http1ClientStream) SendMsg(m any) error

func (*Http1ClientStream) Trailer

func (h *Http1ClientStream) Trailer() metadata.MD

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL