通过带有Node.js的MQTT连接到Google云IoT时出现问题

通过带有Node.js的MQTT连接到Google云IoT时出现问题,node.js,mqtt,iot,google-cloud-iot,Node.js,Mqtt,Iot,Google Cloud Iot,我正在尝试创建一个MQTT客户端,该客户端将连接到Google Cloud IoT核心,但由于某些原因,它根本无法连接。这是我到目前为止所拥有的 mqtt = require("mqtt") fs = require("fs") var jwt = require('jsonwebtoken'); const projectId = "my-project" const deviceId = "my-device&quo

我正在尝试创建一个MQTT客户端,该客户端将连接到Google Cloud IoT核心,但由于某些原因,它根本无法连接。这是我到目前为止所拥有的

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)
})
当我尝试连接到服务器时,没有收到任何错误。换句话说,一切似乎都在正确地进行身份验证,我没有收到任何错误消息,但客户端从未连接到云,而是在一个无休止的循环中反复尝试重新连接(这就是为什么我包含了终止脚本的代码)。我试着浏览谷歌云页面,但似乎没有任何帮助。当我像指南建议的那样使用CloudSDK时,我没有收到任何类型的错误消息或有用的花边信息

我已经通过防火墙打开了8883端口,以防万一这是个问题,但似乎不是

我根据谷歌的一些指南和这里的指南编写了这段代码。我有一个注册表、项目和设备,所有这些都是用正确的RSA密钥设置的

所以我真的不知道如何继续!如果有任何有帮助的其他信息,请告诉我


谢谢。

我意识到,当我在谷歌控制台上创建项目和注册表时,我实际上输入了我想要的名称(我以为它是“testmqtt”,但实际上是“tesmqtt”)

因此,如果您遇到类似的问题,我建议您尝试以下方法:

  • 确保你的单词拼写正确。确保项目标题正确,注册表标题正确,等等。这听起来很愚蠢,但这些类型的错误都会发生,所以先检查它们不会有什么坏处。否则你会像我一样过度思考
  • 查看此页面了解疑难解答。本疑难解答页面中有两个部分可能会真正帮助您。第一个是尝试看看你是否真的可以连接到云。您可以通过在命令行上发出类似于
    openssl s_client-connect mqtt.googleapis.com:8883
    的命令来测试是否能够建立连接。但是,您需要下载openssl才能发出该命令。您可以查看我刚才链接的页面,了解有关测试连接的更多详细信息。您可以做的第二件事是通过使用Google的sdk运行gcloud命令来检查您是否具有身份验证。我链接的疑难解答页面也有这方面的更多细节
  • 这也特别有帮助。一开始导航可能会让人困惑,但理解它将是你最好的选择
  • 谷歌也有一些很好的例子来说明如何与云物联网核心建立mqtt连接

DavidC在下面的评论中帮助我找到了一些有用的链接,因此应该归功于他。

除了我在评论部分提供的链接之外,还有一些用户使用项目编号而不是项目ID,这会导致您遇到类似的问题。在进行故障排除时,仔细检查配置中的所有内容是值得的


如果您需要更新有关身份验证的信息,也可以参考此信息。

由于您提到没有错误消息,因此我们很难诊断此问题。您是否可以遵循此示例教程[1],并使用此Github链接[2](用于node.js代码)模拟简单的物联网快速启动来隔离问题?[1] -[2]-使用我之前评论中提到的链接,我成功地实现了它。我将尝试一下示例教程,并报告我的结果!因此,我在您链接的github上下载了package.json和cloudiot_mqtt_example_nodejs.js文件,然后在安装依赖项后使用脚本运行以下命令:node cloudiot_mqtt_example_nodejs.js--registryId=mqttDeviceDemo/--registryId=my registry/--deviceId=my device privateKeyFile=./rsa_private.pem/--algorithm=RS256脚本所做的只是重复打印“close”。如果我正确使用了该示例,那么这可能是身份验证的问题?身份验证可能是其中的一个因素,但由于您提到日志中没有错误消息,所以很难说。尝试连接时出现身份验证问题,至少会给您一个错误。虽然没有可用的日志,但我建议您查看提供的Github链接中的示例代码,并将其与您的代码进行比较。另一种方法是从示例代码开始,并将其转换为您最初在本文中遵循的内容。