pubo-node 1.0.157 → 1.0.159
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/lib/child-process/index.js +7 -7
- package/lib/file-system/index.d.ts +0 -4
- package/lib/ftp-client/index.d.ts +0 -2
- package/lib/grpc/index.d.ts +0 -1
- package/lib/grpc/index.js +2 -2
- package/lib/index.d.ts +2 -1
- package/lib/utils/network.js +2 -3
- package/package.json +4 -17
- package/dist/pubo-node.js +0 -1
- package/es/child-process/index.d.ts +0 -12
- package/es/child-process/index.js +0 -157
- package/es/file-system/index.d.ts +0 -26
- package/es/file-system/index.js +0 -28
- package/es/ftp-client/index.d.ts +0 -66
- package/es/ftp-client/index.js +0 -135
- package/es/grpc/index.d.ts +0 -28
- package/es/grpc/index.js +0 -103
- package/es/index.d.ts +0 -8
- package/es/index.js +0 -8
- package/es/ros/topic.d.ts +0 -20
- package/es/ros/topic.js +0 -80
- package/es/storage/json.d.ts +0 -15
- package/es/storage/json.js +0 -181
- package/es/utils/index.d.ts +0 -1
- package/es/utils/index.js +0 -14
- package/es/utils/network.d.ts +0 -2
- package/es/utils/network.js +0 -35
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { exec } from 'child_process';
|
|
2
|
-
import { loop, waitFor } from 'pubo-utils';
|
|
3
|
-
// 获取进程名称
|
|
4
|
-
export function getProcessName(pid) {
|
|
5
|
-
return new Promise((resolve, reject) => {
|
|
6
|
-
exec(`grep "Name:" /proc/${pid}/status`, (err, data) => {
|
|
7
|
-
if (err) {
|
|
8
|
-
reject(err);
|
|
9
|
-
}
|
|
10
|
-
else {
|
|
11
|
-
resolve(data);
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
// 获取进程 cpu 使用率
|
|
17
|
-
export function getProcessCpuUseByPid(pid) {
|
|
18
|
-
return new Promise((resolve) => {
|
|
19
|
-
exec(`ps -p ${pid} -o %cpu=`, (err, stdout) => {
|
|
20
|
-
if (err) {
|
|
21
|
-
resolve(-1);
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
resolve(parseFloat(stdout.toString()));
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
// 获取进程 command 使用率
|
|
30
|
-
export function getProcessCommandByPid(pid) {
|
|
31
|
-
return new Promise((resolve) => {
|
|
32
|
-
exec(`ps -p ${pid} -o command=`, (err, stdout) => {
|
|
33
|
-
if (err) {
|
|
34
|
-
resolve('');
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
resolve(stdout.toString().split('\n')[0]);
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
// 判断进程是否死亡
|
|
43
|
-
export async function isProcessDied(pid) {
|
|
44
|
-
const used = await getProcessCpuUseByPid(pid);
|
|
45
|
-
return used < 0;
|
|
46
|
-
}
|
|
47
|
-
// 获取子进程
|
|
48
|
-
export function getProcessByPpid(pid) {
|
|
49
|
-
return new Promise((resolve) => {
|
|
50
|
-
exec(`ps -o pid --no-headers --ppid ${pid}`, (err, stdout) => {
|
|
51
|
-
if (err) {
|
|
52
|
-
resolve([]);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
resolve(stdout
|
|
56
|
-
.split('\n')
|
|
57
|
-
.filter((item) => !!item)
|
|
58
|
-
.map((item) => parseFloat(item.trim())));
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
// 获取进程树
|
|
64
|
-
export const getProcessTree = async (pid, tree) => {
|
|
65
|
-
let isRoot = false;
|
|
66
|
-
if (!tree) {
|
|
67
|
-
isRoot = true;
|
|
68
|
-
tree = { pid, children: [] };
|
|
69
|
-
}
|
|
70
|
-
const pidList = await getProcessByPpid(pid);
|
|
71
|
-
for (const id of pidList) {
|
|
72
|
-
const item = { pid: id, children: [] };
|
|
73
|
-
await getProcessTree(id, item);
|
|
74
|
-
tree.children.push(item);
|
|
75
|
-
}
|
|
76
|
-
if (isRoot) {
|
|
77
|
-
return tree;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
tree = null;
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
// 杀死进程
|
|
85
|
-
async function _SIGKILL(pid, signal = 2, times = 1) {
|
|
86
|
-
if (times > 5) {
|
|
87
|
-
throw new Error('SIGKILL 失败. times > 5');
|
|
88
|
-
}
|
|
89
|
-
exec(`kill -${signal} ${pid}`);
|
|
90
|
-
try {
|
|
91
|
-
await waitFor(async () => isProcessDied(pid), { checkTime: 100, timeout: 4000 });
|
|
92
|
-
}
|
|
93
|
-
catch (err) {
|
|
94
|
-
await _SIGKILL(pid, 9, times + 1);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
// 广度优先遍历进程树,将pid放入tmp
|
|
98
|
-
const flatProcessTree = (tree, tmp) => {
|
|
99
|
-
if (tree.children) {
|
|
100
|
-
tmp.push(...tree.children.map((item) => item.pid));
|
|
101
|
-
tree.children.forEach((item) => flatProcessTree(item, tmp));
|
|
102
|
-
}
|
|
103
|
-
tree = null;
|
|
104
|
-
tmp = null;
|
|
105
|
-
};
|
|
106
|
-
export async function SIGKILL(pid, signal = 2) {
|
|
107
|
-
if (process.platform === 'win32') {
|
|
108
|
-
return new Promise((resolve) => {
|
|
109
|
-
exec(`taskkill /pid ${pid} /T /F`, resolve);
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
let tree = await getProcessTree(pid);
|
|
113
|
-
// 获取所有进程PID,从叶到根
|
|
114
|
-
const tmp = [tree.pid];
|
|
115
|
-
flatProcessTree(tree, tmp);
|
|
116
|
-
tmp.reverse();
|
|
117
|
-
tree = null;
|
|
118
|
-
for (const item of tmp) {
|
|
119
|
-
await _SIGKILL(item, signal);
|
|
120
|
-
}
|
|
121
|
-
return 'success';
|
|
122
|
-
}
|
|
123
|
-
// 子进程心跳包
|
|
124
|
-
export const heartbeat = () => {
|
|
125
|
-
if (typeof process.send !== 'function') {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
loop(async () => {
|
|
129
|
-
await new Promise((resolve) => {
|
|
130
|
-
process.send({ type: 'beat', timestamp: new Date().valueOf() }, resolve);
|
|
131
|
-
});
|
|
132
|
-
}, 6000);
|
|
133
|
-
};
|
|
134
|
-
const parseAudioCard = (v) => {
|
|
135
|
-
let card = /card \d/.exec(v) ?? ['card 1'];
|
|
136
|
-
card = parseInt(card[0].replace('card ', ''), 10);
|
|
137
|
-
let device = /device \d/.exec(v) ?? ['device 0'];
|
|
138
|
-
device = parseInt(device[0].replace('device ', ''), 10);
|
|
139
|
-
return { text: v, index: `hw:${card},${device}` };
|
|
140
|
-
};
|
|
141
|
-
export const getAudioCards = (filter = '') => {
|
|
142
|
-
return new Promise((resolve, reject) => {
|
|
143
|
-
exec(`arecord -l`, (err, stdout) => {
|
|
144
|
-
if (err) {
|
|
145
|
-
reject(err);
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
const arr = stdout
|
|
149
|
-
.toString()
|
|
150
|
-
.split('\n')
|
|
151
|
-
.filter((item) => item.includes('card') && (filter ? item.includes(filter) : true))
|
|
152
|
-
.map((item) => parseAudioCard(item));
|
|
153
|
-
resolve(arr);
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
/// <reference types="node" />
|
|
4
|
-
/// <reference types="node" />
|
|
5
|
-
import type EventEmitter from 'events';
|
|
6
|
-
import * as fs from 'fs';
|
|
7
|
-
interface PuboFileSystemInterface {
|
|
8
|
-
read: <TBuffer extends NodeJS.ArrayBufferView>(fd: number, buffer?: TBuffer, offset?: number, length?: number, position?: fs.ReadPosition | null) => Promise<[number, TBuffer]>;
|
|
9
|
-
stat: (path: fs.PathLike) => Promise<fs.Stats>;
|
|
10
|
-
readFile: (path: fs.PathOrFileDescriptor, options?: ({
|
|
11
|
-
encoding?: null;
|
|
12
|
-
flag?: string;
|
|
13
|
-
} & EventEmitter.Abortable) | null) => Promise<Buffer>;
|
|
14
|
-
writeFile: (file: fs.PathOrFileDescriptor, data: string | NodeJS.ArrayBufferView, options?: fs.WriteFileOptions) => Promise<void>;
|
|
15
|
-
readdir: (path: fs.PathLike, options?: BufferEncoding | {
|
|
16
|
-
encoding: BufferEncoding | null;
|
|
17
|
-
withFileTypes: false;
|
|
18
|
-
} | null) => Promise<string[]>;
|
|
19
|
-
open: (path: fs.PathLike, flags?: fs.OpenMode, mode?: fs.Mode | null) => Promise<number>;
|
|
20
|
-
close: (fd: number) => Promise<void>;
|
|
21
|
-
mkdir: (path: fs.PathLike, options?: fs.MakeDirectoryOptions) => Promise<void>;
|
|
22
|
-
rm: (path: fs.PathLike) => Promise<void>;
|
|
23
|
-
write: <TBuffer extends NodeJS.ArrayBufferView>(fd: number, buffer: TBuffer, offset?: number | null, length?: number | null, position?: number | null) => Promise<void>;
|
|
24
|
-
}
|
|
25
|
-
export declare const PuboFileSystem: PuboFileSystemInterface;
|
|
26
|
-
export {};
|
package/es/file-system/index.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
const callback2promise = (fn) => {
|
|
3
|
-
return (...args) => new Promise((resolve, reject) => {
|
|
4
|
-
fn(...args, (err, ...rest) => {
|
|
5
|
-
if (err) {
|
|
6
|
-
reject(err);
|
|
7
|
-
}
|
|
8
|
-
if (rest.length < 2) {
|
|
9
|
-
resolve(rest[0]);
|
|
10
|
-
}
|
|
11
|
-
else {
|
|
12
|
-
resolve([...rest]);
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
};
|
|
17
|
-
export const PuboFileSystem = {
|
|
18
|
-
read: callback2promise(fs.read),
|
|
19
|
-
readFile: callback2promise(fs.readFile),
|
|
20
|
-
writeFile: callback2promise(fs.writeFile),
|
|
21
|
-
readdir: callback2promise(fs.readdir),
|
|
22
|
-
open: callback2promise(fs.open),
|
|
23
|
-
close: callback2promise(fs.close),
|
|
24
|
-
write: callback2promise(fs.write),
|
|
25
|
-
stat: callback2promise(fs.stat),
|
|
26
|
-
mkdir: callback2promise(fs.mkdir),
|
|
27
|
-
rm: callback2promise(fs.rm),
|
|
28
|
-
};
|
package/es/ftp-client/index.d.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
import type { Stream } from 'stream';
|
|
4
|
-
export interface FtpFile {
|
|
5
|
-
name: string;
|
|
6
|
-
owner: string;
|
|
7
|
-
group: string;
|
|
8
|
-
size: number;
|
|
9
|
-
date: Date;
|
|
10
|
-
type: string;
|
|
11
|
-
}
|
|
12
|
-
export interface FtpConnectOptions {
|
|
13
|
-
user: string;
|
|
14
|
-
host: string;
|
|
15
|
-
password: string;
|
|
16
|
-
driver: any;
|
|
17
|
-
}
|
|
18
|
-
type GetFile = (path: string) => Promise<Buffer>;
|
|
19
|
-
type PutFile = (input: string | Buffer | Stream, path: string) => Promise<string>;
|
|
20
|
-
type DeleteFile = (path: string) => Promise<string>;
|
|
21
|
-
type ListFiles = (path: string) => Promise<FtpFile[]>;
|
|
22
|
-
type RenameFile = (path: string, old: string) => Promise<string>;
|
|
23
|
-
export interface FtpClientInterface {
|
|
24
|
-
get: GetFile;
|
|
25
|
-
put: PutFile;
|
|
26
|
-
delete: DeleteFile;
|
|
27
|
-
list: ListFiles;
|
|
28
|
-
rename: RenameFile;
|
|
29
|
-
}
|
|
30
|
-
export declare class FtpClient implements FtpClientInterface {
|
|
31
|
-
private readonly driver;
|
|
32
|
-
private readonly options;
|
|
33
|
-
private readonly state;
|
|
34
|
-
private client;
|
|
35
|
-
private _len;
|
|
36
|
-
id: string;
|
|
37
|
-
constructor({ driver, ...options }: FtpConnectOptions);
|
|
38
|
-
get len(): number;
|
|
39
|
-
set len(n: number);
|
|
40
|
-
put: (...args: any[]) => Promise<any>;
|
|
41
|
-
delete: (...args: any[]) => Promise<any>;
|
|
42
|
-
list: (...args: any[]) => Promise<any>;
|
|
43
|
-
rename: (...args: any[]) => Promise<any>;
|
|
44
|
-
private connect;
|
|
45
|
-
private close;
|
|
46
|
-
private run;
|
|
47
|
-
private bind;
|
|
48
|
-
get(...args: any[]): Promise<Buffer>;
|
|
49
|
-
}
|
|
50
|
-
export declare class FtpClientPool implements FtpClientInterface {
|
|
51
|
-
private readonly options;
|
|
52
|
-
private readonly maxConnection;
|
|
53
|
-
private readonly pool;
|
|
54
|
-
constructor({ maxConnection, ...options }: {
|
|
55
|
-
maxConnection?: number;
|
|
56
|
-
} & FtpConnectOptions);
|
|
57
|
-
get: (...args: any[]) => Promise<any>;
|
|
58
|
-
put: (...args: any[]) => Promise<any>;
|
|
59
|
-
delete: (...args: any[]) => Promise<any>;
|
|
60
|
-
list: (...args: any[]) => Promise<any>;
|
|
61
|
-
rename: (...args: any[]) => Promise<any>;
|
|
62
|
-
get len(): number;
|
|
63
|
-
private get client();
|
|
64
|
-
private bind;
|
|
65
|
-
}
|
|
66
|
-
export {};
|
package/es/ftp-client/index.js
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { random, waitFor } from 'pubo-utils';
|
|
2
|
-
export class FtpClient {
|
|
3
|
-
driver;
|
|
4
|
-
options;
|
|
5
|
-
state = { running: false, connected: false, destroyed: false, connecting: false };
|
|
6
|
-
client;
|
|
7
|
-
_len = 0;
|
|
8
|
-
id = random();
|
|
9
|
-
constructor({ driver, ...options }) {
|
|
10
|
-
this.driver = driver;
|
|
11
|
-
this.options = options;
|
|
12
|
-
}
|
|
13
|
-
get len() {
|
|
14
|
-
return this._len;
|
|
15
|
-
}
|
|
16
|
-
set len(n) {
|
|
17
|
-
this._len = n;
|
|
18
|
-
if (this._len < 1) {
|
|
19
|
-
this.close();
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
put = this.bind('put');
|
|
23
|
-
delete = this.bind('delete');
|
|
24
|
-
list = this.bind('list');
|
|
25
|
-
rename = this.bind('rename');
|
|
26
|
-
async connect() {
|
|
27
|
-
if (!this.client) {
|
|
28
|
-
this.client = new this.driver();
|
|
29
|
-
}
|
|
30
|
-
this.state.destroyed = false;
|
|
31
|
-
if (this.state.connecting) {
|
|
32
|
-
await waitFor(() => this.state.connected, { checkTime: 1000, timeout: 10000 });
|
|
33
|
-
return 'connected';
|
|
34
|
-
}
|
|
35
|
-
this.state.connecting = true;
|
|
36
|
-
return new Promise((resolve, reject) => {
|
|
37
|
-
this.client.once('ready', () => {
|
|
38
|
-
this.state.connected = true;
|
|
39
|
-
resolve('connected');
|
|
40
|
-
this.state.connecting = false;
|
|
41
|
-
});
|
|
42
|
-
this.client.once('error', (err) => {
|
|
43
|
-
reject(err);
|
|
44
|
-
this.close();
|
|
45
|
-
});
|
|
46
|
-
this.client.connect({ ...this.options });
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
close() {
|
|
50
|
-
this.client.end();
|
|
51
|
-
this.state.connected = false;
|
|
52
|
-
this.state.destroyed = true;
|
|
53
|
-
this.state.connecting = false;
|
|
54
|
-
this.client = null;
|
|
55
|
-
}
|
|
56
|
-
async run({ fn, args }) {
|
|
57
|
-
this.len += 1;
|
|
58
|
-
if (!this.state.connected) {
|
|
59
|
-
await this.connect();
|
|
60
|
-
}
|
|
61
|
-
if (this.state.running) {
|
|
62
|
-
await waitFor(() => !this.state.running, { checkTime: 1000, timeout: 6000000 });
|
|
63
|
-
}
|
|
64
|
-
this.state.running = true;
|
|
65
|
-
return new Promise((resolve, reject) => {
|
|
66
|
-
this.client[fn](...args, (err, res) => {
|
|
67
|
-
if (err) {
|
|
68
|
-
reject(err);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
resolve(res);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
bind(fn) {
|
|
77
|
-
return async (...args) => {
|
|
78
|
-
const res = await this.run({ fn, args });
|
|
79
|
-
this.state.running = false;
|
|
80
|
-
this.len -= 1;
|
|
81
|
-
return res;
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
async get(...args) {
|
|
85
|
-
let res = Buffer.alloc(0);
|
|
86
|
-
const stream = await this.run({ fn: 'get', args });
|
|
87
|
-
return new Promise((resolve) => {
|
|
88
|
-
stream.on('data', (chunk) => {
|
|
89
|
-
res = Buffer.concat([res, chunk], res.byteLength + chunk.byteLength);
|
|
90
|
-
});
|
|
91
|
-
stream.on('end', () => {
|
|
92
|
-
resolve(res);
|
|
93
|
-
this.state.running = false;
|
|
94
|
-
this.len -= 1;
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
export class FtpClientPool {
|
|
100
|
-
options;
|
|
101
|
-
maxConnection;
|
|
102
|
-
pool = [];
|
|
103
|
-
constructor({ maxConnection = 5, ...options }) {
|
|
104
|
-
this.options = options;
|
|
105
|
-
this.maxConnection = maxConnection;
|
|
106
|
-
}
|
|
107
|
-
get = this.bind('get');
|
|
108
|
-
put = this.bind('put');
|
|
109
|
-
delete = this.bind('delete');
|
|
110
|
-
list = this.bind('list');
|
|
111
|
-
rename = this.bind('rename');
|
|
112
|
-
get len() {
|
|
113
|
-
return this.pool.length;
|
|
114
|
-
}
|
|
115
|
-
get client() {
|
|
116
|
-
if (this.pool.length < this.maxConnection) {
|
|
117
|
-
const client = new FtpClient(this.options);
|
|
118
|
-
this.pool.push(client);
|
|
119
|
-
return client;
|
|
120
|
-
}
|
|
121
|
-
this.pool.sort((a, b) => a.len - b.len);
|
|
122
|
-
return this.pool[0];
|
|
123
|
-
}
|
|
124
|
-
bind(fn) {
|
|
125
|
-
return async (...args) => {
|
|
126
|
-
const client = this.client;
|
|
127
|
-
const res = await client[fn](...args);
|
|
128
|
-
if (client.len < 1) {
|
|
129
|
-
const index = this.pool.findIndex((item) => item.id === client.id);
|
|
130
|
-
this.pool.splice(index, 1);
|
|
131
|
-
}
|
|
132
|
-
return res;
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
}
|
package/es/grpc/index.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
export interface CreateClientProps {
|
|
3
|
-
url: string;
|
|
4
|
-
options?: any;
|
|
5
|
-
ServiceImp: any;
|
|
6
|
-
Grpc: any;
|
|
7
|
-
cert?: Buffer;
|
|
8
|
-
}
|
|
9
|
-
declare class GrpcClient {
|
|
10
|
-
private readonly url;
|
|
11
|
-
private readonly options;
|
|
12
|
-
private readonly Grpc;
|
|
13
|
-
private readonly credentials;
|
|
14
|
-
private client;
|
|
15
|
-
private _timeout;
|
|
16
|
-
connections: number;
|
|
17
|
-
constructor({ url, options, Grpc, cert }: any);
|
|
18
|
-
request(service: any, method: any, data: any): Promise<Buffer>;
|
|
19
|
-
_request({ service, method, data }: {
|
|
20
|
-
service: any;
|
|
21
|
-
method: any;
|
|
22
|
-
data: any;
|
|
23
|
-
}): Promise<Buffer>;
|
|
24
|
-
close(): void;
|
|
25
|
-
}
|
|
26
|
-
export declare const GrpcList: GrpcClient[];
|
|
27
|
-
export declare function createRpcClient<T>({ url, options, ServiceImp, Grpc, cert }: CreateClientProps): T;
|
|
28
|
-
export {};
|
package/es/grpc/index.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
const passThrough = (argument) => argument;
|
|
2
|
-
class GrpcClient {
|
|
3
|
-
url;
|
|
4
|
-
options;
|
|
5
|
-
Grpc;
|
|
6
|
-
credentials;
|
|
7
|
-
client;
|
|
8
|
-
_timeout;
|
|
9
|
-
connections = 0;
|
|
10
|
-
constructor({ url, options = {}, Grpc, cert }) {
|
|
11
|
-
const opt = { 'grpc.max_send_message_length': -1, 'grpc.max_receive_message_length': -1, ...options };
|
|
12
|
-
const credentials = cert ? Grpc.credentials.createSsl(cert) : Grpc.credentials.createInsecure();
|
|
13
|
-
this.url = url;
|
|
14
|
-
this.Grpc = Grpc;
|
|
15
|
-
this.credentials = credentials;
|
|
16
|
-
this.options = opt;
|
|
17
|
-
this.options.timeout = this.options.timeout ?? 10000;
|
|
18
|
-
Grpc = null;
|
|
19
|
-
options = null;
|
|
20
|
-
cert = null;
|
|
21
|
-
}
|
|
22
|
-
async request(service, method, data) {
|
|
23
|
-
if (this._timeout) {
|
|
24
|
-
clearTimeout(this._timeout);
|
|
25
|
-
this._timeout = null;
|
|
26
|
-
}
|
|
27
|
-
this.connections += 1;
|
|
28
|
-
if (!this.client) {
|
|
29
|
-
this.client = new this.Grpc.Client(this.url, this.credentials, this.options);
|
|
30
|
-
}
|
|
31
|
-
let error;
|
|
32
|
-
let result = Buffer.alloc(0);
|
|
33
|
-
try {
|
|
34
|
-
result = await this._request({ service, method, data });
|
|
35
|
-
}
|
|
36
|
-
catch (err) {
|
|
37
|
-
error = err;
|
|
38
|
-
}
|
|
39
|
-
service = null;
|
|
40
|
-
method = null;
|
|
41
|
-
data = null;
|
|
42
|
-
this.connections -= 1;
|
|
43
|
-
if (this.connections < 0) {
|
|
44
|
-
this.connections = 0;
|
|
45
|
-
}
|
|
46
|
-
if (this.connections < 1) {
|
|
47
|
-
if (this._timeout) {
|
|
48
|
-
clearTimeout(this._timeout);
|
|
49
|
-
this._timeout = null;
|
|
50
|
-
}
|
|
51
|
-
this._timeout = setTimeout(() => this.close(), 60000);
|
|
52
|
-
}
|
|
53
|
-
if (error) {
|
|
54
|
-
console.log(error);
|
|
55
|
-
this.close();
|
|
56
|
-
throw new Error('grpc connection error.');
|
|
57
|
-
}
|
|
58
|
-
return result;
|
|
59
|
-
}
|
|
60
|
-
_request({ service, method, data }) {
|
|
61
|
-
return new Promise((resolve, reject) => {
|
|
62
|
-
let _ended = false;
|
|
63
|
-
const _timeout = setTimeout(() => {
|
|
64
|
-
_ended = true;
|
|
65
|
-
this.close();
|
|
66
|
-
console.log('rpc request timeout');
|
|
67
|
-
reject(new Error('timeout'));
|
|
68
|
-
}, this.options.timeout);
|
|
69
|
-
const onResponse = (err, res) => {
|
|
70
|
-
if (_ended) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
clearTimeout(_timeout);
|
|
75
|
-
}
|
|
76
|
-
if (err) {
|
|
77
|
-
reject(err);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
resolve(res);
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
this.client.makeUnaryRequest(`/${service}/${method}`, passThrough, passThrough, data ? Buffer.from(data) : Buffer.alloc(0), onResponse);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
close() {
|
|
87
|
-
if (this._timeout) {
|
|
88
|
-
clearTimeout(this._timeout);
|
|
89
|
-
delete this._timeout;
|
|
90
|
-
}
|
|
91
|
-
this.client?.close();
|
|
92
|
-
this.client = null;
|
|
93
|
-
delete this.client;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
export const GrpcList = [];
|
|
97
|
-
export function createRpcClient({ url, options = {}, ServiceImp, Grpc, cert }) {
|
|
98
|
-
const client = new GrpcClient({ url, options, Grpc, cert });
|
|
99
|
-
GrpcList.push(client);
|
|
100
|
-
Grpc = null;
|
|
101
|
-
options = null;
|
|
102
|
-
return new ServiceImp({ request: client.request.bind(client) });
|
|
103
|
-
}
|
package/es/index.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { JsonStorage } from './storage/json';
|
|
2
|
-
export { FtpClient, FtpClientPool, FtpConnectOptions, FtpFile } from './ftp-client';
|
|
3
|
-
export { createRpcClient, GrpcList } from './grpc';
|
|
4
|
-
export { SIGKILL, isProcessDied, getProcessName, getProcessTree, getProcessByPpid, getProcessCpuUseByPid, getProcessCommandByPid, heartbeat, } from './child-process';
|
|
5
|
-
export { isPortAvailable } from './utils';
|
|
6
|
-
export { getWifiName, getNetworks } from './utils/network';
|
|
7
|
-
export { RosTopicManager, RosTopic } from './ros/topic';
|
|
8
|
-
export { PuboFileSystem } from './file-system';
|
package/es/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { JsonStorage } from './storage/json';
|
|
2
|
-
export { FtpClient, FtpClientPool } from './ftp-client';
|
|
3
|
-
export { createRpcClient, GrpcList } from './grpc';
|
|
4
|
-
export { SIGKILL, isProcessDied, getProcessName, getProcessTree, getProcessByPpid, getProcessCpuUseByPid, getProcessCommandByPid, heartbeat, } from './child-process';
|
|
5
|
-
export { isPortAvailable } from './utils';
|
|
6
|
-
export { getWifiName, getNetworks } from './utils/network';
|
|
7
|
-
export { RosTopicManager, RosTopic } from './ros/topic';
|
|
8
|
-
export { PuboFileSystem } from './file-system';
|
package/es/ros/topic.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Emitter } from 'pubo-utils';
|
|
2
|
-
export declare class RosTopic {
|
|
3
|
-
topic: string;
|
|
4
|
-
messageType: string;
|
|
5
|
-
emitter: Emitter;
|
|
6
|
-
private subscribed;
|
|
7
|
-
private readonly dog;
|
|
8
|
-
private readonly strSplit;
|
|
9
|
-
private subscribeChildProcess;
|
|
10
|
-
constructor(topic: any, messageType: any);
|
|
11
|
-
private onTimeout;
|
|
12
|
-
private onData;
|
|
13
|
-
subscribe(): Promise<void>;
|
|
14
|
-
unsubscribe(): Promise<void>;
|
|
15
|
-
publish(payload: any): Promise<unknown>;
|
|
16
|
-
}
|
|
17
|
-
export declare const RosTopicManager: {
|
|
18
|
-
cache: never[];
|
|
19
|
-
getTopic: (topic: any, messageType: any) => RosTopic;
|
|
20
|
-
};
|
package/es/ros/topic.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { exec, spawn } from 'child_process';
|
|
2
|
-
import { Emitter, WatchDog, StringSplit, sleep } from 'pubo-utils';
|
|
3
|
-
import * as YAML from 'yaml';
|
|
4
|
-
import { SIGKILL } from '../child-process';
|
|
5
|
-
export class RosTopic {
|
|
6
|
-
topic;
|
|
7
|
-
messageType;
|
|
8
|
-
emitter = new Emitter();
|
|
9
|
-
subscribed = false;
|
|
10
|
-
dog = new WatchDog({ limit: 10, onTimeout: this.onTimeout.bind(this) });
|
|
11
|
-
strSplit = new StringSplit('---');
|
|
12
|
-
subscribeChildProcess;
|
|
13
|
-
constructor(topic, messageType) {
|
|
14
|
-
this.topic = topic;
|
|
15
|
-
this.messageType = messageType;
|
|
16
|
-
this.subscribed = false;
|
|
17
|
-
this.emitter = new Emitter();
|
|
18
|
-
}
|
|
19
|
-
async onTimeout() {
|
|
20
|
-
if (!this.subscribed) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
await this.unsubscribe();
|
|
24
|
-
await sleep(1000);
|
|
25
|
-
await this.subscribe();
|
|
26
|
-
}
|
|
27
|
-
onData(data) {
|
|
28
|
-
const tmp = this.strSplit.split(data.toString()).slice(-1)[0];
|
|
29
|
-
if (!tmp) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
this.dog.feed();
|
|
33
|
-
const res = YAML.parse(tmp);
|
|
34
|
-
this.emitter.emit('message', res);
|
|
35
|
-
}
|
|
36
|
-
async subscribe() {
|
|
37
|
-
if (this.subscribeChildProcess) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
this.subscribed = true;
|
|
41
|
-
this.dog.init();
|
|
42
|
-
this.subscribeChildProcess = spawn(`rostopic`, ['echo', this.topic]);
|
|
43
|
-
this.subscribeChildProcess.stdout.on('data', this.onData.bind(this));
|
|
44
|
-
this.subscribeChildProcess.stderr.on('data', (buf) => console.log(buf.toString()));
|
|
45
|
-
}
|
|
46
|
-
async unsubscribe() {
|
|
47
|
-
if (!this.subscribeChildProcess) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
this.dog.stop();
|
|
51
|
-
this.subscribed = false;
|
|
52
|
-
await SIGKILL(this.subscribeChildProcess.pid);
|
|
53
|
-
this.subscribeChildProcess = null;
|
|
54
|
-
}
|
|
55
|
-
publish(payload) {
|
|
56
|
-
const data = YAML.stringify(payload);
|
|
57
|
-
return new Promise((resolve, reject) => {
|
|
58
|
-
exec(`rostopic pub -1 ${this.topic} ${this.messageType} "${data}"`, (err, stdout) => {
|
|
59
|
-
if (err) {
|
|
60
|
-
reject(err);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
resolve(stdout);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
export const RosTopicManager = {
|
|
70
|
-
cache: [],
|
|
71
|
-
getTopic: function (topic, messageType) {
|
|
72
|
-
const tmp = this.cache.find((item) => item.topic === topic);
|
|
73
|
-
if (tmp) {
|
|
74
|
-
return tmp;
|
|
75
|
-
}
|
|
76
|
-
const instance = new RosTopic(topic, messageType);
|
|
77
|
-
this.cache.push(instance);
|
|
78
|
-
return instance;
|
|
79
|
-
},
|
|
80
|
-
};
|
package/es/storage/json.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface JsonStorageOptions {
|
|
2
|
-
initialState?: any;
|
|
3
|
-
defaultState?: any;
|
|
4
|
-
}
|
|
5
|
-
export declare class JsonStorage {
|
|
6
|
-
private readonly instance;
|
|
7
|
-
private readonly queue;
|
|
8
|
-
constructor(path: string, options?: JsonStorageOptions);
|
|
9
|
-
private getState;
|
|
10
|
-
private setState;
|
|
11
|
-
get(key?: string): Promise<any>;
|
|
12
|
-
set(key: string, values: any): Promise<void>;
|
|
13
|
-
merge(values: any): Promise<void>;
|
|
14
|
-
remove(key: string): Promise<void>;
|
|
15
|
-
}
|