events - 为什么我会从particle.publish 获得两个事件?
问题描述
我在粒子电子上使用这样的代码来报告从我的 kegerator 上的流量计到粒子云的脉冲计数:
void meterInterrupt(void) {
detachInterrupt(pin);
ticks++;
cloudPending = 1;
attachInterrupt(pin, meterInterrupt, FALLING);
}
void publishStatus() {
if (!cloudPending) {
return;
}
cloudPending = 0;
getStatus(&statusMessage);
// status message contains number of ticks since last publish
bool published = Particle.publish("Ticks", statusMessage, PRIVATE);
if (published) {
resetMeters();
lastPublish = millis();
}
}
void loop() {
if ((millis() - lastPublish) >= 1000) {
publishStatus();
}
}
当我将事件日志卷曲到终端时,我看到第一次发布的两个事件如下所示:
event: Ticks
data: {"data":"ticks:1","ttl":60,"published_at":"2018-07-03T22:35:01.008Z","coreid":"420052000351353337353037"}
event: hook-sent/Ticks
data: {"data":"","ttl":60,"published_at":"2018-07-03T22:35:01.130Z","coreid":"particle-internal"}
event: Ticks
data: {"data":"ticks:46","ttl":60,"published_at":"2018-07-03T22:35:01.193Z","coreid":"420052000351353337353037"}
event: hook-sent/Ticks
data: {"data":"","ttl":60,"published_at":"2018-07-03T22:35:01.303Z","coreid":"particle-internal"}
我不明白这怎么会发生。为什么它不只报告“ticks:47”?我错过了什么?
更新:我做了一些进一步的测试,并注意到 Particle.publish 在实际成功完成时第一次返回 false 。这是超时问题吗?这些发布之间的时间差只有大约 200 毫秒。
解决方案
好的,这至少是部分答案。
看来 Particle.publish 是异步的。它返回一个答案的承诺,最初是假的,只有当/如果动作实际完成时最终才变为真。如果我在 Particle.publish 之后和检查返回码之前等待了一段不确定的时间(比如 delay(10)),则返回值将指示发布的实际成功或失败。我的代码无法工作,因为在我重置仪表时,我等待时计算的滴答声将被删除。WITH_ACK 给了我同样的行为。
我将不得不修改我的代码,以便在长时间运行 Particle.publish 期间不会丢失任何记号。我在想每个 statusMessage 应该进入一个列表,直到它被服务器确认。
最终答案:
我修改了代码以关闭窗口,在此期间我可以接收刻度,然后在我重置计数器时将其清除。我通过将刻度捕获到一个数组中然后重置刻度计数器(仪表)来做到这一点。我正在使用一个名为 PublishQueueAsyncRK 的库(感谢 rickkas7 这个库很棒!)所以我可以解雇它并忘记它。在 github 上查看。
void publishStatus() {
unsigned int counters[NUM_METERS];
unsigned int pending;
for (int i = 0; i < NUM_METERS; i++) {
meter_t *meter = &meters[i];
counters[i] = meter->ticks;
pending += counters[i];
resetMeter(i);
}
if (pending) {
String statusReport;
for (int i = 0; i < NUM_METERS; i++) {
statusReport.concat(String::format("%i:%u|", i+1, counters[i]));
}
publishReport(statusReport);
lastPublished = millis();
}
}
void publishReport(String report) {
if (report != "") {
publishQueue.publish("PourLittleTicks", report, PRIVATE);
}
}
void loop() {
if ((millis() - lastPublished) >= PUBLISH_INTERVAL) {
publishStatus();
}
}
推荐阅读
- java - 如何使用 Apache PDFBOX 获取 PDF 大纲指向的位置
- python - 从 forexfactory.com 抓取数据
- mysql - 查询时如何保持前导/尾随空格
- winapi - 进程运行时如何在记事本中单击“菜单”?
- c - 如何在c中malloc一个表?
- python - pandas填写log数据中没有记录的日期
- sql - SAP DBTech JDBC:[257]:sql 语法错误:“:OT”附近的语法不正确
- laravel-8 - Laravel 8 SQLSTATE [42S02]:找不到基表或视图:1146 表 'dummydb.users' 不存在
- mysql - 如何在 MySQL 中显示一个表中的所有行并从另一个表中计数
- python - python数据框并用不均匀的时间序列绘制