使用 Node.js 通过 MQTT 连接到 Google Cloud IoT 时遇到问题
Trouble Connecting to Google Cloud IoT via MQTT with Node.js
我正在尝试创建一个将连接到 Google Cloud IoT Core 的 MQTT 客户端,但由于某种原因,它根本无法连接。这是我目前所拥有的
mqtt = require("mqtt")
fs = require("fs")
var jwt = require('jsonwebtoken');
const projectId = "my-project"
const deviceId = "my-device"
const registryId = "my-degistry"
const region = "us-central1"
const algorithm = "RS256"
const privateKeyFile = "./rsa_private.pem"
const mqttBridgeHostname = "mqtt.googleapis.com"
const mqttBridgePort = 8883
const messageType = "events"
//The mqttClientId is a unique string that identifies a particular device.
//For Google Cloud IoT Core, it must be the format below
const mqttClientId = `projects/${projectId}/locations/${region}/registries/${registryId}/devices/${deviceId}`
const mqttTopic = `/devices/${deviceId}/${messageType}`;
const createJwt = (projectId, privateKeyFile, algorithm) => {
// Create a JWT to authenticate this device. The device will be disconnected
// after the token expires, and will have to reconnect with a new token. The
// audience field should always be set to the GCP project id.
const token = {
iat: parseInt(Date.now() / 1000),
exp: parseInt(Date.now() / 1000) + 20 * 60, // 20 minutes
aud: projectId,
};
const privateKey = fs.readFileSync(privateKeyFile);
return jwt.sign(token, privateKey, {algorithm: algorithm});
};
//Username field is ignored in Cloud IoT Core, but it must be set to something
//Password field sends a JWT (javascript web token) to authorize the device
//mqtts protocol causes library to connecti using SSL, which is required for IoT Core
const connectionArgs = {
host: mqttBridgeHostname,
port: mqttBridgePort,
clientId: mqttClientId,
username: "unused",
password: createJwt(projectId, privateKeyFile, algorithm),
protocol: "mqtts",
secureProtocol: "TLSv1_2_method"
}
const client = mqtt.connect(connectionArgs)
client.on("connect", (connected)=>{
console.log("Attempting to connect")
if (!connected) {
console.log("Client failed to connect")
} else {
console.log("Client is connected!")
}
})
client.on("error", err => {
console.log(err)
setTimeout(( ()=> {
console.log('Terminating process')
return process.kill(process.pid);
}), 1000);
})
client.on("packetsend", (payload) => {
console.log("Payload has been sent")
return process.kill(process.pid)
})
client.on("packetreceive", packet => {
console.log("Killing")
//return process.kill(process.pid)
})
client.on("reconnect", ()=>{
console.log("Attempting a reconnect")
//return process.kill(process.pid)
})
client.on("close", ()=>{
console.log("A disconnect occurred")
// return process.kill(process.pid)
})
client.on("offline", () => {
console.log("Client is offline")
//return process.kill(process.pid)
})
我尝试连接到服务器时没有收到任何错误。换句话说,一切似乎都经过了正确的身份验证,我没有收到任何错误消息,但客户端从未连接到云,而是在无休止的循环中反复尝试重新连接(这就是为什么我包含了终止脚本的代码)。我尝试浏览 Google Cloud troubleshooting 页面,但似乎没有任何帮助。在按照指南建议使用 Cloud SDK 时,我没有收到任何类型的错误消息或有用的信息花絮。
我已经通过我的防火墙打开了端口 8883 以防万一这是问题,但它似乎不是。
我根据 Google 的一些指南和此处的 this 指南编写了此代码。我有一个注册表、项目和设备都设置了正确的 RSA 密钥。
所以我不太确定如何进行!如果有任何其他信息有帮助,请告诉我。
谢谢。
我意识到,当我在 Google 控制台上创建项目和注册表时,我实际上打错了我想要的名称(我以为是“testmqtt”,但实际上是“tesmqtt”)。
因此,如果您遇到与此类似的问题,我建议您尝试以下方法:
- 确保您拼写正确。确保项目标题、注册表标题等是正确的。这听起来很愚蠢,但这些类型的错误会发生,所以先检查一下也无妨。否则你会像我一样想太多。
- 查看此 this 页面以进行故障排除。此疑难解答页面的两个部分可能真正对您有所帮助。第一个是尝试查看您是否真的可以连接到云。您可以通过在命令行上发出
openssl s_client -connect mqtt.googleapis.com:8883
之类的命令来测试您是否能够建立连接。但是,您需要下载 openssl 才能发出该命令。您可以查看我刚刚链接的页面,了解有关测试连接的更多详细信息。您可以做的第二件事是使用 Google 的 sdk 通过 运行 gcloud 命令检查您是否有身份验证。我链接的故障排除页面也有这方面的更多详细信息。
- 这个quickstart guide也特别有用。一开始导航可能会造成混淆,但了解它是您最好的选择。
- Google 的 github repository 也有一些很好的示例,说明如何与云 IoT 核心建立 mqtt 连接。
下面评论中的 DavidC 帮助我找到了其中一些有用的链接,因此应归功于他。
除了我在评论部分提供的链接以及您发现的内容之外,一些用户使用项目编号而不是项目 ID,这导致了您遇到的类似问题。在进行故障排除时仔细检查配置中的所有内容确实值得。
如果需要复习一下认证,也可以参考这篇link。
我正在尝试创建一个将连接到 Google Cloud IoT Core 的 MQTT 客户端,但由于某种原因,它根本无法连接。这是我目前所拥有的
mqtt = require("mqtt")
fs = require("fs")
var jwt = require('jsonwebtoken');
const projectId = "my-project"
const deviceId = "my-device"
const registryId = "my-degistry"
const region = "us-central1"
const algorithm = "RS256"
const privateKeyFile = "./rsa_private.pem"
const mqttBridgeHostname = "mqtt.googleapis.com"
const mqttBridgePort = 8883
const messageType = "events"
//The mqttClientId is a unique string that identifies a particular device.
//For Google Cloud IoT Core, it must be the format below
const mqttClientId = `projects/${projectId}/locations/${region}/registries/${registryId}/devices/${deviceId}`
const mqttTopic = `/devices/${deviceId}/${messageType}`;
const createJwt = (projectId, privateKeyFile, algorithm) => {
// Create a JWT to authenticate this device. The device will be disconnected
// after the token expires, and will have to reconnect with a new token. The
// audience field should always be set to the GCP project id.
const token = {
iat: parseInt(Date.now() / 1000),
exp: parseInt(Date.now() / 1000) + 20 * 60, // 20 minutes
aud: projectId,
};
const privateKey = fs.readFileSync(privateKeyFile);
return jwt.sign(token, privateKey, {algorithm: algorithm});
};
//Username field is ignored in Cloud IoT Core, but it must be set to something
//Password field sends a JWT (javascript web token) to authorize the device
//mqtts protocol causes library to connecti using SSL, which is required for IoT Core
const connectionArgs = {
host: mqttBridgeHostname,
port: mqttBridgePort,
clientId: mqttClientId,
username: "unused",
password: createJwt(projectId, privateKeyFile, algorithm),
protocol: "mqtts",
secureProtocol: "TLSv1_2_method"
}
const client = mqtt.connect(connectionArgs)
client.on("connect", (connected)=>{
console.log("Attempting to connect")
if (!connected) {
console.log("Client failed to connect")
} else {
console.log("Client is connected!")
}
})
client.on("error", err => {
console.log(err)
setTimeout(( ()=> {
console.log('Terminating process')
return process.kill(process.pid);
}), 1000);
})
client.on("packetsend", (payload) => {
console.log("Payload has been sent")
return process.kill(process.pid)
})
client.on("packetreceive", packet => {
console.log("Killing")
//return process.kill(process.pid)
})
client.on("reconnect", ()=>{
console.log("Attempting a reconnect")
//return process.kill(process.pid)
})
client.on("close", ()=>{
console.log("A disconnect occurred")
// return process.kill(process.pid)
})
client.on("offline", () => {
console.log("Client is offline")
//return process.kill(process.pid)
})
我尝试连接到服务器时没有收到任何错误。换句话说,一切似乎都经过了正确的身份验证,我没有收到任何错误消息,但客户端从未连接到云,而是在无休止的循环中反复尝试重新连接(这就是为什么我包含了终止脚本的代码)。我尝试浏览 Google Cloud troubleshooting 页面,但似乎没有任何帮助。在按照指南建议使用 Cloud SDK 时,我没有收到任何类型的错误消息或有用的信息花絮。
我已经通过我的防火墙打开了端口 8883 以防万一这是问题,但它似乎不是。
我根据 Google 的一些指南和此处的 this 指南编写了此代码。我有一个注册表、项目和设备都设置了正确的 RSA 密钥。
所以我不太确定如何进行!如果有任何其他信息有帮助,请告诉我。
谢谢。
我意识到,当我在 Google 控制台上创建项目和注册表时,我实际上打错了我想要的名称(我以为是“testmqtt”,但实际上是“tesmqtt”)。
因此,如果您遇到与此类似的问题,我建议您尝试以下方法:
- 确保您拼写正确。确保项目标题、注册表标题等是正确的。这听起来很愚蠢,但这些类型的错误会发生,所以先检查一下也无妨。否则你会像我一样想太多。
- 查看此 this 页面以进行故障排除。此疑难解答页面的两个部分可能真正对您有所帮助。第一个是尝试查看您是否真的可以连接到云。您可以通过在命令行上发出
openssl s_client -connect mqtt.googleapis.com:8883
之类的命令来测试您是否能够建立连接。但是,您需要下载 openssl 才能发出该命令。您可以查看我刚刚链接的页面,了解有关测试连接的更多详细信息。您可以做的第二件事是使用 Google 的 sdk 通过 运行 gcloud 命令检查您是否有身份验证。我链接的故障排除页面也有这方面的更多详细信息。 - 这个quickstart guide也特别有用。一开始导航可能会造成混淆,但了解它是您最好的选择。
- Google 的 github repository 也有一些很好的示例,说明如何与云 IoT 核心建立 mqtt 连接。
下面评论中的 DavidC 帮助我找到了其中一些有用的链接,因此应归功于他。
除了我在评论部分提供的链接以及您发现的内容之外,一些用户使用项目编号而不是项目 ID,这导致了您遇到的类似问题。在进行故障排除时仔细检查配置中的所有内容确实值得。
如果需要复习一下认证,也可以参考这篇link。