6

I'm novice in gRPC. My program is written with ‍‍nuxtjs and is a simple login page that receives the username and password and sends it to the server using gRPC. Everything is fine when I submit a request with BloomRPC. But when using the browser, the request is not sent to the server.

My auth class is as follow:

// auth.js

export default class {
  constructor(vars) {
    this.tokenKey = vars.tokenKey
    this.proto = vars.proto
    this.client = new vars.proto.AuthenticationClient('http://127.0.0.1:50051', null, null)
  }

  async loginRequest(user) {
    const request = new this.proto.LoginRequest()
    request.setUsername(user.username.trim().toLowerCase())
    request.setPassword(user.password.trim()) 
    return await this.client.login(request, {})    
  } 
}

This error is shown when requesting to the server with the browser, whether the server is up or not.

net ERROR_CONNECTION_REFUSED
message: 'Http response at 400 or 500 level'
...

Chrome Screenshot: Chrome Screenshot

Do I have to do a specific configuration?

I just want a hint for configuring.

UPDATE:

This link says that you should use Envoy. But why do we need it? And how do I configure it?

BloomRPC screenshot:

As you can see on the right side of the image, the answer is returned correctly. bloomrpc screenshot

Saeed
  • 3,294
  • 5
  • 35
  • 52
  • Is `nuxt` actually running and listening 5005 port? Does it log something? – Anton Dec 17 '21 at 13:00
  • @Anton Nuxt is running on 3000 port and as you can see in the code, the request is sent to port 50051, where the server is listening. – Saeed Dec 17 '21 at 13:03
  • Sorry, you are right. But does gRPC server log something? – Anton Dec 17 '21 at 13:05
  • You can try `curl -v http://127.0.01:5005` to check that port actually listening. – Anton Dec 17 '21 at 13:13
  • @Anton No. Does not record any logs. This is probably because the request will not be sent to the server. – Saeed Dec 17 '21 at 13:24
  • 1
    It seems like `127.0.0.1:5005` actually not listening (also, listening `localhost` is not the same as listening `127.0.0.1`). – Anton Dec 17 '21 at 13:36
  • @Anton Exactly. Adequate configuration to connect to the server should probably be done. – Saeed Dec 17 '21 at 13:39
  • Can you show screenshots of BloomRPC, with success queries? – Anton Dec 17 '21 at 13:43
  • @Anton Thanks for continuing to help. I am sending now. – Saeed Dec 17 '21 at 13:47
  • @Saeed I found [this](https://stackoverflow.com/questions/58322610/is-there-a-possibility-to-use-grpc-in-nuxt-js). The only answer said that you have to use [grpc-web](https://github.com/grpc/grpc-web). – Giovanni Esposito Dec 17 '21 at 15:17
  • 1
    @GiovanniEsposito Thanks. I've seen this answer before. The upvoted question and answer was done by me. I'm using [grpc-web](https://github.com/grpc/grpc-web) but it looks like it has configurations that I do not know how it is. I need to read more. – Saeed Dec 17 '21 at 15:26
  • 1
    @Saeed well if you find a solution add an answer here. Could be very usefull! – Giovanni Esposito Dec 17 '21 at 15:29
  • 1
    @GiovanniEsposito The problem was that the requests did not reach the server and I needed a proxy to send the requests from the client to the server. Please see my answer. – Saeed Dec 20 '21 at 03:32
  • you can refer to [this answer](https://stackoverflow.com/a/70637968/5767110) about configuring the envoy proxy – Bhirawa Mbani Jan 09 '22 at 02:31

3 Answers3

5

Where was the problem?

The problem is that requests do not reach the server. So it does not matter if the server is up or down.

> Short Answer:

I needed a proxy to receive requests from the server. So I used ‍envoy proxy. In this way, nginx received the request from the browser and then sent it to a port (for example 5000). On the other hand, envoy listens to port 5000 and then sends the request to the server running on port 50051.

This is how I designed the tracking of a gRPC connection.

gRPC traking a request


> Long Answer:

1. Generate html/css/js file with building nuxt project. I put my website files in the root/site‍ folder.

2. envoy config: I config envoy.yaml file as follows according to what the documentions grpc-web said.

static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address: { address: 0.0.0.0, port_value: 5000 }
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              config:
                codec_type: auto
                stat_prefix: ingress_http
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: local_service
                      domains: ["*"]
                      routes:
                        - match: { prefix: "/" }
                          route:
                            cluster: sample_cluster
                            max_grpc_timeout: 0s
                      cors:
                        allow_origin_string_match:
                          - prefix: "*"
                        allow_methods: GET, PUT, DELETE, POST, OPTIONS
                        allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
                        max_age: "1728000"
                        expose_headers: grpc-status,grpc-message
                http_filters:
                  - name: envoy.filters.http.grpc_web
                  - name: envoy.filters.http.cors
                  - name: envoy.filters.http.router
  clusters:
    - name: sample_cluster
      connect_timeout: 0.25s
      type: logical_dns
      http2_protocol_options: {}
      lb_policy: round_robin
      hosts: [{ socket_address: { address: 0.0.0.0, port_value: 50051 }}]

This yaml file has two parts listeners and clusters. In the first part(listeners), we specify which port and address for listening(For example, here is address 0.0.0.0 and port 5000), and in the second part(clusters), we tell it where to send the requests(here is address 0.0.0.0 and port 50051). To use this file, we give it to Docker. So I create a Dockerfile.

# Dockerfile
FROM envoyproxy/envoy:v1.14.3
COPY ./envoy.yaml /etc/envoy/envoy.yaml
EXPOSE 5000
CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml

To build the container, I use the following commands inside Dockerfile folder and then run it.

docker build -t my-grpc-container:1.0.0 .
docker run -d --net=host my-grpc-container:1.0.0

By executing the above commands, envoy is up and listens to port 5000 and sends requests to port 500051.

For more information about envoy read this nice blog:

The role of Envoy:

Envoy translates the HTTP/1.1 calls produced by the client into HTTP/2 calls that can be handled by those services (gRPC uses HTTP/2 for transport).

3. nginx config:

I went to the /etc/nginx/sites-enabled/ folder and open default file and set the path of my website files(see section 1) as follows:

# server block
root /root/site;

Then told nginx that if a request in the url started with /rpc/, send it to 5000 port(where envoy is listening):

# server block
location /rpc/ {
    proxy_http_version 1.1;
    proxy_pass http://127.0.0.1:5000/;
    }

Then I restart nginx:

sudo systemctl restart nginx

By doing this part, nginx is up and send requests that start with /rpc/ to port 5000, where envoy is ready to receive.


In summary:

  1. The server is running on port 50051.
  2. nginx sends requests to port 5000.
  3. envoy, as an interface between the server and nginx, receives requests from port 5000 and sends them to port 50051.

Done

Saeed
  • 3,294
  • 5
  • 35
  • 52
2

According to chrome screenshot you trying to access to 5005 port in JS, but according to BloomRPC, screenshot your service listening 50051.

Anton
  • 728
  • 3
  • 8
  • Please see the new screenshot. No change. – Saeed Dec 17 '21 at 14:19
  • @Saeed I suggest you try to change port, and make sure you use same host for your app and server (i.e. both 127.0.0.1 or both localhost) – Anton Dec 17 '21 at 15:36
  • Also, is this your issue? - https://github.com/grpc/grpc-web/issues/1175 – Anton Dec 17 '21 at 15:37
  • 1
    The problem was that the requests did not reach the server. Please see my answer. I hope it is useful. – Saeed Dec 20 '21 at 03:30
0

A very well written article about strange GoAway 503 occurrences with gRPC in combination with a proxy (in that case an NGINX) helped me understand more about possible ssl hickups.

Also I learned that gRPC came up with automatic Retry Mechanisms from v.1.41.0 - I am using gRPC in the Java world here.

Simeon
  • 748
  • 1
  • 9
  • 26