@cc-livekit/ttsignal 1.0.6 → 1.0.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/build/Release/ttsignal.darwin.arm64.node +0 -0
- package/build/Release/ttsignal.darwin.x64.node +0 -0
- package/build/Release/ttsignal.linux.arm64.node +0 -0
- package/build/Release/ttsignal.linux.x64.node +0 -0
- package/build/Release/ttsignal.win32.x64.node +0 -0
- package/index.js +611 -482
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/index.js
CHANGED
|
@@ -1,91 +1,33 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
1
|
/*******************************************************************************
|
|
4
2
|
* javascript glue wrapper of ttsignal module
|
|
5
3
|
* @module index.js
|
|
6
|
-
* @author
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// var util = require('util');
|
|
10
|
-
const EventEmitter = require("events").EventEmitter;
|
|
11
|
-
const fs = require("fs");
|
|
12
|
-
const path = require("path");
|
|
13
|
-
const Module = require("module");
|
|
14
|
-
|
|
15
|
-
const PLATFORM = process.platform;
|
|
16
|
-
const ARCH = process.arch;
|
|
17
|
-
const ADDON_BASENAME = `ttsignal.${PLATFORM}.${ARCH}.node`;
|
|
18
|
-
|
|
19
|
-
function expandAsar(candidate) {
|
|
20
|
-
if (!candidate) return candidate;
|
|
21
|
-
const idx = candidate.indexOf(".asar/");
|
|
22
|
-
if (idx === -1) return candidate;
|
|
23
|
-
return candidate.replace(".asar/", ".asar.unpacked/");
|
|
24
|
-
}
|
|
4
|
+
* @author anto.
|
|
5
|
+
*******************************************************************************/
|
|
25
6
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (process.env.TTSIGNAL_NATIVE_PATH) {
|
|
29
|
-
candidates.push(process.env.TTSIGNAL_NATIVE_PATH);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const baseDir = __dirname;
|
|
33
|
-
const searchRoots = [
|
|
34
|
-
path.join(baseDir, "build", "Release"),
|
|
35
|
-
path.join(baseDir, "dist", "build", "Release"),
|
|
36
|
-
path.join(baseDir, "..", "build", "Release"),
|
|
37
|
-
path.join(baseDir, "..", "dist", "build", "Release"),
|
|
38
|
-
];
|
|
39
|
-
|
|
40
|
-
for (const root of searchRoots) {
|
|
41
|
-
candidates.push(path.join(root, ADDON_BASENAME));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const unique = [...new Set(candidates.filter(Boolean))];
|
|
45
|
-
|
|
46
|
-
for (const candidate of unique) {
|
|
47
|
-
if (fs.existsSync(candidate)) {
|
|
48
|
-
return candidate;
|
|
49
|
-
}
|
|
50
|
-
const unpacked = expandAsar(candidate);
|
|
51
|
-
if (unpacked !== candidate && fs.existsSync(unpacked)) {
|
|
52
|
-
return unpacked;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const tried = unique.concat(unique.map(expandAsar)).filter(Boolean);
|
|
57
|
-
throw new Error(
|
|
58
|
-
`Unable to locate ttsignal native addon (${PLATFORM}/${ARCH}). Tried: ${tried.join(
|
|
59
|
-
", "
|
|
60
|
-
)}`
|
|
61
|
-
);
|
|
62
|
-
}
|
|
7
|
+
var util = require('util');
|
|
8
|
+
var EventEmitter = require('events').EventEmitter;
|
|
63
9
|
|
|
64
|
-
|
|
65
|
-
const createRequire =
|
|
66
|
-
Module.createRequire ||
|
|
67
|
-
Module.createRequireFromPath ||
|
|
68
|
-
require("module").createRequire;
|
|
69
|
-
const req = createRequire(__filename);
|
|
70
|
-
const addonPath = resolveAddonPath();
|
|
71
|
-
return req(addonPath);
|
|
72
|
-
}
|
|
10
|
+
var ttsignal = null;
|
|
73
11
|
|
|
74
|
-
|
|
12
|
+
if (process.ttsBuildType == 'debug') {
|
|
13
|
+
ttsignal = require('./Debug/ttsignal.'+process.platform+'.'+process.arch+'.node');
|
|
14
|
+
} else {
|
|
15
|
+
ttsignal = require('./Release/ttsignal.'+process.platform+'.'+process.arch+'.node');
|
|
16
|
+
}
|
|
75
17
|
|
|
76
18
|
const CONST = {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
19
|
+
TTS_TYPE_COMMAND : 0x01,
|
|
20
|
+
TTS_TYPE_MESSAGE : 0x02,
|
|
21
|
+
TTS_TYPE_USER_CONTROL : 0x03,
|
|
22
|
+
TTS_CC_BBR : 0x62,
|
|
23
|
+
TTS_CC_BBR2 : 0x42,
|
|
24
|
+
TTS_CC_CUBIC : 0x63,
|
|
25
|
+
TTS_CC_RENO : 0x72,
|
|
26
|
+
LOG_LEVEL_DEBUG : 0x01,
|
|
27
|
+
LOG_LEVEL_INFO : 0x02,
|
|
28
|
+
LOG_LEVEL_WARN : 0x03,
|
|
29
|
+
LOG_LEVEL_ERROR : 0x04,
|
|
30
|
+
LOG_LEVEL_FATAL : 0x05
|
|
89
31
|
};
|
|
90
32
|
|
|
91
33
|
//*******************************************************************************
|
|
@@ -93,47 +35,45 @@ const CONST = {
|
|
|
93
35
|
//*******************************************************************************
|
|
94
36
|
|
|
95
37
|
function copyProperties(target, source) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
38
|
+
for (var k in source){
|
|
39
|
+
if (source.hasOwnProperty(k)) {
|
|
40
|
+
target[k] = source[k];
|
|
41
|
+
}
|
|
99
42
|
}
|
|
100
|
-
}
|
|
101
43
|
}
|
|
102
44
|
copyProperties(ttsignal, CONST);
|
|
103
45
|
|
|
104
46
|
function inherits(target, source) {
|
|
105
|
-
for (var k in source.prototype)
|
|
47
|
+
for (var k in source.prototype)
|
|
48
|
+
target.prototype[k] = source.prototype[k];
|
|
106
49
|
}
|
|
107
50
|
inherits(ttsignal.Connector, EventEmitter);
|
|
108
51
|
inherits(ttsignal.Connection, EventEmitter);
|
|
109
52
|
inherits(ttsignal.Server, EventEmitter);
|
|
110
53
|
inherits(ttsignal.ServerConnection, EventEmitter);
|
|
111
54
|
|
|
55
|
+
|
|
112
56
|
/*******************************************************************************
|
|
113
|
-
|
|
114
|
-
|
|
57
|
+
* @class ttsignal.Connector
|
|
58
|
+
*******************************************************************************/
|
|
115
59
|
|
|
116
60
|
/**
|
|
117
61
|
* @method _internalCallback
|
|
118
62
|
* @private
|
|
119
|
-
*
|
|
120
|
-
*
|
|
63
|
+
*
|
|
64
|
+
*
|
|
121
65
|
**/
|
|
122
|
-
ttsignal.Connector.prototype._internalCallback = function
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
this.emit("close");
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
};
|
|
66
|
+
ttsignal.Connector.prototype._internalCallback = function(type, __arg2, __arg3){
|
|
67
|
+
switch(type){
|
|
68
|
+
case 'close':
|
|
69
|
+
this.emit('close');
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
133
73
|
|
|
134
74
|
/**
|
|
135
75
|
* 为特定事件添加一个监听处理程序.
|
|
136
|
-
* 当前支持除'_error/_result/onStatus/error/close'等事件之外的
|
|
76
|
+
* 当前支持除'_error/_result/onStatus/error/close'等事件之外的
|
|
137
77
|
* 任何自定义事件.上述事件为内部保留事件,用户不应定义与这些事件同名的
|
|
138
78
|
* 远程调用函数名。与用户自定义事件相对应的事件处理函数的参数列表与远端
|
|
139
79
|
* 调用时传入的参数列表一致。
|
|
@@ -184,17 +124,17 @@ ttsignal.Connector.prototype._internalCallback = function (
|
|
|
184
124
|
* @example
|
|
185
125
|
* press.createConnection(config);
|
|
186
126
|
**/
|
|
187
|
-
ttsignal.Connector.prototype.createConnection = function
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
127
|
+
ttsignal.Connector.prototype.createConnection = function(config){
|
|
128
|
+
if (typeof(config) != 'object'){
|
|
129
|
+
throw Error('Invalid args value.');
|
|
130
|
+
}
|
|
131
|
+
var default_config = {
|
|
132
|
+
c_cong_ctl : CONST.TTS_CC_BBR2
|
|
133
|
+
}
|
|
134
|
+
copyProperties(default_config, config);
|
|
135
|
+
let conn = this.__createConnection__(default_config);
|
|
136
|
+
return conn;
|
|
137
|
+
}
|
|
198
138
|
|
|
199
139
|
/**
|
|
200
140
|
* 关闭。
|
|
@@ -205,73 +145,84 @@ ttsignal.Connector.prototype.createConnection = function (config) {
|
|
|
205
145
|
* @example
|
|
206
146
|
* connector.close();
|
|
207
147
|
**/
|
|
208
|
-
ttsignal.Connector.prototype.close = function
|
|
209
|
-
|
|
210
|
-
}
|
|
148
|
+
ttsignal.Connector.prototype.close = function(){
|
|
149
|
+
this.__close__();
|
|
150
|
+
}
|
|
151
|
+
|
|
211
152
|
|
|
212
153
|
/*******************************************************************************
|
|
213
|
-
|
|
214
|
-
|
|
154
|
+
* @class ttsignal.Connection
|
|
155
|
+
*******************************************************************************/
|
|
215
156
|
|
|
216
157
|
/**
|
|
217
158
|
* @method _internalCallback
|
|
218
159
|
* @private
|
|
219
|
-
*
|
|
220
|
-
*
|
|
160
|
+
*
|
|
161
|
+
*
|
|
221
162
|
**/
|
|
222
|
-
ttsignal.Connection.prototype._internalCallback = function
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
163
|
+
ttsignal.Connection.prototype._internalCallback = function(type, __arg2, __arg3, __arg4, __arg5){
|
|
164
|
+
let self = this;
|
|
165
|
+
switch(type){
|
|
166
|
+
case 'handshakeFinished':
|
|
167
|
+
this.streams = {};
|
|
168
|
+
this.emit('handshakeFinished');
|
|
169
|
+
break;
|
|
170
|
+
case 'streamCreated':
|
|
171
|
+
if (this.streams.hasOwnProperty(__arg2)) {
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
var stream = new ttsignal.Stream(this, __arg2);
|
|
175
|
+
this.streams[__arg2] = stream;
|
|
176
|
+
this.emit('streamCreated', stream);
|
|
177
|
+
break;
|
|
178
|
+
case 'streamClosed':
|
|
179
|
+
if (!this.streams.hasOwnProperty(__arg2)) {
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
var stream = this.streams[__arg2];
|
|
183
|
+
delete this.streams[__arg2];
|
|
184
|
+
stream.onClose();
|
|
185
|
+
break;
|
|
186
|
+
case 'streamDataAcked':
|
|
187
|
+
if (!this.streams.hasOwnProperty(__arg2)) {
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
var stream = this.streams[__arg2];
|
|
191
|
+
stream.onDataAcked(__arg3, __arg4, __arg5);
|
|
192
|
+
break;
|
|
193
|
+
case 'streamDataSent':
|
|
194
|
+
if (!this.streams.hasOwnProperty(__arg2)) {
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
var stream = this.streams[__arg2];
|
|
198
|
+
stream.onDataSent(__arg3, __arg4);
|
|
199
|
+
break;
|
|
200
|
+
case 'command':
|
|
201
|
+
if (!this.streams.hasOwnProperty(__arg2)) {
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
var stream = this.streams[__arg2];
|
|
205
|
+
stream.onCommand(__arg3);
|
|
206
|
+
break;
|
|
207
|
+
case 'data':
|
|
208
|
+
if (!this.streams.hasOwnProperty(__arg2)) {
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
var stream = this.streams[__arg2];
|
|
212
|
+
stream.onData(__arg3, __arg4);
|
|
213
|
+
break;
|
|
214
|
+
case 'restart':
|
|
215
|
+
this.emit('restart', __arg2, __arg3);
|
|
216
|
+
break;
|
|
217
|
+
case 'close':
|
|
218
|
+
this.emit('close', __arg2);
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
271
222
|
|
|
272
223
|
/**
|
|
273
224
|
* 为特定事件添加一个监听处理程序.
|
|
274
|
-
* 当前支持除'_error/_result/onStatus/error/close'等事件之外的
|
|
225
|
+
* 当前支持除'_error/_result/onStatus/error/close'等事件之外的
|
|
275
226
|
* 任何自定义事件.上述事件为内部保留事件,用户不应定义与这些事件同名的
|
|
276
227
|
* 远程调用函数名。与用户自定义事件相对应的事件处理函数的参数列表与远端
|
|
277
228
|
* 调用时传入的参数列表一致。
|
|
@@ -336,31 +287,26 @@ ttsignal.Connection.prototype._internalCallback = function (
|
|
|
336
287
|
* console.log(result);
|
|
337
288
|
* });
|
|
338
289
|
**/
|
|
339
|
-
ttsignal.Connection.prototype.connect = function
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
timeoutInMs,
|
|
343
|
-
callback
|
|
344
|
-
) {
|
|
345
|
-
if (typeof url != "string") {
|
|
346
|
-
throw Error("Invalid url value.");
|
|
347
|
-
}
|
|
348
|
-
if (typeof callback != "function") {
|
|
349
|
-
throw Error("Invalid callback value.");
|
|
350
|
-
}
|
|
351
|
-
this.__connect__(url, JSON.stringify(args), timeoutInMs, (err, response) => {
|
|
352
|
-
if (typeof response == "string") {
|
|
353
|
-
try {
|
|
354
|
-
props = JSON.parse(response);
|
|
355
|
-
callback(err, props);
|
|
356
|
-
} catch (e) {
|
|
357
|
-
callback(err, response);
|
|
358
|
-
}
|
|
359
|
-
} else {
|
|
360
|
-
callback(err, null);
|
|
290
|
+
ttsignal.Connection.prototype.connect = function(url, args, timeoutInMs, callback){
|
|
291
|
+
if (typeof(url) != 'string'){
|
|
292
|
+
throw Error('Invalid url value.');
|
|
361
293
|
}
|
|
362
|
-
|
|
363
|
-
|
|
294
|
+
if (typeof(callback) != 'function'){
|
|
295
|
+
throw Error('Invalid callback value.');
|
|
296
|
+
}
|
|
297
|
+
this.__connect__(url, JSON.stringify(args), timeoutInMs, (err, response)=>{
|
|
298
|
+
if (typeof response == 'string') {
|
|
299
|
+
try {
|
|
300
|
+
props = JSON.parse(response);
|
|
301
|
+
callback(err, props);
|
|
302
|
+
} catch (e) {
|
|
303
|
+
callback(err, response);
|
|
304
|
+
}
|
|
305
|
+
} else {
|
|
306
|
+
callback(err, null);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
364
310
|
|
|
365
311
|
/**
|
|
366
312
|
* 重新创建底层socket。
|
|
@@ -371,9 +317,9 @@ ttsignal.Connection.prototype.connect = function (
|
|
|
371
317
|
* @example
|
|
372
318
|
* conn.restart();
|
|
373
319
|
**/
|
|
374
|
-
ttsignal.Connection.prototype.restart = function
|
|
375
|
-
|
|
376
|
-
}
|
|
320
|
+
ttsignal.Connection.prototype.restart = function(){
|
|
321
|
+
this.__restart__();
|
|
322
|
+
}
|
|
377
323
|
|
|
378
324
|
/**
|
|
379
325
|
* 关闭。
|
|
@@ -384,175 +330,345 @@ ttsignal.Connection.prototype.restart = function () {
|
|
|
384
330
|
* @example
|
|
385
331
|
* conn.close();
|
|
386
332
|
**/
|
|
387
|
-
ttsignal.Connection.prototype.close = function
|
|
388
|
-
|
|
389
|
-
}
|
|
333
|
+
ttsignal.Connection.prototype.close = function(){
|
|
334
|
+
this.__close__();
|
|
335
|
+
}
|
|
390
336
|
|
|
391
337
|
/*******************************************************************************
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
class Stream extends EventEmitter {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
338
|
+
* @class ttsignal.Stream
|
|
339
|
+
*******************************************************************************/
|
|
340
|
+
|
|
341
|
+
class Stream extends EventEmitter {
|
|
342
|
+
constructor(conn, streamId){
|
|
343
|
+
super();
|
|
344
|
+
this.conn = conn;
|
|
345
|
+
this.streamId = streamId;
|
|
346
|
+
this.nextTransId = 2;
|
|
347
|
+
this.stubs = {};
|
|
348
|
+
this.dataStreams = {};
|
|
349
|
+
}
|
|
350
|
+
onCommand(cmdStr){
|
|
351
|
+
let self = this;
|
|
352
|
+
try {
|
|
353
|
+
let cmd = JSON.parse(cmdStr)
|
|
354
|
+
if (typeof(cmd) != 'object') {
|
|
355
|
+
throw Error('Invalid command value.' + __arg2);
|
|
356
|
+
}
|
|
357
|
+
if (!cmd.hasOwnProperty('name')){
|
|
358
|
+
throw Error('Invalid command value, MUST have "name" property.' + __arg2);
|
|
359
|
+
}
|
|
360
|
+
if (cmd.name == '_error' || cmd.name == '_result' || cmd.name == 'onStatus'){
|
|
361
|
+
if (self.stubs.hasOwnProperty(cmd.transId)) {
|
|
362
|
+
self.stubs[cmd.transId](cmd);
|
|
363
|
+
let keepStub = cmd.name == 'onStatus'
|
|
364
|
+
if (!keepStub) {
|
|
365
|
+
delete self.stubs[cmd.transId];
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
} else {
|
|
369
|
+
if (cmd.hasOwnProperty('transId')) {
|
|
370
|
+
cmd.echoResult = function(result){
|
|
371
|
+
self.sendCommand({
|
|
372
|
+
name: '_result',
|
|
373
|
+
transId: cmd.transId,
|
|
374
|
+
result: result
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
cmd.echoError = function(error){
|
|
378
|
+
self.sendCommand({
|
|
379
|
+
name: '_error',
|
|
380
|
+
transId: cmd.transId,
|
|
381
|
+
error: error
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
} else {
|
|
385
|
+
cmd.echoResult = ()=>{};
|
|
386
|
+
cmd.echoError = ()=>{};
|
|
387
|
+
}
|
|
388
|
+
self.emit(cmd.name, cmd);
|
|
389
|
+
}
|
|
390
|
+
} catch (error) {
|
|
391
|
+
console.error('parse command failed', error);
|
|
392
|
+
return;
|
|
420
393
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
name: "_error",
|
|
433
|
-
transId: cmd.transId,
|
|
434
|
-
error: error,
|
|
435
|
-
});
|
|
436
|
-
};
|
|
437
|
-
} else {
|
|
438
|
-
cmd.echoResult = () => {};
|
|
439
|
-
cmd.echoError = () => {};
|
|
394
|
+
}
|
|
395
|
+
onData(data, transId){
|
|
396
|
+
if (transId && this.dataStreams.hasOwnProperty(transId)) {
|
|
397
|
+
let ds = this.dataStreams[transId];
|
|
398
|
+
if (data.length === 0) {
|
|
399
|
+
delete this.dataStreams[transId];
|
|
400
|
+
ds.emit('end');
|
|
401
|
+
} else {
|
|
402
|
+
ds.emit('data', data);
|
|
403
|
+
}
|
|
404
|
+
return;
|
|
440
405
|
}
|
|
441
|
-
|
|
442
|
-
}
|
|
443
|
-
} catch (error) {
|
|
444
|
-
console.error("parse command failed", error);
|
|
445
|
-
return;
|
|
406
|
+
this.emit('data', data);
|
|
446
407
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
this.emit("close");
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
/**
|
|
458
|
-
* 发送命令.
|
|
459
|
-
*
|
|
460
|
-
* @method sendCommand
|
|
461
|
-
* @public
|
|
462
|
-
* @param timestamp {Number} timestamp.
|
|
463
|
-
* @param cmd {Buffer} commnd to send.
|
|
464
|
-
* @example
|
|
465
|
-
* conn.sendCommand(cmd);
|
|
466
|
-
**/
|
|
467
|
-
sendCommand(cmd, callback) {
|
|
468
|
-
if (typeof cmd != "object") {
|
|
469
|
-
throw Error("Invalid command value.");
|
|
408
|
+
|
|
409
|
+
onClose(){
|
|
410
|
+
for (let tid in this.dataStreams) {
|
|
411
|
+
this.dataStreams[tid].emit('end');
|
|
412
|
+
}
|
|
413
|
+
this.dataStreams = {};
|
|
414
|
+
this.emit('close');
|
|
470
415
|
}
|
|
471
|
-
|
|
472
|
-
|
|
416
|
+
|
|
417
|
+
/** QUIC 发送侧:数据确认回调;emit `dataAcked`(ackDelayTimeµs, ackedBytes, inflightBytes)。 */
|
|
418
|
+
onDataAcked(ackDelayTime, ackedBytes, inflightBytes){
|
|
419
|
+
this.emit('dataAcked', ackDelayTime, ackedBytes, inflightBytes);
|
|
473
420
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
421
|
+
|
|
422
|
+
/** QUIC 发送侧:数据已从待发队列写入传输;emit `dataSent`(nTransId, size)。putFile 返回的 ws 仅转发本 transId 为 `dataSent`(size)。 */
|
|
423
|
+
onDataSent(nTransId, size){
|
|
424
|
+
this.emit('dataSent', nTransId, size);
|
|
477
425
|
}
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* 发送命令.
|
|
429
|
+
*
|
|
430
|
+
* @method sendCommand
|
|
431
|
+
* @public
|
|
432
|
+
* @param cmd {Object} command to send.
|
|
433
|
+
* @param callback {Function} callback function.
|
|
434
|
+
* @example
|
|
435
|
+
* conn.sendCommand(cmd);
|
|
436
|
+
**/
|
|
437
|
+
sendCommand(cmd, callback){
|
|
438
|
+
if (typeof(cmd) != 'object') {
|
|
439
|
+
throw Error('Invalid command value.');
|
|
440
|
+
}
|
|
441
|
+
if (!cmd.hasOwnProperty('name')){
|
|
442
|
+
throw Error('Invalid command value, MUST have "name" property.');
|
|
443
|
+
}
|
|
444
|
+
if (typeof callback === 'function') {
|
|
445
|
+
cmd.transId = this.nextTransId++;
|
|
446
|
+
this.stubs[cmd.transId] = callback;
|
|
447
|
+
}
|
|
448
|
+
let msg = JSON.stringify(cmd);
|
|
449
|
+
let buf = Buffer.from(msg, 'utf8');
|
|
450
|
+
this.conn.__sendPacket__(CONST.TTS_TYPE_COMMAND, (new Date).getTime(),
|
|
451
|
+
cmd.transId, this.streamId, buf);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* 发送数据.
|
|
456
|
+
*
|
|
457
|
+
* @method sendData
|
|
458
|
+
* @public
|
|
459
|
+
* @param timestamp {Number} timestamp.
|
|
460
|
+
* @param data {Buffer} data to send.
|
|
461
|
+
* @example
|
|
462
|
+
* conn.sendData(data);
|
|
463
|
+
**/
|
|
464
|
+
sendData(data){
|
|
465
|
+
if (data instanceof Buffer == false) {
|
|
466
|
+
throw Error('Invalid data type, MUST be Buffer.');
|
|
467
|
+
}
|
|
468
|
+
this.conn.__sendPacket__(CONST.TTS_TYPE_MESSAGE, (new Date).getTime(),
|
|
469
|
+
0, this.streamId, data);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* 请求文件(数据流下载)。
|
|
474
|
+
*
|
|
475
|
+
* @method getFile
|
|
476
|
+
* @public
|
|
477
|
+
* @param req {Object} 请求参数,如 {path:"index.html"}
|
|
478
|
+
* @param callback {Function} 命令响应回调,透传给底层 __sendPacket__
|
|
479
|
+
* @return {EventEmitter} 数据流对象,支持 'data' 和 'end' 事件
|
|
480
|
+
* @example
|
|
481
|
+
* let ds = stream.getFile({path:"index.html"}, (cmd)=>{
|
|
482
|
+
* console.log('response:', cmd);
|
|
483
|
+
* });
|
|
484
|
+
* ds.on('data', (chunk) => { ... });
|
|
485
|
+
* ds.on('end', () => { ... });
|
|
486
|
+
**/
|
|
487
|
+
getFile(args, callback){
|
|
488
|
+
if (typeof(args) != 'object') {
|
|
489
|
+
throw Error('Invalid request value.');
|
|
490
|
+
}
|
|
491
|
+
if (!args.hasOwnProperty('path')) {
|
|
492
|
+
throw Error('Invalid request value, MUST have "path" property.');
|
|
493
|
+
}
|
|
494
|
+
args.method = 'GET';
|
|
495
|
+
let req = {
|
|
496
|
+
name: 'staticFile',
|
|
497
|
+
props: args
|
|
498
|
+
};
|
|
499
|
+
let self = this;
|
|
500
|
+
let transId = this.nextTransId++;
|
|
501
|
+
req.transId = transId;
|
|
502
|
+
if (typeof callback === 'function') {
|
|
503
|
+
this.stubs[transId] = callback;
|
|
504
|
+
}
|
|
505
|
+
let ds = new EventEmitter();
|
|
506
|
+
ds.once('end', () => { delete self.dataStreams[transId]; });
|
|
507
|
+
this.dataStreams[transId] = ds;
|
|
508
|
+
let msg = JSON.stringify(req);
|
|
509
|
+
let buf = Buffer.from(msg, 'utf8');
|
|
510
|
+
this.conn.__sendPacket__(CONST.TTS_TYPE_COMMAND, (new Date).getTime(),
|
|
511
|
+
transId, this.streamId, buf);
|
|
512
|
+
return ds;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* 上传文件(数据流上传)。
|
|
517
|
+
*
|
|
518
|
+
* @method putFile
|
|
519
|
+
* @public
|
|
520
|
+
* @param req {Object} 请求参数,如 {path:"upload.bin"}
|
|
521
|
+
* @param callback {Function} 命令响应回调
|
|
522
|
+
* @return {events.EventEmitter} 写入流:write(data)、end(),并可 on('dataSent', (size)=>{})(仅本 putFile 事务)。
|
|
523
|
+
* @example
|
|
524
|
+
* let ws = stream.putFile({path:"upload.bin"}, (cmd)=>{
|
|
525
|
+
* console.log('response:', cmd);
|
|
526
|
+
* });
|
|
527
|
+
* ws.on('dataSent', (size) => {});
|
|
528
|
+
* ws.write(chunk1);
|
|
529
|
+
* ws.write(chunk2);
|
|
530
|
+
* ws.end();
|
|
531
|
+
**/
|
|
532
|
+
putFile(args, callback){
|
|
533
|
+
if (typeof(args) != 'object') {
|
|
534
|
+
throw Error('Invalid request value.');
|
|
535
|
+
}
|
|
536
|
+
if (!args.hasOwnProperty('path')) {
|
|
537
|
+
throw Error('Invalid request value, MUST have "path" property.');
|
|
538
|
+
}
|
|
539
|
+
if (!args.hasOwnProperty('size')) {
|
|
540
|
+
throw Error('Invalid request value, MUST have "path" property.');
|
|
541
|
+
}
|
|
542
|
+
args.method = 'PUT';
|
|
543
|
+
let req = {
|
|
544
|
+
name: 'staticFile',
|
|
545
|
+
props: args
|
|
546
|
+
};
|
|
547
|
+
let self = this;
|
|
548
|
+
let transId = this.nextTransId++;
|
|
549
|
+
req.transId = transId;
|
|
550
|
+
if (typeof callback === 'function') {
|
|
551
|
+
this.stubs[transId] = callback;
|
|
552
|
+
}
|
|
553
|
+
let msg = JSON.stringify(req);
|
|
554
|
+
let buf = Buffer.from(msg, 'utf8');
|
|
555
|
+
this.conn.__sendPacket__(CONST.TTS_TYPE_COMMAND, (new Date).getTime(),
|
|
556
|
+
transId, this.streamId, buf);
|
|
557
|
+
let ended = false;
|
|
558
|
+
let ws = new EventEmitter();
|
|
559
|
+
let onDataSent = (nTransId, size) => {
|
|
560
|
+
if (nTransId == transId) {
|
|
561
|
+
ws.emit('dataSent', size);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
this.on('dataSent', onDataSent);
|
|
565
|
+
ws.write = (data) => {
|
|
566
|
+
if (ended) {
|
|
567
|
+
throw Error('Write after end.');
|
|
568
|
+
}
|
|
569
|
+
if (data instanceof Buffer == false) {
|
|
570
|
+
throw Error('Invalid data type, MUST be Buffer.');
|
|
571
|
+
}
|
|
572
|
+
self.conn.__sendPacket__(CONST.TTS_TYPE_MESSAGE, (new Date).getTime(),
|
|
573
|
+
transId, self.streamId, data);
|
|
574
|
+
}
|
|
575
|
+
ws.end = () => {
|
|
576
|
+
if (ended) return;
|
|
577
|
+
ended = true;
|
|
578
|
+
self.conn.__sendPacket__(CONST.TTS_TYPE_MESSAGE, (new Date).getTime(),
|
|
579
|
+
transId, self.streamId, Buffer.alloc(0));
|
|
580
|
+
self.removeListener('dataSent', onDataSent);
|
|
581
|
+
}
|
|
582
|
+
return ws;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* 请求文件(数据流下载)。
|
|
587
|
+
*
|
|
588
|
+
* @method getLogFile
|
|
589
|
+
* @public
|
|
590
|
+
* @param req {Object} 请求参数,如 {path:"room_name"}
|
|
591
|
+
* @param callback {Function} 命令响应回调,透传给底层 __sendPacket__
|
|
592
|
+
* @return {EventEmitter} 数据流对象,支持 'data' 和 'end' 事件
|
|
593
|
+
* @example
|
|
594
|
+
* let ds = stream.getLogFile({path:"room_name"}, (cmd)=>{
|
|
595
|
+
* console.log('response:', cmd);
|
|
596
|
+
* });
|
|
597
|
+
* ds.on('data', (chunk) => { ... });
|
|
598
|
+
* ds.on('end', () => { ... });
|
|
599
|
+
**/
|
|
600
|
+
getLogFile(args, callback){
|
|
601
|
+
if (typeof(args) != 'object') {
|
|
602
|
+
throw Error('Invalid request value.');
|
|
603
|
+
}
|
|
604
|
+
if (!args.hasOwnProperty('roomId')) {
|
|
605
|
+
throw Error('Invalid request value, MUST have "roomId" property.');
|
|
606
|
+
}
|
|
607
|
+
args.method = 'GET';
|
|
608
|
+
let req = {
|
|
609
|
+
name: 'logFile',
|
|
610
|
+
props: args
|
|
611
|
+
};
|
|
612
|
+
let self = this;
|
|
613
|
+
let transId = this.nextTransId++;
|
|
614
|
+
req.transId = transId;
|
|
615
|
+
if (typeof callback === 'function') {
|
|
616
|
+
this.stubs[transId] = callback;
|
|
617
|
+
}
|
|
618
|
+
let ds = new EventEmitter();
|
|
619
|
+
ds.once('end', () => { delete self.dataStreams[transId]; });
|
|
620
|
+
this.dataStreams[transId] = ds;
|
|
621
|
+
let msg = JSON.stringify(req);
|
|
622
|
+
let buf = Buffer.from(msg, 'utf8');
|
|
623
|
+
this.conn.__sendPacket__(CONST.TTS_TYPE_COMMAND, (new Date).getTime(),
|
|
624
|
+
transId, this.streamId, buf);
|
|
625
|
+
return ds;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* 关闭。
|
|
630
|
+
*
|
|
631
|
+
* @method close
|
|
632
|
+
* @public
|
|
633
|
+
* @sync
|
|
634
|
+
* @example
|
|
635
|
+
* conn.close();
|
|
636
|
+
**/
|
|
637
|
+
close(){
|
|
638
|
+
this.conn.__closeStream__(this.streamId);
|
|
502
639
|
}
|
|
503
|
-
this.conn.__sendPacket__(
|
|
504
|
-
CONST.TTS_TYPE_MESSAGE,
|
|
505
|
-
new Date().getTime(),
|
|
506
|
-
0,
|
|
507
|
-
this.streamId,
|
|
508
|
-
data
|
|
509
|
-
);
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
/**
|
|
513
|
-
* 关闭。
|
|
514
|
-
*
|
|
515
|
-
* @method close
|
|
516
|
-
* @public
|
|
517
|
-
* @sync
|
|
518
|
-
* @example
|
|
519
|
-
* conn.close();
|
|
520
|
-
**/
|
|
521
|
-
close() {
|
|
522
|
-
this.conn.__closeStream__(this.streamId);
|
|
523
|
-
}
|
|
524
640
|
}
|
|
525
641
|
ttsignal.Stream = Stream;
|
|
526
642
|
|
|
527
643
|
/*******************************************************************************
|
|
528
|
-
|
|
529
|
-
|
|
644
|
+
* @class ttsignal.Server
|
|
645
|
+
*******************************************************************************/
|
|
530
646
|
|
|
531
647
|
/**
|
|
532
648
|
* @method _internalCallback
|
|
533
649
|
* @private
|
|
534
|
-
*
|
|
535
|
-
*
|
|
650
|
+
*
|
|
651
|
+
*
|
|
536
652
|
**/
|
|
537
|
-
ttsignal.Server.prototype._internalCallback = function
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
}
|
|
653
|
+
ttsignal.Server.prototype._internalCallback = function(type, __arg2, __arg3){
|
|
654
|
+
switch(type){
|
|
655
|
+
case 'connection':
|
|
656
|
+
if (__arg2 instanceof ttsignal.ServerConnection) {
|
|
657
|
+
let conn = __arg2;
|
|
658
|
+
conn.nextTransId = 2;
|
|
659
|
+
conn.stubs = {};
|
|
660
|
+
this.emit('connection', conn);
|
|
661
|
+
}
|
|
662
|
+
break;
|
|
663
|
+
case 'close':
|
|
664
|
+
this.emit('close');
|
|
665
|
+
break;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
552
668
|
|
|
553
669
|
/**
|
|
554
670
|
* 为特定事件添加一个监听处理程序.
|
|
555
|
-
* 当前支持除'_error/_result/onStatus/error/close'等事件之外的
|
|
671
|
+
* 当前支持除'_error/_result/onStatus/error/close'等事件之外的
|
|
556
672
|
* 任何自定义事件.上述事件为内部保留事件,用户不应定义与这些事件同名的
|
|
557
673
|
* 远程调用函数名。与用户自定义事件相对应的事件处理函数的参数列表与远端
|
|
558
674
|
* 调用时传入的参数列表一致。
|
|
@@ -603,9 +719,9 @@ ttsignal.Server.prototype._internalCallback = function (type, __arg2, __arg3) {
|
|
|
603
719
|
* @example
|
|
604
720
|
* connector.start();
|
|
605
721
|
**/
|
|
606
|
-
ttsignal.Server.prototype.start = function
|
|
607
|
-
|
|
608
|
-
}
|
|
722
|
+
ttsignal.Server.prototype.start = function(){
|
|
723
|
+
this.__start__();
|
|
724
|
+
}
|
|
609
725
|
|
|
610
726
|
/**
|
|
611
727
|
* 关闭服务器。
|
|
@@ -616,93 +732,88 @@ ttsignal.Server.prototype.start = function () {
|
|
|
616
732
|
* @example
|
|
617
733
|
* connector.close();
|
|
618
734
|
**/
|
|
619
|
-
ttsignal.Server.prototype.close = function
|
|
620
|
-
|
|
621
|
-
}
|
|
735
|
+
ttsignal.Server.prototype.close = function(){
|
|
736
|
+
this.__close__();
|
|
737
|
+
}
|
|
738
|
+
|
|
622
739
|
|
|
623
740
|
/*******************************************************************************
|
|
624
|
-
|
|
625
|
-
|
|
741
|
+
* @class ttsignal.ServerConnection
|
|
742
|
+
*******************************************************************************/
|
|
626
743
|
|
|
627
744
|
/**
|
|
628
745
|
* @method _internalCallback
|
|
629
746
|
* @private
|
|
630
|
-
*
|
|
631
|
-
*
|
|
747
|
+
*
|
|
748
|
+
*
|
|
632
749
|
**/
|
|
633
|
-
ttsignal.ServerConnection.prototype._internalCallback = function
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
)
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
break;
|
|
697
|
-
case "close":
|
|
698
|
-
this.emit("close", __arg2);
|
|
699
|
-
break;
|
|
700
|
-
}
|
|
701
|
-
};
|
|
750
|
+
ttsignal.ServerConnection.prototype._internalCallback = function(type, __arg2, __arg3){
|
|
751
|
+
var self = this;
|
|
752
|
+
switch(type){
|
|
753
|
+
case 'handshakeFinished':
|
|
754
|
+
this.emit('handshakeFinished');
|
|
755
|
+
break;
|
|
756
|
+
case 'connect':
|
|
757
|
+
try {
|
|
758
|
+
props = JSON.parse(__arg2);
|
|
759
|
+
this.emit('connect', props);
|
|
760
|
+
} catch (e) {
|
|
761
|
+
this.emit('connect', e);
|
|
762
|
+
}
|
|
763
|
+
break;
|
|
764
|
+
case 'command':
|
|
765
|
+
try {
|
|
766
|
+
cmd = JSON.parse(__arg2);
|
|
767
|
+
if (typeof(cmd) != 'object') {
|
|
768
|
+
throw Error('Invalid command value.' + __arg2);
|
|
769
|
+
}
|
|
770
|
+
if (!cmd.hasOwnProperty('name')){
|
|
771
|
+
throw Error('Invalid command value, MUST have "name" property.' + __arg2);
|
|
772
|
+
}
|
|
773
|
+
if (cmd.name == '_error' || cmd.name == '_result'){
|
|
774
|
+
if (self.stubs.hasOwnProperty(cmd.transId)) {
|
|
775
|
+
self.stubs[cmd.transId](cmd);
|
|
776
|
+
delete self.stubs[cmd.transId];
|
|
777
|
+
}
|
|
778
|
+
} else {
|
|
779
|
+
if (cmd.hasOwnProperty('transId')) {
|
|
780
|
+
cmd.echoResult = function(result){
|
|
781
|
+
self.sendCommand({
|
|
782
|
+
name: '_result',
|
|
783
|
+
transId: cmd.transId,
|
|
784
|
+
result: result
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
cmd.echoError = function(error){
|
|
788
|
+
self.sendCommand({
|
|
789
|
+
name: '_error',
|
|
790
|
+
transId: cmd.transId,
|
|
791
|
+
error: error
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
} else {
|
|
795
|
+
cmd.echoResult = ()=>{};
|
|
796
|
+
cmd.echoError = ()=>{};
|
|
797
|
+
}
|
|
798
|
+
self.emit(cmd.name, cmd);
|
|
799
|
+
}
|
|
800
|
+
} catch (error) {
|
|
801
|
+
console.error('parse command failed', error);
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
break;
|
|
805
|
+
case 'data':
|
|
806
|
+
this.emit('data', __arg2);
|
|
807
|
+
break;
|
|
808
|
+
case 'close':
|
|
809
|
+
this.emit('close', __arg2);
|
|
810
|
+
break;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
702
813
|
|
|
703
814
|
/**
|
|
704
815
|
* 为特定事件添加一个监听处理程序.
|
|
705
|
-
* 当前支持除'_error/_result/onStatus/error/close'等事件之外的
|
|
816
|
+
* 当前支持除'_error/_result/onStatus/error/close'等事件之外的
|
|
706
817
|
* 任何自定义事件.上述事件为内部保留事件,用户不应定义与这些事件同名的
|
|
707
818
|
* 远程调用函数名。与用户自定义事件相对应的事件处理函数的参数列表与远端
|
|
708
819
|
* 调用时传入的参数列表一致。
|
|
@@ -749,26 +860,28 @@ ttsignal.ServerConnection.prototype._internalCallback = function (
|
|
|
749
860
|
*
|
|
750
861
|
* @method sendCommand
|
|
751
862
|
* @public
|
|
752
|
-
* @param
|
|
753
|
-
* @param
|
|
863
|
+
* @param cmd {Object} command to send.
|
|
864
|
+
* @param callback {Function} callback function.
|
|
754
865
|
* @example
|
|
755
|
-
* conn.sendCommand(cmd)
|
|
866
|
+
* conn.sendCommand(cmd, function(result){
|
|
867
|
+
* console.log(result);
|
|
868
|
+
* });
|
|
756
869
|
**/
|
|
757
|
-
ttsignal.ServerConnection.prototype.sendCommand = function
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
}
|
|
870
|
+
ttsignal.ServerConnection.prototype.sendCommand = function(cmd, callback){
|
|
871
|
+
if (typeof(cmd) != 'object') {
|
|
872
|
+
throw Error('Invalid command value.');
|
|
873
|
+
}
|
|
874
|
+
if (!cmd.hasOwnProperty('name')){
|
|
875
|
+
throw Error('Invalid command value, MUST have "name" property.');
|
|
876
|
+
}
|
|
877
|
+
if (typeof callback === 'function') {
|
|
878
|
+
cmd.transId = this.nextTransId++;
|
|
879
|
+
this.stubs[cmd.transId] = callback;
|
|
880
|
+
}
|
|
881
|
+
let msg = JSON.stringify(cmd);
|
|
882
|
+
let buf = Buffer.from(msg, 'utf8');
|
|
883
|
+
this.__sendPacket__(CONST.TTS_TYPE_COMMAND, (new Date).getTime(), cmd.transId, 0, buf);
|
|
884
|
+
}
|
|
772
885
|
|
|
773
886
|
/**
|
|
774
887
|
* 发送数据.
|
|
@@ -780,12 +893,12 @@ ttsignal.ServerConnection.prototype.sendCommand = function (cmd) {
|
|
|
780
893
|
* @example
|
|
781
894
|
* conn.sendData(data);
|
|
782
895
|
**/
|
|
783
|
-
ttsignal.ServerConnection.prototype.sendData = function
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
}
|
|
896
|
+
ttsignal.ServerConnection.prototype.sendData = function(data){
|
|
897
|
+
if (data instanceof Buffer == false) {
|
|
898
|
+
throw Error('Invalid data type, MUST be Buffer.');
|
|
899
|
+
}
|
|
900
|
+
this.__sendPacket__(CONST.TTS_TYPE_MESSAGE, (new Date).getTime(), 0, data);
|
|
901
|
+
}
|
|
789
902
|
|
|
790
903
|
/**
|
|
791
904
|
* 接受连接。
|
|
@@ -796,12 +909,12 @@ ttsignal.ServerConnection.prototype.sendData = function (data) {
|
|
|
796
909
|
* @example
|
|
797
910
|
* conn.accept(true, { server_param: 'server param' });
|
|
798
911
|
**/
|
|
799
|
-
ttsignal.ServerConnection.prototype.accept = function
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
}
|
|
912
|
+
ttsignal.ServerConnection.prototype.accept = function(accept, result){
|
|
913
|
+
if (typeof(accept) != 'boolean') {
|
|
914
|
+
throw Error('Invalid accept value.');
|
|
915
|
+
}
|
|
916
|
+
this.__accept__(accept, JSON.stringify(result));
|
|
917
|
+
}
|
|
805
918
|
|
|
806
919
|
/**
|
|
807
920
|
* 关闭。
|
|
@@ -812,13 +925,13 @@ ttsignal.ServerConnection.prototype.accept = function (accept, result) {
|
|
|
812
925
|
* @example
|
|
813
926
|
* conn.close();
|
|
814
927
|
**/
|
|
815
|
-
ttsignal.ServerConnection.prototype.close = function
|
|
816
|
-
|
|
817
|
-
}
|
|
928
|
+
ttsignal.ServerConnection.prototype.close = function(){
|
|
929
|
+
this.__close__();
|
|
930
|
+
}
|
|
818
931
|
|
|
819
932
|
/*******************************************************************************
|
|
820
|
-
|
|
821
|
-
|
|
933
|
+
* @class
|
|
934
|
+
*******************************************************************************/
|
|
822
935
|
|
|
823
936
|
/**
|
|
824
937
|
* 创建连接器.
|
|
@@ -826,18 +939,36 @@ ttsignal.ServerConnection.prototype.close = function () {
|
|
|
826
939
|
* @method createConnector
|
|
827
940
|
* @public
|
|
828
941
|
* @param config {Object} configure info.
|
|
942
|
+
* @param config.alpn {String} required, ALPN string ('ttsignal' on the wire regardless).
|
|
943
|
+
* @param config.ca_cert_pem {String=} optional, custom root CA in PEM format.
|
|
944
|
+
* @param config.disableAutoRestart {Boolean=} optional, default `false`.
|
|
945
|
+
* When `false` (default) ttsignal starts a platform-native path-change
|
|
946
|
+
* monitor (NWPathMonitor on macOS, NETLINK_ROUTE on Linux,
|
|
947
|
+
* NotifyIpInterfaceChange on Windows) and automatically restarts the
|
|
948
|
+
* underlying UDP socket whenever the OS reports a different default
|
|
949
|
+
* interface (Wi-Fi <-> ethernet, Wi-Fi <-> wired, VPN up/down). Each
|
|
950
|
+
* auto-restart fires the existing `connection.on('restart', cb)` event,
|
|
951
|
+
* so application code does NOT need to call `connection.restart()`
|
|
952
|
+
* manually. Set `disableAutoRestart: true` for long-lived server
|
|
953
|
+
* deployments where the box never roams.
|
|
829
954
|
* @example
|
|
830
|
-
* var
|
|
955
|
+
* var connector = ttsignal.createConnector({
|
|
956
|
+
* alpn: 'ttsignal',
|
|
957
|
+
* disableAutoRestart: false, // default
|
|
958
|
+
* });
|
|
831
959
|
**/
|
|
832
|
-
ttsignal.createConnector = function
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
960
|
+
ttsignal.createConnector = function(config){
|
|
961
|
+
if (typeof config !== 'object') {
|
|
962
|
+
throw Error('Invalid config.');
|
|
963
|
+
}
|
|
964
|
+
if (!config.alpn){
|
|
965
|
+
throw Error('Invalid alpn value.');
|
|
966
|
+
}
|
|
967
|
+
if (config.caCertPem && !config.ca_cert_pem) {
|
|
968
|
+
config.ca_cert_pem = config.caCertPem;
|
|
969
|
+
}
|
|
970
|
+
return ttsignal.__createConnector__(config);
|
|
971
|
+
}
|
|
841
972
|
|
|
842
973
|
/**
|
|
843
974
|
* 创建服务器.
|
|
@@ -848,23 +979,21 @@ ttsignal.createConnector = function (config) {
|
|
|
848
979
|
* @example
|
|
849
980
|
* var succeed = ttsignal.createServer(config);
|
|
850
981
|
**/
|
|
851
|
-
ttsignal.createServer = function
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
}
|
|
982
|
+
ttsignal.createServer = function(config){
|
|
983
|
+
if (typeof config !== 'object') {
|
|
984
|
+
throw Error('Invalid config.');
|
|
985
|
+
}
|
|
986
|
+
if (!config.alpn){
|
|
987
|
+
throw Error('Invalid alpn value.');
|
|
988
|
+
}
|
|
989
|
+
return ttsignal.__createServer__(config);
|
|
990
|
+
}
|
|
860
991
|
|
|
861
992
|
//*******************************************************************************
|
|
862
|
-
// Exports :
|
|
993
|
+
// Exports :
|
|
863
994
|
//*******************************************************************************
|
|
864
995
|
|
|
865
|
-
|
|
866
|
-
// module.exports = ttsignal;
|
|
867
|
-
exports.ttsignal = ttsignal;
|
|
996
|
+
module.exports = ttsignal;
|
|
868
997
|
|
|
869
998
|
//*******************************************************************************
|
|
870
999
|
// End of file : ttsignal.js
|