当前位置: 首页 > 知识库问答 >
问题:

gRPC Node Js客户端:“找不到方法”

荆煌
2023-03-14

我有一个用python实现的gRPC服务器,我正在从NodeJS调用RPC,但它给出了一个错误“找不到方法”。当我使用python客户端调用时,请求成功。

syntax = "proto3";

package csv;

service Stream {
  rpc csvToObject(CSVDataRequest) returns (stream CSVDataResponse) {};
  rpc sayHello(HelloRequest) returns (HelloReply);
}

message CSVDataRequest{
  string url = 1;
  enum Protocol {
    HTTP = 0;
    HTTPS = 1;
    FTP = 2;
    SFTP = 3;

}

  Protocol protocol = 2;
}

message CSVDataResponse{
  repeated string row = 1;
}

message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}
var PROTO_PATH = '../stream_csv.proto';

var grpc = require('grpc');
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
    PROTO_PATH,
    {keepCase: true,
     longs: String,
     enums: String,
     defaults: true,
     oneofs: true
    });
var proto = grpc.loadPackageDefinition(packageDefinition).csv;

function main() {
  var client = new proto.Stream('localhost:5000',
                                       grpc.credentials.createInsecure());
  var user;
  if (process.argv.length >= 3) {
    user = process.argv[2];
  } else {
    user = 'world';
  }
  console.log(user);
  client.sayHello({name: user}, function(err, response) {
    console.log(err);
  });
}

main();

导入grpc import stream\u csv\u pb2 import urllib。来自urllib的请求。从并发导入期货导入HTTPError时出错,URLError

class DataService:

    def csv_to_object(self, request, context):
        url = request.url
        protocol = stream_csv_pb2.CSVDataRequest.Protocol.Name(
            request.protocol)
        fetch_url = protocol.lower() + "://"+url

        try:
            with urllib.request.urlopen(fetch_url) as data:
                for line in data:
                    decoded_line = line.decode()
                    val = decoded_line.split(',')
                    print(val)
                    print("Data send")
                    yield stream_csv_pb2.CSVDataResponse(row=val)

            print("Sending finished!")

        except URLError as e:
            context.abort(grpc.StatusCode.UNKNOWN,
                        'Randomly injected failure.')
            # return stream_csv_pb2.CSVDataResponse(row=[], error=e.reason)

    def SayHello(self, request, context):
        name = request.name
        print(name)
        return stream_csv_pb2.HelloReply(message='Hello %s' % (name))

def add_DataServicer_to_server(servicer, server):
    rpc_method_handlers = {
        'CSVToObject': grpc.unary_stream_rpc_method_handler(
            servicer.csv_to_object,
            request_deserializer=stream_csv_pb2.CSVDataRequest.FromString,
            response_serializer=stream_csv_pb2.CSVDataResponse.SerializeToString,
        ),
        'SayHello': grpc.unary_unary_rpc_method_handler(
            servicer.SayHello,
            request_deserializer=stream_csv_pb2.HelloRequest.FromString,
            response_serializer=stream_csv_pb2.HelloReply.SerializeToString,
        )
    }
    generic_handler = grpc.method_handlers_generic_handler(
        'stream_csv.Stream', rpc_method_handlers)
    server.add_generic_rpc_handlers((generic_handler,))


def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    add_DataServicer_to_server(DataService(), server)
    server.add_insecure_port('[::]:5000')
    server.start()
    server.wait_for_termination()


if __name__ == '__main__':
    serve()
Error: 12 UNIMPLEMENTED: Method not found!
    at Object.exports.createStatusError (/home/shantam/Documents/grepsr/client/node_modules/grpc/src/common.js:91:15)
    at Object.onReceiveStatus (/home/shantam/Documents/grepsr/client/node_modules/grpc/src/client_interceptors.js:1209:28)
    at InterceptingListener._callNext (/home/shantam/Documents/grepsr/client/node_modules/grpc/src/client_interceptors.js:568:42)
    at InterceptingListener.onReceiveStatus (/home/shantam/Documents/grepsr/client/node_modules/grpc/src/client_interceptors.js:618:8)
    at callback (/home/shantam/Documents/grepsr/client/node_modules/grpc/src/client_interceptors.js:847:24) {
  code: 12,
  metadata: Metadata { _internal_repr: {}, flags: 0 },
  details: 'Method not found!'
}

共有1个答案

左丘耀
2023-03-14

我编写了Python(和Golang)服务器实现的更简单变体。

两者都可以用于节点。JS客户端原样。

我认为您的问题可能很简单,只需为rpc命名(而不是命名)。

from concurrent import futures
import logging

import grpc

import stream_csv_pb2
import stream_csv_pb2_grpc


class Stream(stream_csv_pb2_grpc.StreamServicer):

    def sayHello(self, request, context):
        logging.info("[sayHello]")
        return stream_csv_pb2.HelloReply(message='Hello, %s!' % request.name)


def serve():
    logging.info("[serve]")
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    stream_csv_pb2_grpc.add_StreamServicer_to_server(Stream(), server)
    server.add_insecure_port('[::]:50051')
    server.start()
    server.wait_for_termination()


if __name__ == '__main__':
    logging.basicConfig()
    serve()

以及:

node client.js
Greeting: Hello, Freddie!
null

按照惯例(!),gRPC遵循CamelCasingservice、rpc和消息名称的Pro bufs样式指南,并在其他地方使用下划线(请参阅样式指南)。当协议编译时,结果并不总是完全匹配(例如,Python的CamelCeld函数,而不是用下划线进行低删减)。

按照惯例,您的原型是:

service Stream {
  rpc CsvToObject(CSVDataRequest) returns (stream CSVDataResponse) {};
  rpc SayHello(HelloRequest) returns (HelloReply);
}

...然后Python生成的函数也是(!)SayHello

 类似资料:
  • 我有一个老项目,这是试图从谷歌分析检索数据。 它不起作用,所以我试图找出问题所在。 找到了在服务器端使用分析的示例代码。 它与我的测试帐户的秘密文件一起工作。但是它对一个老项目的秘密文件不起作用。我收到以下错误: 有什么问题?机密文件已过期?如果是,我可以在没有访问谷歌帐户的情况下收到另一个吗?

  • URI 方法 URI() string 返回当前客户端使用的服务器地址。 SetURI 方法 SetURI(uri string) 设置当前客户端使用的服务器地址。如果你想要设置多个服务器地址,请使用 SetURIList 方法代替该方法。 URIList 方法 URIList() []string 返回当前客户端可使用的服务器地址列表。 SetURIList 方法 SetURIList(uriL

  • 我使用CAS和Spnego支持,KDC是192.168.1.244,我的领域是示例。COM我测试了我的本地Windows域环境,我可以从示例中获得票证。com我用“kinit”命令测试它,但在CAS spnego环境中,在Kerberos数据库中找不到异常客户端,我已经在C:\windows\krb5.ini中创建了它,内容如下 krb5.ini 异常报告如下: 但为什么在kerberos数据库中

  • 我们试图用任何google帐户登录我的worklight混合移动示例应用程序。 下面是创建google gmail API和创建OAuth 2.0客户端ID的屏幕截图步骤 错误日志中没有错误,只有这里引用的页面加载错误。我们得到这样的屏幕截图错误

  •  说明 判断是否安装游戏 $.f2eMb.app.checkInstall(pckName) 下载游戏 $.f2eMb.app.dwGame(gameId) 根据地址下载游戏 $.f2eMb.app.dwGameByUrl(url,gameId,pckName) 进入游戏 $.f2eMb.app.strGame(pckName) 登录 $.f2eMb.app.login() 复制 $.f2eMb

  • 在设置passport之后,我配置并创建了一个控制器,用于管理注册登录和对资源的访问,以满足一般外部post请求。我不需要特定的客户。但当我尝试在注册或登录中创建令牌时: 错误是: 运行时异常:未找到个人访问客户端。请创建一个。在文件C:\xampp7中。1\htdocs\passport\vendor\laravel\passport\src\ClientRepository。php第94行堆栈