0

我已经配置了一个谷歌云物联网项目,并从谷歌云物联网控制台主题页面成功发布了“Hello, World”消息。我也可以查看收到的消息。

现在,在尝试使用 Hivemq M2Mqtt nuget 包在 Visual Studio C# 上运行以下代码时,消息未发布。我观察到以下情况:

  1. Publisher.Connect 返回的代码值为 5
  2. Publisher.Publish 返回的 msgID 值为 1
  3. publisher.MqttMsgPublished 事件未触发

我犯了什么错误?

谢谢。

    public static int ConvertToSeconds(DateTime date)
    {
        DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
        TimeSpan diff = date.ToUniversalTime() - origin;
        return Convert.ToInt32(diff.TotalSeconds);
    }

    private bool createClients()
    {
        try
        {
            publisher = new MqttClient("mqtt.googleapis.com", 8883, true,
                new System.Security.Cryptography.X509Certificates.X509Certificate(Properties.Resources.roots),
                null, MqttSslProtocols.TLSv1_2);
            publisher.ProtocolVersion = MqttProtocolVersion.Version_3_1_1;
            string Gu_id = "projects/testproject-279402/locations/asia-east1/registries/My_Registry/devices/My_Device";
            var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Properties.Resources.rsa_private);
            var credentials = new Microsoft.IdentityModel.Tokens.SigningCredentials
                (securityKey, Microsoft.IdentityModel.Tokens.SecurityAlgorithms.HmacSha256);
            var header = new System.IdentityModel.Tokens.Jwt.JwtHeader(credentials);

            var validfrom = DateTime.UtcNow.Subtract(TimeSpan.FromSeconds(30));
            var validTo = DateTime.UtcNow.Add(TimeSpan.FromMinutes(600));
            var payload = new System.IdentityModel.Tokens.Jwt.JwtPayload {
                {"aud", "googleapis.com/projects/testproject-279402/topics/Temperature"},
                {"iat", ConvertToSeconds(validfrom)},
                {"exp", ConvertToSeconds(validTo) }
            };
            var secToken = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(header, payload);
            var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
            var tokenString = handler.WriteToken(secToken);
            byte code = publisher.Connect(Gu_id, null, tokenString,
                                       false, // will retain flag
                                        MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, // will QoS
                                       true, // will flag
                                       "/will_topic", // will topic
                                       "will_message", // will message
                                       true,
                                       60);
            publisher.MqttMsgPublished += publisher_MqttMsgPublished;

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
            return false;
        }
        return true;
    }

    private bool publish(ref string ers)
    {
        try
        {
            ushort msgId = publisher.Publish("/projects/testproject-279402/topics/Temperature",
                              Encoding.UTF8.GetBytes("123"),
                              MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE,
                              false); // retained
        }
        catch (Exception ex)
        {
            ers = "Exception occurred in publish.";
            return false;
        }
        ers = "";
        return true;
    }
4

1 回答 1

0

JWT 中的“aud”键应该只是项目 ID,而不是完整的 Pub/Sub 主题。我不知道它是否足够聪明,可以阅读所需的内容,但请先尝试一下。

另外,如果我没看错,您似乎是在尝试直接发布到 Pub/Sub 主题?如果您使用 IoT Core,您应该发布到 MQTT 主题 (/devices/[device_id]/events) 而不是 Pub/Sub 主题。如果您尝试将 MQTT 直接发布到 Pub/Sub,那就另当别论了……但听起来您仍然想使用 IoT Core?

于 2020-06-09T06:41:00.483 回答