【问题标题】:How to solve: premature close at onclosenexttick in Node.js Server?如何解决:Node.js 服务器的 onclosenexttick 过早关闭?
【发布时间】:2020-04-28 18:50:32
【问题描述】:

如何解决这个错误,我正在使用 AWS IoT 运行我的 Node.js,然后它有时会显示这个错误:

      throw er; // Unhandled 'error' event
      ^

Error: How  (/home/ec2-user/work/nodejs_27_01/node_modules/end-of-stream/index.js:54:                                                                                                     86)
    at processTicksAndRejections (internal/process/task_queues.js:79:11)
Emitted 'error' event on DeviceClient instance at:
    at MqttClient.<anonymous> (/home/ec2-user/work/nodejs_27_01/node_modules/aws-iot-device-sdk/                                                                                                     device/index.js:772:15)
    at MqttClient.emit (events.js:333:22)
    at MqttClient.EventEmitter.emit (domain.js:485:12)
    at TLSSocket.f (/home/ec2-user/work/nodejs_27_01/node_modules/once/once.js:25:25)
    at onclosenexttick (/home/ec2-user/work/nodejs_27_01/node_modules/end-of-stream/index.js:54:                                                                                                     73)

【问题讨论】:

  • 能贴出sn-p代码吗?这将有助于我们为您提供指导。
  • 库有错误listner device.on('error', callback),可以考虑使用。
  • @SandeepPatel 来自我的错误监听器 device.on('error', callback) 它带来了这个错误:**premature close at onclosenexttick **

标签: node.js amazon-web-services aws-iot


【解决方案1】:

这可能有多种原因:

具有相同 ClientId 的多个连接

clientId 一次只能用于一个连接。如果您在建立另一个连接的同时使用相同的 clientId 进行连接,则旧连接将被丢弃(这会导致过早关闭错误)并建立新连接。

客户端正在使用已在使用的客户端 ID。在这种情况下,已经连接的客户端将被断开 [...]。 (Source)

权限

如果设备(来自aws-iot-device-sdk-js 的 mqtt.Client)没有正确的权限来连接和/或发布/订阅/接收给定主题的消息,则可能会发生此错误。

查看更多文档:https://docs.aws.amazon.com/iot/latest/developerguide/pub-sub-policy.html

政策应如下所示(示例显示 Cloudformation Iot Policy 资源):

MyIotThingsPolicy:
  Type: AWS::IoT::Policy
  Properties:
    PolicyDocument:
      Version: "2012-10-17"
      Statement:
        - Action: iot:Connect
          Effect: Allow
          Resource: !Join [ "", [!Sub "arn:aws:iot:${AWS::Region}:${AWS::AccountId}:client/",
                                 "${iot:ClientId}"] ]
        - Action: iot:Receive
          Effect: Allow
          Resource: !Join [ "", [!Sub "arn:aws:iot:${AWS::Region}:${AWS::AccountId}:topic/",
                                "${iot:ClientId}/eg/your/broadcast/topic"] ]
        - Action: iot:Subscribe
          Effect: Allow
          Resource: !Join [ "", [!Sub "arn:aws:iot:${AWS::Region}:${AWS::AccountId}:topicfilter/",
                                 "${iot:ClientId}/eg/your/broadcast/topic"] ]
        - Action: iot:Publish
          Effect: Allow
          Resource: !Join [ "", [!Sub "arn:aws:iot:${AWS::Region}:${AWS::AccountId}:topic/",
                                 "${iot:ClientId}/eg/your/publish/topic"] ]

!Join 是必要的,因为 Cloudformation 会尝试解析 ${iot:ClientId},这是一个运行时值,在部署期间是未知的。

疑难解答

【讨论】:

  • 感谢 Simons,我会看看我能解决这个问题,因为我有一个单一事物的证书,我已经构建它能够读取其他事物的影子和更新,现在我必须找到一种方法来拥有一个可以完成工作的对象。订阅话题,听话题
  • 大家好,非常感谢您的帮助。原来是我的clientId的问题。我对多个设备、我的本地设备、我的同事、EC2 实例使用单个 clientId。所以冲突就在那里。为了解决这个问题,我必须在我的 IoT 策略中添加多个 clientId。现在我不再有这样的问题了。
【解决方案2】:

我可以使用没有任何限制的策略解决这个问题,它对我有用。因为我不想限制连接的客户端和订阅或发布的主题,所以我使用了这个策略

"Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:*",
      "Resource": "*"
    }
  ] 

【讨论】:

  • 非常感谢,这也可以,但我想它只会给您带来安全风险,允许所有客户端连接而不是您定义的客户端
【解决方案3】:

在测试时,我附加了具有完整 "Action": "iot:*" 权限的策略,但错过了激活新创建的证书。请转到物联网核心服务Secure --&gt; Certificates 并验证附加到&lt;Thing&gt; 的证书是否已激活,如果您在确认与端点的连接后收到error Error: premature close

telnet &lt;your-iot-endpoint&gt; 8883.

有关上述指定页面上每个证书的可用选项,请参见附图。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多