首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >gRPC web服务器返回“找不到方法”

gRPC web服务器返回“找不到方法”
EN

Stack Overflow用户
提问于 2019-10-14 16:36:36
回答 1查看 4.5K关注 0票数 3

我用Python语言编写了一个测试gRPC服务器,并在ReactJS (ES6)上编写了客户端。它是一个简单的python gRPC服务器,它为客户端提供身份验证方法。还配置了用于将HTTP请求传输到HTTP2的EnvoyProxy。当我从客户机调用gRPC方法时,我得到了{"code": 12, "message": "Method not found"}

status codes docs中,此错误描述为未实现的方法:

但是我确信这个方法已经实现了!

下面是我的一些Python服务代码:

代码语言:javascript
运行
复制
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()

我尝试从python客户端调用gRPC方法,它按预期工作:

代码语言:javascript
运行
复制
# 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)
代码语言:javascript
运行
复制
~$ python ./client.py
Refresh Token: 
success: true
response {
  token: "7ae52622cf556632de0a0fe115e1fc0c5adaea9c"
  expired_at: "2019-11-13 13:22:56.870937"
}

我的特使YAML配置:

代码语言:javascript
运行
复制
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客户端代码:

代码语言:javascript
运行
复制
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);
    }
});

我期望输出是我的令牌响应,但实际输出是:

Package.json:

代码语言:javascript
运行
复制
{
  "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"
  }
}
EN

回答 1

Stack Overflow用户

发布于 2019-11-26 01:11:47

我遇到了类似的method not found错误,通过将客户端创建更改为

让客户端=新的AuthenticationClient('http://localhost:9090',null,null);

注:删除末尾的/

通过这种方式,调用client.signIn(...)将被定向到

http://127.0.0.1:9090/[package-if-defined-in-proto].AuthenticationServicer/SignIn

但是如果

让客户端=新的AuthenticationClient('http://localhost:9090/',null,null);

则相同的调用client.signIn(...)将被定向到

http://127.0.0.1:9090//[package-if-defined-in-proto].AuthenticationServicer/SignIn

并且双//导致找不到方法的问题。我认为grpc-web会自动并强制地将/添加到主机名中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58372922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档