oox 0.3.3 → 0.3.4
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/bin/cli.js +40 -13
- package/bin/register.js +1 -1
- package/index.js +12 -7
- package/{rpc-keepalive-connection.js → keepalive-connection.js} +24 -17
- package/modules/socketio/adapter.js +7 -128
- package/modules/socketio/server.js +5 -24
- package/modules/socketio/utils.js +2 -1
- package/package.json +4 -2
- package/registry.js +61 -0
- package/samples/index.js +1 -0
- package/samples/keepalive-connection-sample.js +130 -0
- package/types/index.d.ts +15 -12
- package/types/keepalive-connection.d.ts +79 -0
- package/types/modules/socketio/adapter.d.ts +10 -24
- package/types/modules/socketio/server.d.ts +1 -7
- package/types/modules/socketio/utils.d.ts +2 -1
- package/types/registry.d.ts +16 -0
- package/types/samples/index.d.ts +1 -0
- package/types/samples/keepalive-connection-sample.d.ts +46 -0
- package/types/rpc-keepalive-connection.d.ts +0 -57
package/bin/cli.js
CHANGED
|
@@ -27,23 +27,26 @@ if (execFilename.endsWith('oox') || fileURLToPath(import.meta.url) === execFilen
|
|
|
27
27
|
console.log();
|
|
28
28
|
console.log(' oox entry.js port=8080');
|
|
29
29
|
console.log();
|
|
30
|
-
console.log(' oox
|
|
30
|
+
console.log(' oox entry.js group=app/ registry=:6000');
|
|
31
|
+
console.log(' oox app/entry/index.js group=app/ env=envs/prod.js ignore=core');
|
|
31
32
|
console.log();
|
|
32
33
|
console.log(chalk.bold('Params:'));
|
|
33
34
|
const params = [
|
|
34
|
-
['
|
|
35
|
-
['
|
|
36
|
-
['
|
|
37
|
-
['
|
|
38
|
-
['
|
|
39
|
-
['
|
|
40
|
-
['
|
|
41
|
-
['
|
|
42
|
-
['
|
|
43
|
-
['
|
|
44
|
-
['
|
|
35
|
+
['default-env', 'file', '.js or .json file, merge to oox.config'],
|
|
36
|
+
['env', 'file', `${chalk.bold.red('default-env')}.js or .json file, merge to oox.config, ${chalk.bold('(after default-env)')}`],
|
|
37
|
+
['port', 'int', `default is ${chalk.bold('0')}, for random port, or any integer > 0`],
|
|
38
|
+
['group', 'dir', 'service group directory, all LocalCall transform to RPC'],
|
|
39
|
+
['ignore', 'name', 'set a name for LocalCall do not transform to RPC, support string | array<string>'],
|
|
40
|
+
['http', 'json', 'HTTP server options, support flat name, ex: http.path=/api'],
|
|
41
|
+
['socketio', 'json', 'SocketIO server options, support flat name'],
|
|
42
|
+
['isRegistry', 'bool', `default is ${chalk.bold.red('true')}, set no to disable service registry`],
|
|
43
|
+
['registryAdapter', 'name', 'set service registry adapter name'],
|
|
44
|
+
['registry', 'urls', 'registry service url, support string | array<string>'],
|
|
45
|
+
['origin', 'urls', `set ${chalk.bold('*')}, allow any connections <Access-Control-Allow-Origin>`],
|
|
46
|
+
['errorStack', 'bool', 'set no to hidden error stack return'],
|
|
45
47
|
];
|
|
46
|
-
|
|
48
|
+
console.log(mergeCommandParams(params));
|
|
49
|
+
console.log(' ...', 'set params as', chalk.bold('foo=bar') + ',', 'usage as', chalk.bold('oox.config.foo'));
|
|
47
50
|
console.log();
|
|
48
51
|
}
|
|
49
52
|
if (isStartup) {
|
|
@@ -55,3 +58,27 @@ if (execFilename.endsWith('oox') || fileURLToPath(import.meta.url) === execFilen
|
|
|
55
58
|
await startup();
|
|
56
59
|
}
|
|
57
60
|
}
|
|
61
|
+
function mergeCommandParams(params) {
|
|
62
|
+
let result = '';
|
|
63
|
+
const perLinePrefix = ' '.repeat(2);
|
|
64
|
+
const nameMaxLength = 12;
|
|
65
|
+
const typeMaxLength = 6;
|
|
66
|
+
for (const param of params) {
|
|
67
|
+
const name = param[0];
|
|
68
|
+
const type = param[1];
|
|
69
|
+
const desc = param.slice(2).join(' ');
|
|
70
|
+
result += perLinePrefix + name;
|
|
71
|
+
if (name.length > nameMaxLength) {
|
|
72
|
+
result += '\n' + perLinePrefix;
|
|
73
|
+
result += ' '.repeat(nameMaxLength);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
result += ' '.repeat(nameMaxLength - name.length);
|
|
77
|
+
}
|
|
78
|
+
result += '[' + type + ']';
|
|
79
|
+
result += ' '.repeat(typeMaxLength - type.length);
|
|
80
|
+
result += desc;
|
|
81
|
+
result += '\n';
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
package/bin/register.js
CHANGED
|
@@ -2,7 +2,7 @@ import chalk from 'chalk';
|
|
|
2
2
|
import * as oox from '../index.js';
|
|
3
3
|
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
4
4
|
async function connect(url, prevError = null) {
|
|
5
|
-
const adapter = oox.
|
|
5
|
+
const adapter = oox.keepAliveConnectionAdapters.get(oox.config.registryAdapter);
|
|
6
6
|
try {
|
|
7
7
|
const connection = await adapter.open(url);
|
|
8
8
|
onConnection(connection, url);
|
package/index.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import * as app from './app.js';
|
|
3
3
|
import { getIPAddress } from './utils.js';
|
|
4
|
+
import * as registry from './registry.js';
|
|
4
5
|
import Module, { ModuleConfig } from './modules/module.js';
|
|
5
|
-
import
|
|
6
|
-
import { RPCKeepAliveConnection, rpcKeepAliveConnectionAdapters, keepAliveConnections, enabledKeepAliveConnections } from './rpc-keepalive-connection.js';
|
|
7
|
-
export { RPCKeepAliveConnection, rpcKeepAliveConnectionAdapters, keepAliveConnections, enabledKeepAliveConnections };
|
|
8
|
-
export { Module, ModuleConfig };
|
|
9
|
-
export const modules = new Modules;
|
|
10
|
-
export const { asyncStore, setMethods, getMethods, kvMethods, sourceKVMethods, call, execute, logger, on, once, off, emit, } = app;
|
|
6
|
+
import { KeepAliveConnection, keepAliveConnectionAdapters, keepAliveConnections, enabledKeepAliveConnections } from './keepalive-connection.js';
|
|
11
7
|
export class Context extends app.Context {
|
|
12
8
|
// 请求溯源IP
|
|
13
9
|
sourceIP = '';
|
|
@@ -49,6 +45,8 @@ export class Config {
|
|
|
49
45
|
origin = '';
|
|
50
46
|
// 默认返回错误调用栈信息信息
|
|
51
47
|
errorStack = true;
|
|
48
|
+
// 是否开启服务注册功能
|
|
49
|
+
isRegistry = true;
|
|
52
50
|
// 服务注册列表
|
|
53
51
|
registry = [];
|
|
54
52
|
// 服务注册适配器
|
|
@@ -120,7 +118,7 @@ export async function rpc(arg1, action, params, context) {
|
|
|
120
118
|
context = getContext();
|
|
121
119
|
}
|
|
122
120
|
let connection;
|
|
123
|
-
if (arg1 instanceof
|
|
121
|
+
if (arg1 instanceof KeepAliveConnection) {
|
|
124
122
|
connection = arg1;
|
|
125
123
|
}
|
|
126
124
|
else if ('string' === typeof arg1) {
|
|
@@ -132,3 +130,10 @@ export async function rpc(arg1, action, params, context) {
|
|
|
132
130
|
throw new Error(`Unknown rpc arg1<${arg1}>`);
|
|
133
131
|
return connection.adapter.rpc(connection, action, params, context);
|
|
134
132
|
}
|
|
133
|
+
export { KeepAliveConnection, keepAliveConnectionAdapters, keepAliveConnections, enabledKeepAliveConnections };
|
|
134
|
+
export { Module, ModuleConfig };
|
|
135
|
+
export { registry };
|
|
136
|
+
export const { asyncStore, setMethods, getMethods, kvMethods, sourceKVMethods, call, execute, logger, on, once, off, emit, } = app;
|
|
137
|
+
// 放在最后导入,解决循环依赖问题
|
|
138
|
+
import Modules from './modules/index.js';
|
|
139
|
+
export const modules = new Modules;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import EventEmitter from 'node:events';
|
|
2
|
-
export class
|
|
2
|
+
export class KeepAliveConnection extends EventEmitter {
|
|
3
3
|
// 连接是否可用
|
|
4
4
|
#enabled = false;
|
|
5
5
|
data;
|
|
@@ -9,8 +9,14 @@ export class RPCKeepAliveConnection extends EventEmitter {
|
|
|
9
9
|
super();
|
|
10
10
|
this.adapter = adapter;
|
|
11
11
|
this.nativeConnection = nativeConnection;
|
|
12
|
-
this.data = data
|
|
12
|
+
this.data = Object.assign(data, {
|
|
13
|
+
adapter: adapter.name,
|
|
14
|
+
});
|
|
13
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* 设置连接是否可用,并自动触发enabled或disabled事件
|
|
18
|
+
* @param enabled 是否可用
|
|
19
|
+
*/
|
|
14
20
|
set enabled(enabled) {
|
|
15
21
|
if (enabled !== this.#enabled) {
|
|
16
22
|
this.#enabled = enabled;
|
|
@@ -26,21 +32,22 @@ export class RPCKeepAliveConnection extends EventEmitter {
|
|
|
26
32
|
get enabled() {
|
|
27
33
|
return this.#enabled;
|
|
28
34
|
}
|
|
29
|
-
|
|
35
|
+
/**
|
|
36
|
+
* enable & mount connection
|
|
37
|
+
* @param params
|
|
38
|
+
* @returns
|
|
39
|
+
*/
|
|
40
|
+
ready(params) {
|
|
41
|
+
// 连接已就绪,不允许重复就绪
|
|
42
|
+
if (this.enabled)
|
|
43
|
+
return;
|
|
44
|
+
const { id, name } = params;
|
|
30
45
|
keepAliveConnections.remove(this);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
updateName(newName) {
|
|
35
|
-
keepAliveConnections.remove(this);
|
|
36
|
-
this.data.name = newName;
|
|
37
|
-
keepAliveConnections.add(this);
|
|
38
|
-
}
|
|
39
|
-
updateIdAndName(newId, newName) {
|
|
40
|
-
keepAliveConnections.remove(this);
|
|
41
|
-
this.data.id = newId;
|
|
42
|
-
this.data.name = newName;
|
|
46
|
+
// 更新连接数据
|
|
47
|
+
this.data.id = id;
|
|
48
|
+
this.data.name = name;
|
|
43
49
|
keepAliveConnections.add(this);
|
|
50
|
+
this.enabled = true;
|
|
44
51
|
}
|
|
45
52
|
}
|
|
46
53
|
export class KeepAliveConnectionStore {
|
|
@@ -74,7 +81,7 @@ export class KeepAliveConnectionStore {
|
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
83
|
remove(name, id) {
|
|
77
|
-
if (name instanceof
|
|
84
|
+
if (name instanceof KeepAliveConnection) {
|
|
78
85
|
id = name.data.id;
|
|
79
86
|
name = name.data.name;
|
|
80
87
|
}
|
|
@@ -84,6 +91,6 @@ export class KeepAliveConnectionStore {
|
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
}
|
|
87
|
-
export const
|
|
94
|
+
export const keepAliveConnectionAdapters = new Map();
|
|
88
95
|
export const keepAliveConnections = new KeepAliveConnectionStore();
|
|
89
96
|
export const enabledKeepAliveConnections = new KeepAliveConnectionStore();
|
|
@@ -1,50 +1,12 @@
|
|
|
1
1
|
import * as SocketIOClient from 'socket.io-client';
|
|
2
2
|
import * as oox from '../../index.js';
|
|
3
|
-
import { OOXEvent, genWebSocketURL
|
|
3
|
+
import { OOXEvent, genWebSocketURL } from './utils.js';
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
[OOXEvent.SYNC_CONNECTIONS](datas) {
|
|
11
|
-
for (const data of datas) {
|
|
12
|
-
if (data.name === oox.config.name)
|
|
13
|
-
continue;
|
|
14
|
-
if (!data.url || !isWebSocketURL(data.url))
|
|
15
|
-
continue;
|
|
16
|
-
const has = oox.keepAliveConnections.has(data.name, data.id);
|
|
17
|
-
if (has)
|
|
18
|
-
continue;
|
|
19
|
-
this.open(data.url).catch((error) => console.error(error));
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
bindClientConnectionEvents(connection) {
|
|
23
|
-
const socket = connection.nativeConnection;
|
|
24
|
-
socket.on(OOXEvent.CONNECTED, ({ id, name }) => {
|
|
25
|
-
connection.updateIdAndName(id, name);
|
|
26
|
-
connection.enabled = true;
|
|
27
|
-
socket.emit(OOXEvent.SYNC_CONNECTIONS, this[OOXEvent.SYNC_CONNECTIONS].bind(this));
|
|
28
|
-
});
|
|
29
|
-
socket.on(OOXEvent.DISABLED, () => {
|
|
30
|
-
connection.enabled = false;
|
|
31
|
-
});
|
|
32
|
-
socket.on('disconnect', (reason) => {
|
|
33
|
-
connection.emit('disconnect');
|
|
34
|
-
oox.removeKeepAliveConnection(connection);
|
|
35
|
-
socket.removeAllListeners();
|
|
36
|
-
socket.disconnect();
|
|
37
|
-
});
|
|
38
|
-
socket.on('connect', () => {
|
|
39
|
-
connection.emit('connect');
|
|
40
|
-
});
|
|
41
|
-
socket.on('connect_error', (error) => {
|
|
42
|
-
connection.emit('error', error);
|
|
43
|
-
oox.removeKeepAliveConnection(connection);
|
|
44
|
-
socket.removeAllListeners();
|
|
45
|
-
socket.disconnect();
|
|
46
|
-
});
|
|
47
|
-
}
|
|
5
|
+
import { SampleKeepAliveConnectionAdapter } from '../../samples/index.js';
|
|
6
|
+
export default class SocketIOAdapter extends SampleKeepAliveConnectionAdapter {
|
|
7
|
+
name = 'socketio';
|
|
8
|
+
OOXEvent = OOXEvent;
|
|
9
|
+
nativeEvent = { CONNECT: 'connect', DISCONNECT: 'disconnect', ERROR: 'connect_error' };
|
|
48
10
|
newConnection(url) {
|
|
49
11
|
const { id, host, name } = oox.config;
|
|
50
12
|
const headers = {
|
|
@@ -64,95 +26,12 @@ export default class SocketIOAdapter {
|
|
|
64
26
|
path: mURL.pathname,
|
|
65
27
|
autoConnect: false,
|
|
66
28
|
});
|
|
67
|
-
const
|
|
29
|
+
const connection = new oox.KeepAliveConnection(this, socket, {
|
|
68
30
|
name: 'anonymous',
|
|
69
31
|
id: randomUUID(),
|
|
70
32
|
host: mURL.host,
|
|
71
33
|
url: mURL
|
|
72
|
-
};
|
|
73
|
-
const connection = new oox.RPCKeepAliveConnection(this, socket, data);
|
|
74
|
-
return connection;
|
|
75
|
-
}
|
|
76
|
-
async open(url) {
|
|
77
|
-
const connection = this.newConnection(url);
|
|
78
|
-
oox.addKeepAliveConnection(connection);
|
|
79
|
-
this.bindClientConnectionEvents(connection);
|
|
80
|
-
this.bindCall(connection);
|
|
81
|
-
await new Promise((resolve, reject) => {
|
|
82
|
-
connection.once('enabled', resolve);
|
|
83
|
-
connection.once('error', reject);
|
|
84
|
-
connection.once('disconnect', () => {
|
|
85
|
-
reject(new Error('disconnect'));
|
|
86
|
-
});
|
|
87
|
-
connection.nativeConnection.connect();
|
|
88
34
|
});
|
|
89
35
|
return connection;
|
|
90
36
|
}
|
|
91
|
-
async close(connection) {
|
|
92
|
-
connection.nativeConnection.disconnect();
|
|
93
|
-
return Promise.resolve();
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* socketio emit
|
|
97
|
-
*/
|
|
98
|
-
async emit(socket, event, params) {
|
|
99
|
-
if (!socket.connected)
|
|
100
|
-
throw new Error('Socket not connected');
|
|
101
|
-
return await new Promise((resolve, reject) => {
|
|
102
|
-
const onError = (reason) => {
|
|
103
|
-
const message = 'string' === typeof reason ? reason : reason instanceof Error ? reason.message : 'connect error';
|
|
104
|
-
reject(new Error(message));
|
|
105
|
-
};
|
|
106
|
-
// RPC 执行时中断连接
|
|
107
|
-
socket.once('disconnect', onError);
|
|
108
|
-
socket.emit(event, ...params, (returns) => {
|
|
109
|
-
socket.offAny(onError);
|
|
110
|
-
resolve(returns);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* RPC
|
|
116
|
-
*/
|
|
117
|
-
async rpc(connection, action, params, context) {
|
|
118
|
-
if (!context)
|
|
119
|
-
context = oox.getContext();
|
|
120
|
-
const { success, error, body } = await this.emit(connection.nativeConnection, 'call', [action, params, context]);
|
|
121
|
-
if (success)
|
|
122
|
-
return body;
|
|
123
|
-
else if (error)
|
|
124
|
-
throw new Error(error.message);
|
|
125
|
-
else
|
|
126
|
-
throw new Error('[RPC] Unknown Error');
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* 绑定 call 事件
|
|
130
|
-
* @param connection
|
|
131
|
-
*/
|
|
132
|
-
bindCall(connection) {
|
|
133
|
-
const { id, name, host } = connection.data;
|
|
134
|
-
const connectionContext = {
|
|
135
|
-
sourceIP: '',
|
|
136
|
-
ip: host,
|
|
137
|
-
caller: name,
|
|
138
|
-
callerId: id,
|
|
139
|
-
connection
|
|
140
|
-
};
|
|
141
|
-
connection.nativeConnection.on('call', async (action, params, context, callback) => {
|
|
142
|
-
if ('object' !== typeof context)
|
|
143
|
-
context = oox.genContext(connectionContext);
|
|
144
|
-
else
|
|
145
|
-
context = oox.genContext(Object.assign(context, connectionContext));
|
|
146
|
-
this.call(action, params, context, callback);
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
async call(action, params, context, callback) {
|
|
150
|
-
const returns = await oox.call(action, params, context);
|
|
151
|
-
if (returns.error && !oox.config.errorStack) {
|
|
152
|
-
// 不返回错误调用栈信息
|
|
153
|
-
delete returns.error.stack;
|
|
154
|
-
}
|
|
155
|
-
'function' === typeof callback && callback(returns);
|
|
156
|
-
return returns;
|
|
157
|
-
}
|
|
158
37
|
}
|
|
@@ -4,7 +4,7 @@ import { Server } from 'socket.io';
|
|
|
4
4
|
import * as oox from '../../index.js';
|
|
5
5
|
import { Module, ModuleConfig } from '../../index.js';
|
|
6
6
|
import SocketIOAdapter from './adapter.js';
|
|
7
|
-
import {
|
|
7
|
+
import { OOXEvent } from './utils.js';
|
|
8
8
|
export class SocketIOConfig extends ModuleConfig {
|
|
9
9
|
// listen port
|
|
10
10
|
port = 0;
|
|
@@ -53,7 +53,7 @@ export default class SocketIOServer extends Module {
|
|
|
53
53
|
return this.config;
|
|
54
54
|
}
|
|
55
55
|
async serve() {
|
|
56
|
-
oox.
|
|
56
|
+
oox.keepAliveConnectionAdapters.set(this.name, this.adapter);
|
|
57
57
|
await this.stop();
|
|
58
58
|
const { port, ssl } = this.config;
|
|
59
59
|
const isSelfServer = this.#isSelfServer = this.server ? true : false;
|
|
@@ -148,7 +148,7 @@ export default class SocketIOServer extends Module {
|
|
|
148
148
|
const ip = String(headers['x-real-ip'] || headers['x-ip'] || socket.handshake.address);
|
|
149
149
|
// service name
|
|
150
150
|
const caller = String(headers['x-caller'] || 'anonymous');
|
|
151
|
-
const connection = new oox.
|
|
151
|
+
const connection = new oox.KeepAliveConnection(this.adapter, socket, {
|
|
152
152
|
host: ip,
|
|
153
153
|
name: caller,
|
|
154
154
|
id: callerId,
|
|
@@ -157,29 +157,11 @@ export default class SocketIOServer extends Module {
|
|
|
157
157
|
this.bindServerConnectionEvents(connection);
|
|
158
158
|
this.adapter.bindCall(connection);
|
|
159
159
|
connection.enabled = true;
|
|
160
|
-
socket.emit(OOXEvent.
|
|
160
|
+
socket.emit(OOXEvent.READY, {
|
|
161
161
|
id: oox.config.id,
|
|
162
162
|
name: oox.config.name
|
|
163
163
|
});
|
|
164
164
|
}
|
|
165
|
-
/**
|
|
166
|
-
* 服务器发送连接列表
|
|
167
|
-
* @param connection
|
|
168
|
-
*/
|
|
169
|
-
[OOXEvent.SYNC_CONNECTIONS](connection) {
|
|
170
|
-
const socket = connection.nativeConnection;
|
|
171
|
-
const datas = [];
|
|
172
|
-
for (const [name, connections] of oox.enabledKeepAliveConnections.entries()) {
|
|
173
|
-
if (name === connection.data.name)
|
|
174
|
-
continue;
|
|
175
|
-
for (const conn of Array.from(connections.values())) {
|
|
176
|
-
if (!conn.data.url || !isWebSocketURL(conn.data.url))
|
|
177
|
-
continue;
|
|
178
|
-
datas.push(conn.data);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
return datas;
|
|
182
|
-
}
|
|
183
165
|
/**
|
|
184
166
|
* 绑定服务器连接事件
|
|
185
167
|
* @param connection
|
|
@@ -189,8 +171,7 @@ export default class SocketIOServer extends Module {
|
|
|
189
171
|
socket.on(OOXEvent.SYNC_CONNECTIONS, async (fn) => {
|
|
190
172
|
if ('function' !== typeof fn)
|
|
191
173
|
return;
|
|
192
|
-
|
|
193
|
-
fn(datas);
|
|
174
|
+
oox.registry.onSyncConnections(connection, {}, fn);
|
|
194
175
|
});
|
|
195
176
|
socket.on('disconnecting', (reason) => {
|
|
196
177
|
oox.removeKeepAliveConnection(connection);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export var OOXEvent;
|
|
2
2
|
(function (OOXEvent) {
|
|
3
|
-
OOXEvent["
|
|
3
|
+
OOXEvent["READY"] = "oox:ready";
|
|
4
|
+
OOXEvent["ENABLED"] = "oox:enabled";
|
|
4
5
|
OOXEvent["DISABLED"] = "oox:disabled";
|
|
5
6
|
OOXEvent["SYNC_CONNECTIONS"] = "oox:sync_connections";
|
|
6
7
|
})(OOXEvent || (OOXEvent = {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oox",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "OOX Service Engine",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"http",
|
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
"types": "./types/index.d.ts"
|
|
23
23
|
},
|
|
24
24
|
"./loader": "./bin/loader.mjs",
|
|
25
|
-
"./cli": "./bin/cli.js"
|
|
25
|
+
"./cli": "./bin/cli.js",
|
|
26
|
+
"./samples": "./samples/index.js",
|
|
27
|
+
"./samples/types": "./types/samples/index.d.ts"
|
|
26
28
|
},
|
|
27
29
|
"bin": {
|
|
28
30
|
"oox": "./bin/cli.js"
|
package/registry.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { config } from './index.js';
|
|
2
|
+
import { enabledKeepAliveConnections, keepAliveConnectionAdapters, keepAliveConnections } from './keepalive-connection.js';
|
|
3
|
+
/**
|
|
4
|
+
* 服务器发送连接列表
|
|
5
|
+
* @param connection
|
|
6
|
+
* @param query
|
|
7
|
+
* @param callback
|
|
8
|
+
*/
|
|
9
|
+
export function onSyncConnections(connection, query, callback) {
|
|
10
|
+
// 检查是否开启服务注册功能
|
|
11
|
+
if (!config.isRegistry)
|
|
12
|
+
return callback([]);
|
|
13
|
+
const datas = [];
|
|
14
|
+
if (query.name) {
|
|
15
|
+
const names = Array.isArray(query.name) ? query.name : [query.name];
|
|
16
|
+
for (const [name, connections] of enabledKeepAliveConnections.entries()) {
|
|
17
|
+
if (names.includes(name))
|
|
18
|
+
continue;
|
|
19
|
+
for (const conn of Array.from(connections.values())) {
|
|
20
|
+
if (!conn.data.url)
|
|
21
|
+
continue;
|
|
22
|
+
datas.push(conn.data);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
for (const [name, connections] of enabledKeepAliveConnections.entries()) {
|
|
28
|
+
if (name === connection.data.name)
|
|
29
|
+
continue;
|
|
30
|
+
for (const conn of Array.from(connections.values())) {
|
|
31
|
+
if (!conn.data.url)
|
|
32
|
+
continue;
|
|
33
|
+
datas.push(conn.data);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
callback(datas);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 同步连接列表
|
|
41
|
+
* @param datas 连接参数列表
|
|
42
|
+
*/
|
|
43
|
+
export function syncConnections(datas) {
|
|
44
|
+
for (const data of datas) {
|
|
45
|
+
// 获取适配器
|
|
46
|
+
const adapter = keepAliveConnectionAdapters.get(data.adapter);
|
|
47
|
+
if (!adapter)
|
|
48
|
+
continue;
|
|
49
|
+
// 忽略自己
|
|
50
|
+
if (data.name === config.name)
|
|
51
|
+
continue;
|
|
52
|
+
// 忽略无效URL
|
|
53
|
+
if (!data.url)
|
|
54
|
+
continue;
|
|
55
|
+
// 忽略已存在连接
|
|
56
|
+
if (keepAliveConnections.has(data.name, data.id))
|
|
57
|
+
continue;
|
|
58
|
+
// 建立连接
|
|
59
|
+
adapter.open(data.url).catch((error) => console.error(error));
|
|
60
|
+
}
|
|
61
|
+
}
|
package/samples/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SampleKeepAliveConnectionAdapter } from './keepalive-connection-sample.js';
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import * as oox from '../index.js';
|
|
2
|
+
export class SampleKeepAliveConnectionAdapter {
|
|
3
|
+
name;
|
|
4
|
+
OOXEvent = {
|
|
5
|
+
READY: 'oox:ready',
|
|
6
|
+
ENABLED: 'oox:enabled',
|
|
7
|
+
DISABLED: 'oox:disabled',
|
|
8
|
+
SYNC_CONNECTIONS: 'oox:sync_connections',
|
|
9
|
+
};
|
|
10
|
+
nativeEvent = {
|
|
11
|
+
CONNECT: 'connect',
|
|
12
|
+
DISCONNECT: 'disconnect',
|
|
13
|
+
ERROR: 'error',
|
|
14
|
+
};
|
|
15
|
+
bindConnectionEvents(connection) {
|
|
16
|
+
const socket = connection.nativeConnection;
|
|
17
|
+
socket.on(this.OOXEvent.READY, (params) => {
|
|
18
|
+
connection.ready(params);
|
|
19
|
+
socket.emit(this.OOXEvent.SYNC_CONNECTIONS, oox.registry.syncConnections);
|
|
20
|
+
});
|
|
21
|
+
socket.on(this.OOXEvent.ENABLED, () => {
|
|
22
|
+
connection.enabled = true;
|
|
23
|
+
});
|
|
24
|
+
socket.on(this.OOXEvent.DISABLED, () => {
|
|
25
|
+
connection.enabled = false;
|
|
26
|
+
});
|
|
27
|
+
socket.on(this.nativeEvent.DISCONNECT, (reason) => {
|
|
28
|
+
connection.emit('disconnect');
|
|
29
|
+
oox.removeKeepAliveConnection(connection);
|
|
30
|
+
socket.removeAllListeners();
|
|
31
|
+
socket.disconnect();
|
|
32
|
+
});
|
|
33
|
+
socket.on(this.nativeEvent.CONNECT, () => {
|
|
34
|
+
connection.emit('connect');
|
|
35
|
+
});
|
|
36
|
+
socket.on(this.nativeEvent.ERROR, (error) => {
|
|
37
|
+
connection.emit('error', error);
|
|
38
|
+
oox.removeKeepAliveConnection(connection);
|
|
39
|
+
socket.removeAllListeners();
|
|
40
|
+
socket.disconnect();
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
async open(url) {
|
|
44
|
+
const connection = this.newConnection(url);
|
|
45
|
+
oox.addKeepAliveConnection(connection);
|
|
46
|
+
this.bindConnectionEvents(connection);
|
|
47
|
+
this.bindCall(connection);
|
|
48
|
+
await new Promise((resolve, reject) => {
|
|
49
|
+
connection.once('enabled', resolve);
|
|
50
|
+
connection.once('error', reject);
|
|
51
|
+
connection.once('disconnect', () => {
|
|
52
|
+
reject(new Error('disconnect'));
|
|
53
|
+
});
|
|
54
|
+
if (connection.nativeConnection.connect) {
|
|
55
|
+
connection.nativeConnection.connect();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return connection;
|
|
59
|
+
}
|
|
60
|
+
async close(connection) {
|
|
61
|
+
connection.nativeConnection.disconnect();
|
|
62
|
+
return Promise.resolve();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 发送事件
|
|
66
|
+
* @param socket
|
|
67
|
+
* @param event
|
|
68
|
+
* @param params
|
|
69
|
+
*/
|
|
70
|
+
async emit(socket, event, params) {
|
|
71
|
+
if (!socket.connected)
|
|
72
|
+
throw new Error('Socket not connected');
|
|
73
|
+
return await new Promise((resolve, reject) => {
|
|
74
|
+
const onError = (reason) => {
|
|
75
|
+
const message = 'string' === typeof reason ? reason : reason instanceof Error ? reason.message : 'connect error';
|
|
76
|
+
reject(new Error(message));
|
|
77
|
+
};
|
|
78
|
+
// RPC 执行时中断连接
|
|
79
|
+
socket.once(this.nativeEvent.DISCONNECT, onError);
|
|
80
|
+
socket.emit(event, ...params, (returns) => {
|
|
81
|
+
socket.off(this.nativeEvent.DISCONNECT, onError);
|
|
82
|
+
resolve(returns);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* RPC
|
|
88
|
+
*/
|
|
89
|
+
async rpc(connection, action, params, context) {
|
|
90
|
+
if (!context)
|
|
91
|
+
context = oox.getContext();
|
|
92
|
+
const { success, error, body } = await this.emit(connection.nativeConnection, 'call', [action, params, context]);
|
|
93
|
+
if (success)
|
|
94
|
+
return body;
|
|
95
|
+
else if (error)
|
|
96
|
+
throw new Error(error.message);
|
|
97
|
+
else
|
|
98
|
+
throw new Error('[RPC] Unknown Error');
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 绑定 call 事件
|
|
102
|
+
* @param connection
|
|
103
|
+
*/
|
|
104
|
+
bindCall(connection) {
|
|
105
|
+
const { id, name, host } = connection.data;
|
|
106
|
+
const connectionContext = {
|
|
107
|
+
sourceIP: '',
|
|
108
|
+
ip: host,
|
|
109
|
+
caller: name,
|
|
110
|
+
callerId: id,
|
|
111
|
+
connection
|
|
112
|
+
};
|
|
113
|
+
connection.nativeConnection.on('call', async (action, params, context, callback) => {
|
|
114
|
+
if ('object' !== typeof context)
|
|
115
|
+
context = oox.genContext(connectionContext);
|
|
116
|
+
else
|
|
117
|
+
context = oox.genContext(Object.assign(context, connectionContext));
|
|
118
|
+
this.call(action, params, context, callback);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
async call(action, params, context, callback) {
|
|
122
|
+
const returns = await oox.call(action, params, context);
|
|
123
|
+
if (returns.error && !oox.config.errorStack) {
|
|
124
|
+
// 不返回错误调用栈信息
|
|
125
|
+
delete returns.error.stack;
|
|
126
|
+
}
|
|
127
|
+
'function' === typeof callback && callback(returns);
|
|
128
|
+
return returns;
|
|
129
|
+
}
|
|
130
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import * as app from './app.js';
|
|
2
|
+
import * as registry from './registry.js';
|
|
2
3
|
import Module, { ModuleConfig } from './modules/module.js';
|
|
3
|
-
import
|
|
4
|
-
import { RPCKeepAliveConnectionAdapter, RPCKeepAliveConnection, RPCKeepAliveConnectionData, rpcKeepAliveConnectionAdapters, keepAliveConnections, enabledKeepAliveConnections } from './rpc-keepalive-connection.js';
|
|
5
|
-
export { RPCKeepAliveConnectionAdapter, RPCKeepAliveConnection, RPCKeepAliveConnectionData, rpcKeepAliveConnectionAdapters, keepAliveConnections, enabledKeepAliveConnections };
|
|
6
|
-
export { ReturnsBody } from './app.js';
|
|
7
|
-
export { Module, ModuleConfig };
|
|
8
|
-
export declare const modules: Modules;
|
|
9
|
-
export declare const asyncStore: import("async_hooks").AsyncLocalStorage<app.Context>, setMethods: typeof app.setMethods, getMethods: typeof app.getMethods, kvMethods: Map<string, Function>, sourceKVMethods: Map<string, Function>, call: typeof app.call, execute: typeof app.execute, logger: typeof app.logger, on: typeof app.on, once: typeof app.once, off: typeof app.off, emit: typeof app.emit;
|
|
4
|
+
import { KeepAliveConnectionReadyParams, KeepAliveConnectionAdapter, KeepAliveConnection, KeepAliveConnectionData, keepAliveConnectionAdapters, keepAliveConnections, enabledKeepAliveConnections } from './keepalive-connection.js';
|
|
10
5
|
export declare class Context extends app.Context {
|
|
11
6
|
sourceIP: string;
|
|
12
7
|
ip: string;
|
|
13
8
|
caller: string;
|
|
14
9
|
callerId: string;
|
|
15
|
-
connection?:
|
|
10
|
+
connection?: KeepAliveConnection<any>;
|
|
16
11
|
toJSON?(): {} & this;
|
|
17
12
|
}
|
|
18
13
|
export declare class Config {
|
|
@@ -29,6 +24,7 @@ export declare class Config {
|
|
|
29
24
|
port: number;
|
|
30
25
|
origin: string | string[];
|
|
31
26
|
errorStack: boolean;
|
|
27
|
+
isRegistry: boolean;
|
|
32
28
|
registry: string[];
|
|
33
29
|
registryAdapter: string;
|
|
34
30
|
}
|
|
@@ -45,9 +41,16 @@ export declare function genContext(context?: Context): Context;
|
|
|
45
41
|
export declare function getContext(): Context;
|
|
46
42
|
export declare function serve(): Promise<void>;
|
|
47
43
|
export declare function stop(): Promise<void>;
|
|
48
|
-
export declare function addKeepAliveConnection(connection:
|
|
49
|
-
export declare function removeKeepAliveConnection(connection:
|
|
44
|
+
export declare function addKeepAliveConnection(connection: KeepAliveConnection<any>): void;
|
|
45
|
+
export declare function removeKeepAliveConnection(connection: KeepAliveConnection<any>): void;
|
|
50
46
|
export declare function removeKeepAliveConnection(name: string, id: string): void;
|
|
51
|
-
export declare function setLoadBalancePolicy(policy: (name: string) =>
|
|
47
|
+
export declare function setLoadBalancePolicy(policy: (name: string) => KeepAliveConnection<any>): void;
|
|
52
48
|
export declare function rpc(appName: string, action: string, params: any[], context?: Context): Promise<any>;
|
|
53
|
-
export declare function rpc(connection:
|
|
49
|
+
export declare function rpc(connection: KeepAliveConnection<any>, action: string, params: any[], context?: Context): Promise<any>;
|
|
50
|
+
export { KeepAliveConnectionReadyParams, KeepAliveConnectionAdapter, KeepAliveConnection, KeepAliveConnectionData, keepAliveConnectionAdapters, keepAliveConnections, enabledKeepAliveConnections };
|
|
51
|
+
export { ReturnsBody } from './app.js';
|
|
52
|
+
export { Module, ModuleConfig };
|
|
53
|
+
export { registry };
|
|
54
|
+
export declare const asyncStore: import("async_hooks").AsyncLocalStorage<app.Context>, setMethods: typeof app.setMethods, getMethods: typeof app.getMethods, kvMethods: Map<string, Function>, sourceKVMethods: Map<string, Function>, call: typeof app.call, execute: typeof app.execute, logger: typeof app.logger, on: typeof app.on, once: typeof app.once, off: typeof app.off, emit: typeof app.emit;
|
|
55
|
+
import Modules from './modules/index.js';
|
|
56
|
+
export declare const modules: Modules;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import EventEmitter from 'node:events';
|
|
2
|
+
import { Context } from './index.js';
|
|
3
|
+
type MakeOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
4
|
+
export interface KeepAliveConnectionAdapter<T> {
|
|
5
|
+
/**
|
|
6
|
+
* 连接适配器名称
|
|
7
|
+
*/
|
|
8
|
+
name: string;
|
|
9
|
+
open(url: string | URL): Promise<KeepAliveConnection<T>>;
|
|
10
|
+
close(connection: KeepAliveConnection<T>): Promise<void>;
|
|
11
|
+
rpc(connection: KeepAliveConnection<T>, action: string, params: any[], context: Context): Promise<any>;
|
|
12
|
+
}
|
|
13
|
+
export interface KeepAliveConnectionData {
|
|
14
|
+
/**
|
|
15
|
+
* 连接适配器名称
|
|
16
|
+
*/
|
|
17
|
+
adapter: string;
|
|
18
|
+
/**
|
|
19
|
+
* 连接主机地址
|
|
20
|
+
*/
|
|
21
|
+
host: string;
|
|
22
|
+
/**
|
|
23
|
+
* 连接服务名称
|
|
24
|
+
*/
|
|
25
|
+
name: string;
|
|
26
|
+
/**
|
|
27
|
+
* 连接URL
|
|
28
|
+
*/
|
|
29
|
+
url?: string | URL;
|
|
30
|
+
/**
|
|
31
|
+
* 目标服务网络唯一ID
|
|
32
|
+
*/
|
|
33
|
+
id: string;
|
|
34
|
+
}
|
|
35
|
+
export interface KeepAliveConnectionReadyParams {
|
|
36
|
+
[x: string]: any;
|
|
37
|
+
id: KeepAliveConnectionData['id'];
|
|
38
|
+
name: KeepAliveConnectionData['name'];
|
|
39
|
+
}
|
|
40
|
+
export type KeepAliveConnectionEventMap = Record<keyof {
|
|
41
|
+
"enabled": any;
|
|
42
|
+
"disabled": any;
|
|
43
|
+
"connect": any;
|
|
44
|
+
"disconnect": any;
|
|
45
|
+
'error': any;
|
|
46
|
+
}, any[]>;
|
|
47
|
+
export declare class KeepAliveConnection<T> extends EventEmitter<KeepAliveConnectionEventMap> {
|
|
48
|
+
#private;
|
|
49
|
+
data: KeepAliveConnectionData;
|
|
50
|
+
nativeConnection: T;
|
|
51
|
+
adapter: KeepAliveConnectionAdapter<T>;
|
|
52
|
+
constructor(adapter: KeepAliveConnectionAdapter<T>, nativeConnection: T, data: MakeOptional<KeepAliveConnectionData, 'adapter'>);
|
|
53
|
+
/**
|
|
54
|
+
* 设置连接是否可用,并自动触发enabled或disabled事件
|
|
55
|
+
* @param enabled 是否可用
|
|
56
|
+
*/
|
|
57
|
+
set enabled(enabled: boolean);
|
|
58
|
+
get enabled(): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* enable & mount connection
|
|
61
|
+
* @param params
|
|
62
|
+
* @returns
|
|
63
|
+
*/
|
|
64
|
+
ready(params: KeepAliveConnectionReadyParams): void;
|
|
65
|
+
}
|
|
66
|
+
export declare class KeepAliveConnectionStore<T> {
|
|
67
|
+
#private;
|
|
68
|
+
entries(): MapIterator<[string, Map<string, KeepAliveConnection<T>>]>;
|
|
69
|
+
getConnectionsOfService(name: string): Map<string, KeepAliveConnection<T>>;
|
|
70
|
+
has(name: string, id: string): boolean;
|
|
71
|
+
get(name: string, id: string): KeepAliveConnection<T> | null;
|
|
72
|
+
add(connection: KeepAliveConnection<T>): void;
|
|
73
|
+
remove(connection: KeepAliveConnection<T>): void;
|
|
74
|
+
remove(name: string, id: string): void;
|
|
75
|
+
}
|
|
76
|
+
export declare const keepAliveConnectionAdapters: Map<string, KeepAliveConnectionAdapter<any>>;
|
|
77
|
+
export declare const keepAliveConnections: KeepAliveConnectionStore<any>;
|
|
78
|
+
export declare const enabledKeepAliveConnections: KeepAliveConnectionStore<any>;
|
|
79
|
+
export {};
|
|
@@ -1,28 +1,14 @@
|
|
|
1
1
|
import * as oox from '../../index.js';
|
|
2
2
|
import { Socket } from './socket.js';
|
|
3
3
|
import { OOXEvent } from './utils.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* socketio emit
|
|
16
|
-
*/
|
|
17
|
-
emit(socket: Socket, event: string, params: any[]): Promise<unknown>;
|
|
18
|
-
/**
|
|
19
|
-
* RPC
|
|
20
|
-
*/
|
|
21
|
-
rpc(connection: oox.RPCKeepAliveConnection<Socket>, action: string, params: [], context?: oox.Context): Promise<any>;
|
|
22
|
-
/**
|
|
23
|
-
* 绑定 call 事件
|
|
24
|
-
* @param connection
|
|
25
|
-
*/
|
|
26
|
-
bindCall(connection: oox.RPCKeepAliveConnection<Socket>): void;
|
|
27
|
-
call(action: string, params: any[], context: oox.Context, callback?: (returns: any) => void): Promise<oox.ReturnsBody>;
|
|
4
|
+
import { SampleKeepAliveConnectionAdapter } from '../../samples/index.js';
|
|
5
|
+
export default class SocketIOAdapter extends SampleKeepAliveConnectionAdapter<Socket> {
|
|
6
|
+
name: string;
|
|
7
|
+
OOXEvent: typeof OOXEvent;
|
|
8
|
+
nativeEvent: {
|
|
9
|
+
CONNECT: string;
|
|
10
|
+
DISCONNECT: string;
|
|
11
|
+
ERROR: string;
|
|
12
|
+
};
|
|
13
|
+
newConnection(url: string | URL): oox.KeepAliveConnection<Socket>;
|
|
28
14
|
}
|
|
@@ -5,7 +5,6 @@ import * as oox from '../../index.js';
|
|
|
5
5
|
import { Module, ModuleConfig } from '../../index.js';
|
|
6
6
|
import { Socket } from './socket.js';
|
|
7
7
|
import SocketIOAdapter from './adapter.js';
|
|
8
|
-
import { OOXEvent } from './utils.js';
|
|
9
8
|
export declare class SocketIOConfig extends ModuleConfig {
|
|
10
9
|
port: number;
|
|
11
10
|
path: string;
|
|
@@ -35,14 +34,9 @@ export default class SocketIOServer extends Module {
|
|
|
35
34
|
* 服务端Socket连接事件
|
|
36
35
|
*/
|
|
37
36
|
serverOnSocketConnection(socket: Socket<'server'>): void;
|
|
38
|
-
/**
|
|
39
|
-
* 服务器发送连接列表
|
|
40
|
-
* @param connection
|
|
41
|
-
*/
|
|
42
|
-
[OOXEvent.SYNC_CONNECTIONS](connection: oox.RPCKeepAliveConnection<Socket<'server'>>): oox.RPCKeepAliveConnectionData[];
|
|
43
37
|
/**
|
|
44
38
|
* 绑定服务器连接事件
|
|
45
39
|
* @param connection
|
|
46
40
|
*/
|
|
47
|
-
bindServerConnectionEvents(connection: oox.
|
|
41
|
+
bindServerConnectionEvents(connection: oox.KeepAliveConnection<Socket<'server'>>): void;
|
|
48
42
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { KeepAliveConnection, KeepAliveConnectionData } from './keepalive-connection.js';
|
|
2
|
+
export interface SyncConnectionsQuery {
|
|
3
|
+
name?: string | string[];
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* 服务器发送连接列表
|
|
7
|
+
* @param connection
|
|
8
|
+
* @param query
|
|
9
|
+
* @param callback
|
|
10
|
+
*/
|
|
11
|
+
export declare function onSyncConnections(connection: KeepAliveConnection<any>, query: SyncConnectionsQuery, callback: (datas: KeepAliveConnectionData[]) => void): void;
|
|
12
|
+
/**
|
|
13
|
+
* 同步连接列表
|
|
14
|
+
* @param datas 连接参数列表
|
|
15
|
+
*/
|
|
16
|
+
export declare function syncConnections(datas: KeepAliveConnectionData[]): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SampleKeepAliveConnectionAdapter, SampleKeepAliveNativeConnection } from './keepalive-connection-sample.js';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as oox from '../index.js';
|
|
2
|
+
export interface SampleKeepAliveNativeConnection {
|
|
3
|
+
connected: boolean;
|
|
4
|
+
connect?(): void;
|
|
5
|
+
disconnect(): void;
|
|
6
|
+
on(event: string | symbol, listener: (...args: any[]) => void): any;
|
|
7
|
+
once(event: string | symbol, listener: (...args: any[]) => void): any;
|
|
8
|
+
off(event: string | symbol, listener?: (...args: any[]) => void): any;
|
|
9
|
+
emit(event: string | symbol, ...args: any[]): any;
|
|
10
|
+
removeAllListeners(event?: string | symbol): any;
|
|
11
|
+
}
|
|
12
|
+
export declare abstract class SampleKeepAliveConnectionAdapter<NativeConnection extends SampleKeepAliveNativeConnection> implements oox.KeepAliveConnectionAdapter<NativeConnection> {
|
|
13
|
+
name: string;
|
|
14
|
+
OOXEvent: {
|
|
15
|
+
READY: string;
|
|
16
|
+
ENABLED: string;
|
|
17
|
+
DISABLED: string;
|
|
18
|
+
SYNC_CONNECTIONS: string;
|
|
19
|
+
};
|
|
20
|
+
nativeEvent: {
|
|
21
|
+
CONNECT: string;
|
|
22
|
+
DISCONNECT: string;
|
|
23
|
+
ERROR: string;
|
|
24
|
+
};
|
|
25
|
+
abstract newConnection(url: string | URL): oox.KeepAliveConnection<NativeConnection>;
|
|
26
|
+
bindConnectionEvents(connection: oox.KeepAliveConnection<NativeConnection>): void;
|
|
27
|
+
open(url: string | URL): Promise<oox.KeepAliveConnection<NativeConnection>>;
|
|
28
|
+
close(connection: oox.KeepAliveConnection<NativeConnection>): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* 发送事件
|
|
31
|
+
* @param socket
|
|
32
|
+
* @param event
|
|
33
|
+
* @param params
|
|
34
|
+
*/
|
|
35
|
+
emit(socket: NativeConnection, event: string, params: any[]): Promise<unknown>;
|
|
36
|
+
/**
|
|
37
|
+
* RPC
|
|
38
|
+
*/
|
|
39
|
+
rpc(connection: oox.KeepAliveConnection<NativeConnection>, action: string, params: [], context?: oox.Context): Promise<any>;
|
|
40
|
+
/**
|
|
41
|
+
* 绑定 call 事件
|
|
42
|
+
* @param connection
|
|
43
|
+
*/
|
|
44
|
+
bindCall(connection: oox.KeepAliveConnection<NativeConnection>): void;
|
|
45
|
+
call(action: string, params: any[], context: oox.Context, callback?: (returns: any) => void): Promise<oox.ReturnsBody>;
|
|
46
|
+
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import EventEmitter from 'node:events';
|
|
2
|
-
import { Context } from './index.js';
|
|
3
|
-
export interface RPCKeepAliveConnectionAdapter<T> {
|
|
4
|
-
open(url: string | URL): Promise<RPCKeepAliveConnection<T>>;
|
|
5
|
-
close(connection: RPCKeepAliveConnection<T>): Promise<void>;
|
|
6
|
-
rpc(connection: RPCKeepAliveConnection<T>, action: string, params: any[], context: Context): Promise<any>;
|
|
7
|
-
}
|
|
8
|
-
export interface RPCKeepAliveConnectionData {
|
|
9
|
-
/**
|
|
10
|
-
* 连接主机地址
|
|
11
|
-
*/
|
|
12
|
-
host: string;
|
|
13
|
-
/**
|
|
14
|
-
* 连接服务名称
|
|
15
|
-
*/
|
|
16
|
-
name: string;
|
|
17
|
-
/**
|
|
18
|
-
* 连接URL
|
|
19
|
-
*/
|
|
20
|
-
url?: string | URL;
|
|
21
|
-
/**
|
|
22
|
-
* 目标服务网络唯一ID
|
|
23
|
-
*/
|
|
24
|
-
id: string;
|
|
25
|
-
}
|
|
26
|
-
export type RPCKeepAliveConnectionEventMap = Record<keyof {
|
|
27
|
-
"enabled": any;
|
|
28
|
-
"disabled": any;
|
|
29
|
-
"connect": any;
|
|
30
|
-
"disconnect": any;
|
|
31
|
-
'error': any;
|
|
32
|
-
}, any[]>;
|
|
33
|
-
export declare class RPCKeepAliveConnection<T> extends EventEmitter<RPCKeepAliveConnectionEventMap> {
|
|
34
|
-
#private;
|
|
35
|
-
data: RPCKeepAliveConnectionData;
|
|
36
|
-
nativeConnection: T;
|
|
37
|
-
adapter: RPCKeepAliveConnectionAdapter<T>;
|
|
38
|
-
constructor(adapter: RPCKeepAliveConnectionAdapter<T>, nativeConnection: T, data: RPCKeepAliveConnectionData);
|
|
39
|
-
set enabled(enabled: boolean);
|
|
40
|
-
get enabled(): boolean;
|
|
41
|
-
updateId(newId: string): void;
|
|
42
|
-
updateName(newName: string): void;
|
|
43
|
-
updateIdAndName(newId: string, newName: string): void;
|
|
44
|
-
}
|
|
45
|
-
export declare class KeepAliveConnectionStore<T> {
|
|
46
|
-
#private;
|
|
47
|
-
entries(): MapIterator<[string, Map<string, RPCKeepAliveConnection<T>>]>;
|
|
48
|
-
getConnectionsOfService(name: string): Map<string, RPCKeepAliveConnection<T>>;
|
|
49
|
-
has(name: string, id: string): boolean;
|
|
50
|
-
get(name: string, id: string): RPCKeepAliveConnection<T> | null;
|
|
51
|
-
add(connection: RPCKeepAliveConnection<T>): void;
|
|
52
|
-
remove(connection: RPCKeepAliveConnection<T>): void;
|
|
53
|
-
remove(name: string, id: string): void;
|
|
54
|
-
}
|
|
55
|
-
export declare const rpcKeepAliveConnectionAdapters: Map<string, RPCKeepAliveConnectionAdapter<any>>;
|
|
56
|
-
export declare const keepAliveConnections: KeepAliveConnectionStore<any>;
|
|
57
|
-
export declare const enabledKeepAliveConnections: KeepAliveConnectionStore<any>;
|