云模块“@google- JavaScript /iot”似乎与这里的文档(https://googleapis.dev/nodejs/iot/latest/index.html)不太相似。
例如,文档中的函数client.sendCommandToDevice()返回类型SendCommandToDeviceResponse,而它实际上返回接口和未定义的复杂交集。我可以在模块内的命名空间嵌套中找到正确的类型,但即使这样,我也无法从结果中获得所需的数据。例如,...Response类型有一个静态函数"toJSON()“,该函数接受响应并返回JSON--但它不接受实际的响应对象,并且我找不到任何方法将实际的响应对象转换为预期的类型。
这不是唯一这样的错误。这是否可能是一种过于仓促地将旧的JavaScript API转换为TypeScript而没有检查它在TypeScript中是否真的可用的工件?是否有一些关于旧的JavaScript应用程序接口的文档可以让我查看以进行比较?
以下是代码片段(在转换之前):
// node 14.17.3, TypeScript 4.4.4, iot 2.5.1
import iot from "@google-cloud/iot";
// Yes, I did the credentials thing...
const client = new iot.v1.DeviceManagerClient();
function generateRequest(id: string, data: any) {
const formattedName = client.devicePath("myproject", "us-central1", "myregistry", id);
const binData = Buffer.from(JSON.stringify(data)).toString("base64");
return {
ok: true,
name: formattedName,
binData: binData,
};
}
async function run() {
const project = await client.getProjectId();
const parent = client.locationPath(project, 'us-central1');
const deviceId = "d99999995";
const data = { get: [ "program" ] };
const request = generateRequest(deviceId, data);
let r = await client.sendCommandToDevice(request);
// what is r here???
/* Same issue with, e.g.:
client.updateDevice();
client.modifyCloudToDeviceConfig()
*/
return {
ok: true,
result: r,
};
}
run().catch((err) => { console.error(err); });发布于 2021-10-19 20:49:10
Immediate feedback:你对评论者的回复显示了你明显的沮丧。我认为,假设人们不会花时间回答你的问题会让你感到沮丧,这是合理的。我不愿意回复,也不希望也受到惩罚,但像他们一样,我想试着帮助你……
这个库的文档看起来是正确的,但我既不是TypeScript也不是JavaScript专家。我非常熟悉GCP及其服务和编写客户端代码。
谷歌一直在改进其服务,以反映其内部对gRPC的广泛使用。在我看来,这种转向更多gRPC原生服务的趋势正在渗入到它的SDK中(即,protobuf消息的优势),我发现这一点令人困惑,特别是因为我还没有看到它的完整解释。
在@google-cloud/iot的情况下,这些方法确实引用了协议消息。因此,您的sendCommandToDevice方法有一个签名,它接受一个SendCommandToDeviceRequest并返回一个承诺的SendCommandToDeviceResponse。
正如我所说的,我不熟悉TypeScript,但是在JavaScript中,我想知道您是否必须使用SendCommandToDeviceRequest构造函数来创建请求:
function generateRequest(id, data) {
const formattedName = client.devicePath("myproject", "us-central1", "myregistry", id);
const binaryData = Buffer.from(JSON.stringify(data)).toString("base64");
return {
name: formattedName,
binaryData: binaryData,
};
}
const rqst = new iot.protos.google.cloud.iot.v1.SendCommandToDeviceRequest(
generateRequest(deviceId, data)
);备注:
binaryDataisbinData
然后,因为它是await的,所以我认为您的响应类型将是SendCommandToDeviceResponse
const resp = await client.sendCommandToDevice(rqst);@Ash_max在评论中引用了此类型。尽管构造函数列在页面的顶部,但页面下方是toJSON()。因此,您应该能够:
console.log(`response: ${resp.toJSON()}`);也许是
JSON.stringify(resp.toJSON())
今天我没有时间尝试,但明天我会试着重现你的经历,并更新这个帖子。
更新
我创建了一个GCP项目、注册表和设备。
我运行了上面概述的Node.JS代码,返回类型令人困惑;我得到了一个由3个对象组成的数组,其中第一个看起来是一个proto,但不支持toJSON,我也不能获取它的toString()。
因此,我查看了APIs Explorer,根据它的sendCommandToDevice (我认为它是确定的),成功时响应主体将是空的。
困惑的是,我写了一个等价的Golang程序:
package main
import (
"context"
b64 "encoding/base64"
"fmt"
"log"
"os"
"google.golang.org/api/cloudiot/v1"
)
func main() {
ctx := context.Background()
client, err := cloudiot.NewService(ctx)
if err != nil {
log.Fatal(err)
}
rqst := &cloudiot.SendCommandToDeviceRequest{
BinaryData: b64.StdEncoding.EncodeToString([]byte("Hello Freddie")),
}
name := fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s",
os.Getenv("PROJECT"),
os.Getenv("REGION"),
os.Getenv("REGISTRY"),
os.Getenv("DEVICE"),
)
devices := client.Projects.Locations.Registries.Devices
resp, err := devices.SendCommandToDevice(name, rqst).Do()
if err != nil {
log.Fatal(err)
}
log.Printf("%+v", resp)
}并且它的resp绝对是SendCommandToDeviceResponse类型,并且包含ServerResponse,其中包含HTTPStatusCode
&{
ServerResponse:{
HTTPStatusCode:200
Header:map[
Cache-Control:[private]
Content-Type:[application/json; charset=UTF-8]
Date:[Wed, 20 Oct 2021 00:20:00 GMT]
Server:[ESF] Vary:[Origin X-Origin Referer]
X-Content-Type-Options:[nosniff]
X-Frame-Options:[SAMEORIGIN]
X-Xss-Protection:[0]
]
}
}因此,JavaScript (Node.JS|TypeScript)代码应该以某种方式(!)也可以从SendCommandToDeviceResponse中抓取ServerResponse。
文档似乎是正确的。
https://stackoverflow.com/questions/69564906
复制相似问题