tmc.js 0.3.6 → 0.3.8
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/README.md +28 -5
- package/lib/consumer.js +8 -2
- package/lib/message.js +21 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,14 +30,14 @@ new Tmc('your_app_key', 'your_app_secret')
|
|
|
30
30
|
|
|
31
31
|
## API
|
|
32
32
|
|
|
33
|
-
**`new Tmc(appKey: string, appSecret: BinaryLike, groupName?: string |
|
|
33
|
+
**`new Tmc(appKey: string, appSecret: BinaryLike, groupName?: string | ConsumerOptions, options?: ConsumerOptions)`**
|
|
34
34
|
|
|
35
35
|
| 参数 | 类型 | 说明 |
|
|
36
36
|
| --- | --- | --- |
|
|
37
37
|
| appKey | `string` | 应用ID |
|
|
38
38
|
| appSecret | `BinaryLike` | 应用密钥 |
|
|
39
|
-
| groupName | `string` | 消息分组(可选,默认`default`) |
|
|
40
|
-
| options | `
|
|
39
|
+
| groupName | `string \| ConsumerOptions` | 消息分组(可选,默认`default`) |
|
|
40
|
+
| options | `ConsumerOptions` | 消费端配置参数(可选) |
|
|
41
41
|
| options.pullRequestInterval | `number` | 定时发送`pullRequest`请求时间间隔(默认`5000`毫秒) |
|
|
42
42
|
| options.onErrorReconnection | `number` | 当消费端出现错误,重试连接间隔(默认`15000`毫秒) |
|
|
43
43
|
| options.onCloseReconnection | `number` | 当消费端断开连接,重试连接间隔(默认`3000`毫秒) |
|
|
@@ -75,11 +75,11 @@ new Tmc('your_app_key', 'your_app_secret')
|
|
|
75
75
|
|
|
76
76
|
**`tmc.send(msg: Message, options?: { mask?: true, binary?: true }, cb?: (err: Error) => void) => void`**
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
自`v0.3.4`起,当自动应答确认消息无法满足需求的时候,比如消息处理失败,需要`Publisher`再次重推消息,在实例初始化时置`options.autoReplyConfirmation=false`,则在消息处理函数内,可以通过 `this.send()` 函数回复`确认`或者`失败`消息。例如:
|
|
79
79
|
|
|
80
80
|
```js
|
|
81
81
|
new Tmc('your_app_key', 'your_app_secret', { autoReplyConfirmation: false })
|
|
82
|
-
.taobao_trade_TradeDelayConfirmPay(function
|
|
82
|
+
.taobao_trade_TradeDelayConfirmPay(function needDoubleRetriesThenConfirm(msg) {
|
|
83
83
|
if (msg instanceof Message && msg.content?.retried === 0) {
|
|
84
84
|
this.send(
|
|
85
85
|
new Message(MessageType.SENDACK, MessageKind.Failed)
|
|
@@ -91,6 +91,29 @@ new Tmc('your_app_key', 'your_app_secret', { autoReplyConfirmation: false })
|
|
|
91
91
|
.connect();
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
也可以使用此方法发送`To淘宝`消息。在`>=v0.3.4 && <v0.3.7`版本期间,需要自主对`$.content.content`数据做`JSON`字符串化(**特别注意:** 原生`JSON`对`BigInt`类型无法处理)。自`v0.3.7`起,可直接对`$.content.content`以原生`object`类型描述,`SDK`会将此对象转化成`JSON`字符串。例如:
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
/** @see https://open.taobao.com/tmc.htm?docId=732&docType=9 */
|
|
98
|
+
.send(
|
|
99
|
+
new Message(MessageType.SEND, MessageKind.Data)
|
|
100
|
+
.with(MessageFields.TOPIC, 'taobao_fuwu_ElectronicInvoice')
|
|
101
|
+
.with(MessageFields.CONTENT, {
|
|
102
|
+
id: 12345678901234567n, // 支持 BigInt 类型
|
|
103
|
+
tid: 12345678901234567n,
|
|
104
|
+
oid: 12345678901234567n,
|
|
105
|
+
invoice_file: 12345678901234567n,
|
|
106
|
+
e_invoice_no: '12342243435466',
|
|
107
|
+
invoice_time: '2015-04-10 10:33:49', // 时区 +08:00
|
|
108
|
+
invoice_no: '123456',
|
|
109
|
+
invoice_code: '123456',
|
|
110
|
+
amount: '100.00',
|
|
111
|
+
})
|
|
112
|
+
// >=v0.3.4 && <v0.3.7 写法
|
|
113
|
+
// .with(MessageFields.CONTENT, '{"tid":12345678901234567,"amount":"100.00"}')
|
|
114
|
+
)
|
|
115
|
+
```
|
|
116
|
+
|
|
94
117
|
<details><summary>可选设置的 NODE_DEBUG=< label > 环境变量</summary>
|
|
95
118
|
|
|
96
119
|
| label | 说明 |
|
package/lib/consumer.js
CHANGED
|
@@ -99,10 +99,16 @@ class TaoMessageConsumer extends EventEmitter {
|
|
|
99
99
|
* @param {object|Function} [options] - The options
|
|
100
100
|
* @param {Function} [cb] - The Callback
|
|
101
101
|
* @returns {void}
|
|
102
|
-
* @since v0.3.4
|
|
102
|
+
* @since v0.3.4 Exposed for `send(new Message(SENDACK, Failed))` scene
|
|
103
|
+
* @since v0.3.7 The `data.content.content` can be a plain `object` now
|
|
103
104
|
*/
|
|
104
105
|
send(data, options = { mask: true, binary: true }, cb = undefined) {
|
|
105
|
-
if (data instanceof Message) {
|
|
106
|
+
if (data instanceof Message) {
|
|
107
|
+
if (typeof data[CONTENT][CONTENT] === 'object' && data[CONTENT][CONTENT] !== null) {
|
|
108
|
+
Reflect.set(data[CONTENT], CONTENT, stringify(data[CONTENT][CONTENT]));
|
|
109
|
+
}
|
|
110
|
+
this[kWebSocket]?.send(data.with(TOKEN, this[kToken]).buffer, options, cb);
|
|
111
|
+
}
|
|
106
112
|
}
|
|
107
113
|
|
|
108
114
|
onopen() {
|
package/lib/message.js
CHANGED
|
@@ -56,29 +56,16 @@ class Message {
|
|
|
56
56
|
|
|
57
57
|
const utf8 = 'utf8';
|
|
58
58
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
const writeInt8 = 'writeInt8';
|
|
62
|
-
|
|
63
|
-
const writeInt16LE = 'writeInt16LE';
|
|
64
|
-
|
|
65
|
-
const writeInt32LE = 'writeInt32LE';
|
|
66
|
-
|
|
67
|
-
const writeBigInt64LE = 'writeBigInt64LE';
|
|
59
|
+
const kOffset = Symbol('kOffset');
|
|
68
60
|
|
|
69
61
|
const {
|
|
70
62
|
Void, Byte, Int16, Int32, Int64, ByteArray, CountedString,
|
|
71
63
|
} = ValueFormat;
|
|
72
64
|
|
|
73
|
-
function pick(size, method, ...value) {
|
|
74
|
-
const buf = Buffer.alloc(size);
|
|
75
|
-
buf[method](...value);
|
|
76
|
-
|
|
77
|
-
return Buffer.from(buf.buffer);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
65
|
class Encoder {
|
|
81
|
-
[
|
|
66
|
+
[kOffset] = 0;
|
|
67
|
+
|
|
68
|
+
[kBuffer] = [/* method, value, offset, length, charset */];
|
|
82
69
|
|
|
83
70
|
[kData];
|
|
84
71
|
|
|
@@ -102,25 +89,25 @@ class Encoder {
|
|
|
102
89
|
}
|
|
103
90
|
|
|
104
91
|
put(value) {
|
|
105
|
-
this[kBuffer].push(
|
|
92
|
+
this[kBuffer].push(['writeInt8', Number(value), (this[kOffset] += 1) - 1, 1]);
|
|
106
93
|
|
|
107
94
|
return this;
|
|
108
95
|
}
|
|
109
96
|
|
|
110
97
|
putShort(value) {
|
|
111
|
-
this[kBuffer].push(
|
|
98
|
+
this[kBuffer].push(['writeInt16LE', Number(value), (this[kOffset] += 2) - 2, 2]);
|
|
112
99
|
|
|
113
100
|
return this;
|
|
114
101
|
}
|
|
115
102
|
|
|
116
103
|
putInt(value) {
|
|
117
|
-
this[kBuffer].push(
|
|
104
|
+
this[kBuffer].push(['writeInt32LE', Number(value), (this[kOffset] += 4) - 4, 4]);
|
|
118
105
|
|
|
119
106
|
return this;
|
|
120
107
|
}
|
|
121
108
|
|
|
122
109
|
putLong(value) {
|
|
123
|
-
this[kBuffer].push(
|
|
110
|
+
this[kBuffer].push(['writeBigInt64LE', BigInt(value), (this[kOffset] += 8) - 8, 8]);
|
|
124
111
|
|
|
125
112
|
return this;
|
|
126
113
|
}
|
|
@@ -128,7 +115,7 @@ class Encoder {
|
|
|
128
115
|
writeCountedString(value) {
|
|
129
116
|
const len = value ? Buffer.byteLength(value) : 0;
|
|
130
117
|
this.putInt(len);
|
|
131
|
-
if (len) { this[kBuffer].push(
|
|
118
|
+
if (len) { this[kBuffer].push(['write', value, (this[kOffset] += len) - len, len, utf8]); }
|
|
132
119
|
|
|
133
120
|
return this;
|
|
134
121
|
}
|
|
@@ -168,17 +155,24 @@ class Encoder {
|
|
|
168
155
|
}
|
|
169
156
|
|
|
170
157
|
if (Buffer.isBuffer(value)) {
|
|
171
|
-
|
|
172
|
-
this
|
|
158
|
+
const len = value.length;
|
|
159
|
+
this.put(ByteArray).putInt(len);
|
|
160
|
+
this[kBuffer].push(['fill', value, (this[kOffset] += len) - len, len]);
|
|
173
161
|
}
|
|
174
162
|
|
|
175
163
|
return this;
|
|
176
164
|
}
|
|
177
165
|
|
|
178
|
-
get buffer() {
|
|
179
|
-
|
|
166
|
+
get buffer() {
|
|
167
|
+
this[kOffset] = 0;
|
|
168
|
+
this[kBuffer] = [];
|
|
169
|
+
this.compress();
|
|
170
|
+
const buf = Buffer.alloc(this[kOffset]);
|
|
171
|
+
this[kBuffer].forEach(([method, value, offset, length, charset]) => buf[method](value, offset, length, charset));
|
|
180
172
|
|
|
181
|
-
|
|
173
|
+
return buf;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
182
176
|
|
|
183
177
|
class Decoder {
|
|
184
178
|
[kOffset] = 1;
|