title: How to connect go grpc server with dart grpc client using Envoy and Grpc_web
body: <p>I'm new to grpc_web and envoy.</p>
  <p>Please help me to setup following things,</p>
  <ol>
  <li>GRPC_Go server is running on ec2 instance as a docker container</li>
  <li>Dart web client is running on local pc</li>
  <li>Need to make grpc call request from dart web app to grpc_go server</li>
  <li>Used envoy proxy for the request forward. Envoy proxy is running as a container in same ec2 instance</li>
  </ol>
  <p>I'm getting the following error &quot;Response: null, trailers: {access-control-allow-credentials: true, access-control-allow-origin: <a href="http://127.0.0.1:9000" rel="nofollow noreferrer">http://127.0.0.1:9000</a>, vary: Origin})&quot;.</p>
  <p><strong>Grpc_Go:</strong></p>
  <pre><code>package main
  
  import (
  &quot;context&quot;
  &quot;flag&quot;
  &quot;fmt&quot;
  &quot;log&quot;
  &quot;net&quot;
  
  &quot;google.golang.org/grpc&quot;
  pb &quot;google.golang.org/grpc/examples/helloworld/helloworld&quot;
  )
  
  var (
    port = flag.Int(&quot;port&quot;, 50051, &quot;The server port&quot;)
  )
  
  // server is used to implement helloworld.GreeterServer.
  type server struct {
     pb.UnimplementedGreeterServer
  }
  
  // SayHello implements helloworld.GreeterServer
  func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
     log.Printf(&quot;Received: %v&quot;, in.GetName())
     return &amp;pb.HelloReply{Message: &quot;Hello &quot; + in.GetName()}, nil
  }
  
  func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, 
  error) 
  {
     return &amp;pb.HelloReply{Message: &quot;Hello again &quot; + in.GetName()}, nil
  }
  
  func main() {
  flag.Parse()
  lis, err := net.Listen(&quot;tcp&quot;, fmt.Sprintf(&quot;:%d&quot;, *port))
  if err != nil {
      log.Fatalf(&quot;failed to listen: %v&quot;, err)
  }
  s := grpc.NewServer()
  pb.RegisterGreeterServer(s, &amp;server{})
  log.Printf(&quot;server listening at %v&quot;, lis.Addr())
  if err := s.Serve(lis); err != nil {
      log.Fatalf(&quot;failed to serve: %v&quot;, err)
   }
  } 
  </code></pre>
  <p><strong>GRPC_dart_client:</strong></p>
  <pre><code>
  import 'package:grpc/grpc_web.dart';
  import 'package:grpc_web/app.dart';
  import 'package:grpc_web/src/generated/echo.pbgrpc.dart';
  
  void main() {
    final channel = GrpcWebClientChannel.xhr(Uri.parse('http://ec2-ip:8080'));
    final service = EchoServiceClient(channel);
    final app = EchoApp(service);
  
    final button = querySelector('#send') as ButtonElement;
    button.onClick.listen((e) async {
      final msg = querySelector('#msg') as TextInputElement;
      final value = msg.value!.trim();
      msg.value = '';
  
      if (value.isEmpty) return;
  
      if (value.indexOf(' ') &gt; 0) {
        final countStr = value.substring(0, value.indexOf(' '));
        final count = int.tryParse(countStr);
  
        if (count != null) {
          app.repeatEcho(value.substring(value.indexOf(' ') + 1), count);
        } else {
          app.echo(value);
        }
      } else {
        app.echo(value);
      }
    });
  }
  </code></pre>
  <p><strong>envoy.yaml:</strong></p>
  <pre><code>  access_log_path: /tmp/admin_access.log
    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.filters.network.http_connection_manager
          typed_config:
            &quot;@type&quot;: 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: [&quot;*&quot;]
                routes:
                - match: { prefix: &quot;/&quot; }
                  route:
                    cluster: echo_service
                    timeout: 0s
                    max_stream_duration:
                      grpc_timeout_header_max: 0s
                cors:
                  allow_origin_string_match:
                  - prefix: &quot;*&quot;
                  allow_methods: GET, PUT, DELETE, POST, OPTIONS
                  allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
                  max_age: &quot;1728000&quot;
                  expose_headers: custom-header-1,grpc-status,grpc-message
            http_filters:
            - name: envoy.filters.http.grpc_web
            - name: envoy.filters.http.cors
            - name: envoy.filters.http.router
    clusters:
    - name: echo_service
      connect_timeout: 0.25s
      type: logical_dns
      http2_protocol_options: {}
      lb_policy: round_robin
      load_assignment:
        cluster_name: cluster_0
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: app
                      port_value: 50051
  </code></pre>
  <p><strong>Grpc_go_docker_file:</strong></p>
  <pre><code>
  # Install git.
  # Git is required for fetching the dependencies.
  RUN apk update &amp;&amp; apk add --no-cache git
  WORKDIR /app
  COPY go.mod go.sum ./
  RUN go mod download
  COPY . .
  RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
  
  # Start a new stage from scratch
  FROM alpine:latest
  RUN apk --no-cache add ca-certificates
  
  WORKDIR /root/
  
  # Copy the Pre-built binary file from the previous stage. Observe we also copied the .env file
  COPY --from=builder /app/main .
  # Expose port 50051 to the outside world
  EXPOSE 50051
  
  CMD [&quot;./main&quot;] 
  </code></pre>
  <p><strong>Envoy_Docker:</strong></p>
  <pre><code>
  COPY envoy.yaml /etc/envoy/envoy.yaml
  
  CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml -l trace --log-path /tmp/envoy_info.log
  </code></pre>
  <p>I'm stuck with it more than two days, please help me. Thanks in advance</p>