You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node-RED中node-red-contrib-grpc与原生gRPC客户端枚举输出不一致问题

gRPC枚举类型转换异常问题

我遇到一个奇怪的gRPC实现问题:有一个持续流式传输简单消息的gRPC服务器,我在Node-RED中通过两种方式连接它:

  • 使用node-red-contrib-grpc的grpc-call节点
  • 使用加载@grpc/grpc-js和@grpc/proto-loader包的函数节点(这两个包与node-red-contrib-grpc所用包完全相同)

两种方式均能正常连接并返回数据,唯一差异是前者将枚举正确转换为String类型,而函数节点仍保留为Integer类型。我已确认两者使用的.proto文件完全一致。

node-red-contrib-grpc在服务器配置中使用的proto-loader选项如下:

let proto = grpc.loadPackageDefinition(
                protoLoader.loadSync(fileName, {
                    keepCase: true,
                    longs: String,
                    enums: String,
                    defaults: true,
                    oneofs: true
                })
            );

我的函数节点完整代码:

const PROTO_PATH = '/data/userfiles/combined.proto';
const credentials = grpc.credentials.createInsecure();

let numberOfMessages = 1 // 0 to let the server close the stream (infinite messages)

let proto = grpc.loadPackageDefinition(
    protoLoader.loadSync(PROTO_PATH, {
        keepCase: true,
        longs: String,
        enums: String,
        defaults: true,
        oneofs: true
    })
);
// node.warn(proto)

let metadata = new grpc.Metadata();
if (typeof msg.metadata === 'object'){
    Object.keys(msg.metadata).forEach(key => {
        try {
            metadata.add(key, JSON.stringify(msg.metadata[key]));
        } catch (e){
            node.error(e);
        }
    });
}

let client = new proto.plan.v2.PlanService('localhost:8002',
    credentials);

let dataReceived = 0
if (proto.plan.v2.PlanService.service['Subscribe'].responseStream) {
    let call = client.Subscribe({}, metadata);
    call.on("data", function (data) {
        msg.payload = data;
        node.send(msg);
        dataReceived += 1
        if (numberOfMessages > 0 && dataReceived === numberOfMessages) {
            call.cancel();
            node.done();
        }
    });

    call.on('status', function (status) {
        msg.grpc_msg = JSON.stringify(status)
        node.send(msg);
    });

    call.on('end', function () {
        msg.grpc_msg = "client connection ended";
        node.send(msg);
    });

    call.on("error",function (error) {
        msg.error = error;
        node.send(msg);
    });

} else {
    client.Subscribe({}, metadata, function(error, data) {
        msg.payload = data;
        msg.error = error;
        node.send(msg);
        node.done();
    })
}

输出差异

node-red-contrib-grpc输出

...
{
 links: [
    { 
     link_id: "",
     type: "LINK_GROUPED_TO",
     to_id: "4dc1ab6c-5a9d-4221-83a7-986144c1cc27"
    }
  ]
}
...

函数节点输出

...
{
 links: [
    { 
     link_id: "",
     type: 5,
     to_id: "4dc1ab6c-5a9d-4221-83a7-986144c1cc27"
    }
  ]
}
...

内容的提问来源于stack exchange,提问作者sosukeinu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 12:15:30