node-zserial 1.0.33 → 1.0.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/zserial.js +45 -4
package/package.json
CHANGED
package/zserial.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* version: 1.0.34
|
|
5
|
+
*/
|
|
2
6
|
module.exports = function (RED) {
|
|
3
7
|
/*jshint -W082 */
|
|
4
8
|
"use strict";
|
|
@@ -352,7 +356,8 @@ module.exports = function (RED) {
|
|
|
352
356
|
err.sendPayload = err.payload;
|
|
353
357
|
err.payload = ''
|
|
354
358
|
}
|
|
355
|
-
node.
|
|
359
|
+
let serialConfig = node._msg.serialConfigs.find(sitem=>sitem.serialport==port)
|
|
360
|
+
node.errorMsg[port] = Object.assign(serialConfig,err)
|
|
356
361
|
node.send([null, node._msg, null]);
|
|
357
362
|
}
|
|
358
363
|
sendAll(done);
|
|
@@ -655,6 +660,11 @@ module.exports = function (RED) {
|
|
|
655
660
|
_retryNum: 0,
|
|
656
661
|
tout: null,
|
|
657
662
|
queue: [],
|
|
663
|
+
// ---- 防重复推进:同一次 serial 'data' 回调只允许 dequeue 一次 ----
|
|
664
|
+
_rxToken: 0,
|
|
665
|
+
_rxDequeuedToken: -1,
|
|
666
|
+
// ---- 发送序号:用于标记本次 writehead 的队首请求 ----
|
|
667
|
+
_txSeq: 0,
|
|
658
668
|
on: function (a, b) { this._emitter.on(a, b); },
|
|
659
669
|
once: function (a, b) { this._emitter.once(a, b); },
|
|
660
670
|
close: function (cb) {
|
|
@@ -700,11 +710,23 @@ module.exports = function (RED) {
|
|
|
700
710
|
writehead: function () {
|
|
701
711
|
if (!this.queue.length) { return; }
|
|
702
712
|
var qobj = this.queue[0];
|
|
713
|
+
// 标记本次发送的队首请求(用于防止 timeout 与接收回包边界竞态导致双推进)
|
|
714
|
+
qobj._done = false;
|
|
715
|
+
qobj._txId = (++obj._txSeq);
|
|
703
716
|
this.write(qobj.payload, qobj.cb);
|
|
704
717
|
var msg = qobj.msg;
|
|
705
718
|
var timeout = msg.timeout || responsetimeout;
|
|
706
719
|
this.tout = setTimeout(function () {
|
|
707
|
-
this.tout
|
|
720
|
+
// 注意:回调内 this 不是 obj,统一使用 obj.tout
|
|
721
|
+
obj.tout = null;
|
|
722
|
+
|
|
723
|
+
// 关键保护:timeout 触发时,只允许处理“仍然挂在队首的同一个 qobj”。
|
|
724
|
+
// 若队列已因正常回包 dequeue 推进,则该 timeout 已失效,直接忽略,避免连续发送/错位。
|
|
725
|
+
if (!obj.queue || !obj.queue.length) { return; }
|
|
726
|
+
if (obj.queue[0] !== qobj) { return; }
|
|
727
|
+
if (qobj._done) { return; }
|
|
728
|
+
qobj._done = true;
|
|
729
|
+
|
|
708
730
|
var msgout = obj.dequeue() || {};
|
|
709
731
|
msgout.port = id;
|
|
710
732
|
// // if we have some leftover stuff, just send it
|
|
@@ -755,16 +777,33 @@ module.exports = function (RED) {
|
|
|
755
777
|
// if we are trying to dequeue stuff from an
|
|
756
778
|
// empty queue, that's an unsolicited message
|
|
757
779
|
if (!this.queue.length) { return null; }
|
|
758
|
-
|
|
780
|
+
|
|
781
|
+
// 关键保护:同一次 serial 'data' 回调(同 _rxToken)内只允许 dequeue 一次。
|
|
782
|
+
// 防止 frame 自动解析在同一批输入字节上被多协议/多分支误判两次,导致队列被推进两次(连续发送)。
|
|
783
|
+
if (typeof this._rxToken === 'number' && this._rxDequeuedToken === this._rxToken) {
|
|
784
|
+
return null;
|
|
785
|
+
}
|
|
786
|
+
if (typeof this._rxToken === 'number') {
|
|
787
|
+
this._rxDequeuedToken = this._rxToken;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// 出队前标记 done:用于 timeout 回调校验
|
|
791
|
+
var qobj = this.queue[0];
|
|
792
|
+
if (qobj && qobj._done !== true) { qobj._done = true; }
|
|
793
|
+
|
|
794
|
+
var msg = Object.assign({}, qobj.msg);
|
|
759
795
|
msg = Object.assign(msg, {
|
|
760
796
|
request_payload: msg.payload,
|
|
761
797
|
request_msgid: msg._msgid,
|
|
762
798
|
});
|
|
763
799
|
delete msg.payload;
|
|
764
|
-
|
|
800
|
+
|
|
801
|
+
// 取消当前请求的响应超时计时器
|
|
802
|
+
if (obj.tout) {
|
|
765
803
|
clearTimeout(obj.tout);
|
|
766
804
|
obj.tout = null;
|
|
767
805
|
}
|
|
806
|
+
|
|
768
807
|
this.queue.shift();
|
|
769
808
|
this.writehead();
|
|
770
809
|
return msg;
|
|
@@ -1280,6 +1319,8 @@ module.exports = function (RED) {
|
|
|
1280
1319
|
|
|
1281
1320
|
|
|
1282
1321
|
obj.serial.on('data', function (d) {
|
|
1322
|
+
// 标记本次接收事件 token(用于防止同一次 data 回调内重复 dequeue 推进队列)
|
|
1323
|
+
obj._rxToken = (obj._rxToken || 0) + 1;
|
|
1283
1324
|
// RED.log.info("data::::" + d);
|
|
1284
1325
|
function emitData(data) {
|
|
1285
1326
|
if (active === true) {
|