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'
...
Do I have to do a specific configuration?
I just want a hint for configuring.
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.
The problem is that requests do not reach the server. So it does not matter if the server is up or down.
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.
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, whereenvoy
is ready to receive.
In summary:
nginx
sends requests to port 5000.envoy
, as an interface between the server
and nginx
, receives
requests from port 5000 and sends them to port 50051.Done