I wrote a test gRPC server in Python and client on ReactJS (ES6). It's simple python gRPC server which provides authentication methods for client. Also configured EnvoyProxy for transporting HTTP requests into HTTP2. When I call gRPC method from my client I get {"code": 12, "message": "Method not found"}
.
In status codes docs this error described as not implemented method:
but I'm sure that method is implemented!
Here is some of my Python service code:
class AuthenticationServicer(glyphs_pb2_grpc.AuthenticationServicer):
def SignIn(self, request, context):
# do authentication method stuff...
return glyphs_pb2.TokenResponse(
success=True,
response=glyphs_pb2.Token(token=refresh_token.token, expired_at=str(refresh_token.expired_at)),
)
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
glyphs_pb2_grpc.add_AuthenticationServicer_to_server(AuthenticationServicer(), server)
print('Starting server. Listening on port 50051.')
server.add_insecure_port('localhost:50051')
server.start()
I tried calling the gRPC methods from python client and it works as expected:
# client.py
channel = grpc.insecure_channel('localhost:50051')
stub = glyphs_pb2_grpc.AuthenticationStub(channel)
sign_in_form = glyphs_pb2.SignInForm(email="admin@localhost", password="123456a")
sign_in_response = stub.SignIn(sign_in_form)
print("Refresh Token: ")
print(sign_in_response)
~$ python ./client.py
Refresh Token:
success: true
response {
token: "7ae52622cf556632de0a0fe115e1fc0c5adaea9c"
expired_at: "2019-11-13 13:22:56.870937"
}
My envoy YAML configuration:
admin:
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: 9090 }
filter_chains:
- filters:
- name: envoy.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: authentication_service
max_grpc_timeout: 0s
cors:
allow_origin:
- "*"
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.grpc_web
- name: envoy.cors
- name: envoy.router
clusters:
- name: authentication_service
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
hosts: [{ socket_address: { address: host.docker.internal, port_value: 50051 }}]
ReactJS client code:
const { AuthenticationClient } = require('./glyphs_grpc_web_pb');
const { SignInForm } = require('./glyphs_pb');
let client = new AuthenticationClient('http://localhost:9090/', null, null);
let form = new SignInForm();
form.setEmail('admin@localhost');
form.setPassword('123456a');
client.signIn(form, {}, (err, res) => {
if (res) {
console.log(res);
} else {
console.log(err);
}
});
I expected the output to be my token response, but the actual output was:
Package.json:
{
"name": "glyphs"
"dependencies": {
"google-protobuf": "^3.10.0",
"grpc-web": "^1.0.6",
"react": "^16.10.2",
"react-dom": "^16.10.2",
"react-scripts": "3.2.0"
}
}