@push-rpc/next 2.0.0-beta.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/client/RpcClientImpl.d.ts +2 -2
- package/dist/client/RpcClientImpl.js +5 -5
- package/dist/client/RpcClientImpl.js.map +1 -1
- package/dist/client/WebSocketConnection.d.ts +2 -2
- package/dist/client/WebSocketConnection.js +22 -18
- package/dist/client/WebSocketConnection.js.map +1 -1
- package/dist/client/index.d.ts +3 -3
- package/dist/client/index.js +6 -2
- package/dist/client/index.js.map +1 -1
- package/dist/server/RpcServerImpl.d.ts +3 -2
- package/dist/server/RpcServerImpl.js +36 -7
- package/dist/server/RpcServerImpl.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/RpcClientImpl.ts +6 -5
- package/src/client/WebSocketConnection.ts +26 -17
- package/src/client/index.ts +10 -5
- package/src/server/RpcServerImpl.ts +22 -14
- package/src/server/index.ts +2 -1
- package/tests/subscriptions.ts +34 -1
- package/tests/testUtils.ts +3 -0
- package/tsconfig.cjs.json +2 -1
- package/tsconfig.json +2 -1
package/README.md
CHANGED
|
@@ -23,4 +23,8 @@ arguments in the invocation. Middleware can modify context.
|
|
|
23
23
|
|
|
24
24
|
**Throttling**. Used to limit number of notifications from the remote functions. With throttling enabled, not all
|
|
25
25
|
triggers will result in new notifications. Throttling can be used with reducers to aggregate values supplied in
|
|
26
|
-
triggers.
|
|
26
|
+
triggers.
|
|
27
|
+
|
|
28
|
+
## Issues / TBDs
|
|
29
|
+
|
|
30
|
+
- Browser sockets don't have 'ping' event. Need to find a different way to detect connection loss.
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="ws" />
|
|
2
1
|
import { Services } from "../rpc.js";
|
|
3
2
|
import { ServicesWithSubscriptions } from "./remote.js";
|
|
4
3
|
import { ConsumeServicesOptions, RpcClient } from "./index.js";
|
|
@@ -12,8 +11,9 @@ export declare class RpcClientImpl<S extends Services<S>> implements RpcClient {
|
|
|
12
11
|
isConnected(): boolean;
|
|
13
12
|
close(): Promise<void>;
|
|
14
13
|
_allSubscriptions(): [itemName: string, parameters: unknown[], consumers: (d: unknown) => void][];
|
|
15
|
-
_webSocket():
|
|
14
|
+
_webSocket(): WebSocket | null;
|
|
16
15
|
createRemote(): ServicesWithSubscriptions<S>;
|
|
16
|
+
connect(): Promise<void>;
|
|
17
17
|
private call;
|
|
18
18
|
private subscribe;
|
|
19
19
|
private unsubscribe;
|
|
@@ -20,11 +20,7 @@ class RpcClientImpl {
|
|
|
20
20
|
if (cached !== undefined) {
|
|
21
21
|
consumer(cached);
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
this.connection.connect().catch((e) => {
|
|
25
|
-
// ignored
|
|
26
|
-
});
|
|
27
|
-
}
|
|
23
|
+
void this.connection.connect();
|
|
28
24
|
const data = await this.invoke(itemName, rpc_js_1.InvocationType.Subscribe, (...parameters) => this.httpClient.subscribe(itemName, parameters, callOptions?.timeout ?? this.options.callTimeout), parameters);
|
|
29
25
|
this.remoteSubscriptions.subscribe(data, itemName, parameters, consumer);
|
|
30
26
|
};
|
|
@@ -51,6 +47,7 @@ class RpcClientImpl {
|
|
|
51
47
|
this.httpClient = new HttpClient_js_1.HttpClient(url, this.clientId);
|
|
52
48
|
this.remoteSubscriptions = new RemoteSubscriptions_js_1.RemoteSubscriptions();
|
|
53
49
|
this.connection = new WebSocketConnection_js_1.WebSocketConnection(url, this.clientId, {
|
|
50
|
+
subscriptions: options.subscriptions,
|
|
54
51
|
errorDelayMaxDuration: options.errorDelayMaxDuration,
|
|
55
52
|
reconnectDelay: options.reconnectDelay,
|
|
56
53
|
pingInterval: options.pingInterval,
|
|
@@ -83,6 +80,9 @@ class RpcClientImpl {
|
|
|
83
80
|
unsubscribe: this.unsubscribe,
|
|
84
81
|
});
|
|
85
82
|
}
|
|
83
|
+
async connect() {
|
|
84
|
+
await this.connection.connect();
|
|
85
|
+
}
|
|
86
86
|
invoke(itemName, invocationType, next, parameters) {
|
|
87
87
|
const ctx = {
|
|
88
88
|
clientId: this.clientId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RpcClientImpl.js","sourceRoot":"","sources":["../../src/client/RpcClientImpl.ts"],"names":[],"mappings":";;;AAAA,sCAA2E;AAC3E,mDAA0C;AAC1C,qEAA4D;AAC5D,qEAA4D;AAC5D,mCAA6B;AAC7B,2CAAmE;AAEnE,0DAAsD;AAEtD,MAAa,aAAa;IACxB,YACE,GAAW,EACM,OAA+B;QAA/B,YAAO,GAAP,OAAO,CAAwB;
|
|
1
|
+
{"version":3,"file":"RpcClientImpl.js","sourceRoot":"","sources":["../../src/client/RpcClientImpl.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import WebSocket from "ws";
|
|
2
1
|
export declare class WebSocketConnection {
|
|
3
2
|
private readonly url;
|
|
4
3
|
private readonly clientId;
|
|
@@ -6,9 +5,10 @@ export declare class WebSocketConnection {
|
|
|
6
5
|
private readonly consume;
|
|
7
6
|
private readonly onConnected;
|
|
8
7
|
constructor(url: string, clientId: string, options: {
|
|
8
|
+
subscriptions: boolean;
|
|
9
9
|
reconnectDelay: number;
|
|
10
10
|
errorDelayMaxDuration: number;
|
|
11
|
-
pingInterval: number;
|
|
11
|
+
pingInterval: number | null;
|
|
12
12
|
}, consume: (itemName: string, parameters: unknown[], data: unknown) => void, onConnected: () => void);
|
|
13
13
|
close(): Promise<void>;
|
|
14
14
|
/**
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.WebSocketConnection = void 0;
|
|
7
|
-
const ws_1 = __importDefault(require("ws"));
|
|
8
4
|
const logger_js_1 = require("../logger.js");
|
|
9
5
|
const json_js_1 = require("../utils/json.js");
|
|
10
6
|
const promises_js_1 = require("../utils/promises.js");
|
|
@@ -18,13 +14,13 @@ class WebSocketConnection {
|
|
|
18
14
|
this.socket = null;
|
|
19
15
|
this.disconnectedMark = true;
|
|
20
16
|
this.pingTimeout = null;
|
|
21
|
-
this.url = url;
|
|
17
|
+
this.url = url.replace(/^https(.*)/, "wss$1").replace(/^http(.*)/, "ws$1");
|
|
22
18
|
this.clientId = clientId;
|
|
23
19
|
}
|
|
24
20
|
async close() {
|
|
25
21
|
this.disconnectedMark = true;
|
|
26
22
|
if (this.socket) {
|
|
27
|
-
this.socket.
|
|
23
|
+
this.socket.close();
|
|
28
24
|
this.socket = null;
|
|
29
25
|
}
|
|
30
26
|
if (this.pingTimeout) {
|
|
@@ -37,8 +33,14 @@ class WebSocketConnection {
|
|
|
37
33
|
* Never rejects
|
|
38
34
|
*/
|
|
39
35
|
connect() {
|
|
36
|
+
// no subscriptions support, no need to connect
|
|
37
|
+
if (!this.options.subscriptions) {
|
|
38
|
+
return Promise.resolve();
|
|
39
|
+
}
|
|
40
|
+
// already started connecting
|
|
40
41
|
if (this.socket || !this.disconnectedMark)
|
|
41
42
|
return Promise.resolve();
|
|
43
|
+
// start connection process
|
|
42
44
|
this.disconnectedMark = false;
|
|
43
45
|
return new Promise(async (resolve) => {
|
|
44
46
|
let onFirstConnection = resolve;
|
|
@@ -54,7 +56,8 @@ class WebSocketConnection {
|
|
|
54
56
|
// signal about first connection
|
|
55
57
|
onFirstConnection();
|
|
56
58
|
onFirstConnection = () => { };
|
|
57
|
-
}, () => {
|
|
59
|
+
}, (e) => {
|
|
60
|
+
logger_js_1.log.warn("Unable to connect WS", e);
|
|
58
61
|
// 2. ... unable to establish connection
|
|
59
62
|
resolve();
|
|
60
63
|
});
|
|
@@ -83,19 +86,19 @@ class WebSocketConnection {
|
|
|
83
86
|
async establishConnection(onDisconnected) {
|
|
84
87
|
return new Promise(async (resolve, reject) => {
|
|
85
88
|
try {
|
|
86
|
-
const socket = new
|
|
89
|
+
const socket = new WebSocket(this.url, this.clientId);
|
|
87
90
|
let connected = false;
|
|
88
|
-
socket.
|
|
91
|
+
socket.addEventListener("open", () => {
|
|
89
92
|
this.socket = socket;
|
|
90
93
|
connected = true;
|
|
91
94
|
resolve();
|
|
92
95
|
this.heartbeat();
|
|
93
96
|
this.onConnected();
|
|
94
97
|
});
|
|
95
|
-
socket.
|
|
98
|
+
socket.addEventListener("ping", () => {
|
|
96
99
|
this.heartbeat();
|
|
97
100
|
});
|
|
98
|
-
socket.
|
|
101
|
+
socket.addEventListener("close", () => {
|
|
99
102
|
this.socket = null;
|
|
100
103
|
if (connected) {
|
|
101
104
|
onDisconnected();
|
|
@@ -104,11 +107,10 @@ class WebSocketConnection {
|
|
|
104
107
|
clearTimeout(this.pingTimeout);
|
|
105
108
|
}
|
|
106
109
|
});
|
|
107
|
-
socket.
|
|
110
|
+
socket.addEventListener("error", (e) => {
|
|
108
111
|
if (!connected) {
|
|
109
112
|
reject(e);
|
|
110
113
|
}
|
|
111
|
-
logger_js_1.log.warn("WS connection error", e.message);
|
|
112
114
|
try {
|
|
113
115
|
socket.close();
|
|
114
116
|
}
|
|
@@ -116,8 +118,8 @@ class WebSocketConnection {
|
|
|
116
118
|
// ignore
|
|
117
119
|
}
|
|
118
120
|
});
|
|
119
|
-
socket.
|
|
120
|
-
this.receiveSocketMessage(message);
|
|
121
|
+
socket.addEventListener("message", (message) => {
|
|
122
|
+
this.receiveSocketMessage(message.data);
|
|
121
123
|
});
|
|
122
124
|
}
|
|
123
125
|
catch (e) {
|
|
@@ -129,9 +131,11 @@ class WebSocketConnection {
|
|
|
129
131
|
if (this.pingTimeout) {
|
|
130
132
|
clearTimeout(this.pingTimeout);
|
|
131
133
|
}
|
|
132
|
-
this.
|
|
133
|
-
this.
|
|
134
|
-
|
|
134
|
+
if (this.options.pingInterval) {
|
|
135
|
+
this.pingTimeout = setTimeout(() => {
|
|
136
|
+
this.socket?.close();
|
|
137
|
+
}, this.options.pingInterval * 1.5);
|
|
138
|
+
}
|
|
135
139
|
}
|
|
136
140
|
async receiveSocketMessage(rawMessage) {
|
|
137
141
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebSocketConnection.js","sourceRoot":"","sources":["../../src/client/WebSocketConnection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WebSocketConnection.js","sourceRoot":"","sources":["../../src/client/WebSocketConnection.ts"],"names":[],"mappings":"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"}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { RpcContext, Services } from "../rpc.js";
|
|
2
2
|
import { ServicesWithSubscriptions } from "./remote.js";
|
|
3
|
-
import WebSocket from "ws";
|
|
4
3
|
import { Middleware } from "../utils/middleware.js";
|
|
5
4
|
export type RpcClient = {
|
|
6
5
|
isConnected(): boolean;
|
|
@@ -10,11 +9,12 @@ export type RpcClient = {
|
|
|
10
9
|
};
|
|
11
10
|
export type ConsumeServicesOptions = {
|
|
12
11
|
callTimeout: number;
|
|
13
|
-
subscribe: boolean;
|
|
14
12
|
reconnectDelay: number;
|
|
15
13
|
errorDelayMaxDuration: number;
|
|
16
|
-
pingInterval: number;
|
|
14
|
+
pingInterval: number | null;
|
|
15
|
+
subscriptions: boolean;
|
|
17
16
|
middleware: Middleware<RpcContext>[];
|
|
17
|
+
connectOnCreate: boolean;
|
|
18
18
|
};
|
|
19
19
|
export declare function consumeServices<S extends Services<S>>(url: string, overrideOptions?: Partial<ConsumeServicesOptions>): Promise<{
|
|
20
20
|
client: RpcClient;
|
package/dist/client/index.js
CHANGED
|
@@ -11,6 +11,9 @@ async function consumeServices(url, overrideOptions = {}) {
|
|
|
11
11
|
...overrideOptions,
|
|
12
12
|
};
|
|
13
13
|
const client = new RpcClientImpl_js_1.RpcClientImpl(url, options);
|
|
14
|
+
if (options.connectOnCreate) {
|
|
15
|
+
await client.connect();
|
|
16
|
+
}
|
|
14
17
|
return {
|
|
15
18
|
client,
|
|
16
19
|
remote: client.createRemote(),
|
|
@@ -19,10 +22,11 @@ async function consumeServices(url, overrideOptions = {}) {
|
|
|
19
22
|
exports.consumeServices = consumeServices;
|
|
20
23
|
const defaultOptions = {
|
|
21
24
|
callTimeout: 5 * 1000,
|
|
22
|
-
subscribe: true,
|
|
23
25
|
reconnectDelay: 0,
|
|
24
26
|
errorDelayMaxDuration: 15 * 1000,
|
|
25
|
-
pingInterval:
|
|
27
|
+
pingInterval: null, // if set, should be in-sync with server, ie 30 * 1000
|
|
28
|
+
subscriptions: true,
|
|
26
29
|
middleware: [],
|
|
30
|
+
connectOnCreate: false,
|
|
27
31
|
};
|
|
28
32
|
//# sourceMappingURL=index.js.map
|
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":";;;AAEA,yDAAgD;AAsBzC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,kBAAmD,EAAE;IAKrD,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAA;IAC5C,CAAC;IAED,MAAM,OAAO,GAAG;QACd,GAAG,cAAc;QACjB,GAAG,eAAe;KACnB,CAAA;IAED,MAAM,MAAM,GAAG,IAAI,gCAAa,CAAI,GAAG,EAAE,OAAO,CAAC,CAAA;IAEjD,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC5B,MAAM,MAAM,CAAC,OAAO,EAAE,CAAA;IACxB,CAAC;IAED,OAAO;QACL,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE;KAC9B,CAAA;AACH,CAAC;AA1BD,0CA0BC;AAED,MAAM,cAAc,GAA2B;IAC7C,WAAW,EAAE,CAAC,GAAG,IAAI;IACrB,cAAc,EAAE,CAAC;IACjB,qBAAqB,EAAE,EAAE,GAAG,IAAI;IAChC,YAAY,EAAE,IAAI,EAAE,sDAAsD;IAC1E,aAAa,EAAE,IAAI;IACnB,UAAU,EAAE,EAAE;IACd,eAAe,EAAE,KAAK;CACvB,CAAA"}
|
|
@@ -7,13 +7,14 @@ export declare class RpcServerImpl<S extends Services<S>, C extends RpcContext>
|
|
|
7
7
|
private readonly services;
|
|
8
8
|
private readonly options;
|
|
9
9
|
constructor(services: S, options: PublishServicesOptions<C>);
|
|
10
|
-
|
|
10
|
+
private createConnectionsServer;
|
|
11
|
+
start(): Promise<void>;
|
|
11
12
|
close(): Promise<void>;
|
|
12
13
|
createServicesWithTriggers(): ServicesWithTriggers<S>;
|
|
13
14
|
_allSubscriptions(): [itemName: string, parameters: unknown[], consumer: unknown][];
|
|
14
15
|
private readonly localSubscriptions;
|
|
15
16
|
private readonly invocationCache;
|
|
16
|
-
private
|
|
17
|
+
private connectionsServer;
|
|
17
18
|
readonly httpServer: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
|
|
18
19
|
private call;
|
|
19
20
|
private subscribe;
|
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
@@ -6,7 +29,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
29
|
exports.RpcServerImpl = void 0;
|
|
7
30
|
const LocalSubscriptions_js_1 = require("./LocalSubscriptions.js");
|
|
8
31
|
const http_1 = __importDefault(require("http"));
|
|
9
|
-
const ConnectionsServer_js_1 = require("./ConnectionsServer.js");
|
|
10
32
|
const promises_js_1 = require("../utils/promises.js");
|
|
11
33
|
const http_js_1 = require("./http.js");
|
|
12
34
|
const rpc_js_1 = require("../rpc.js");
|
|
@@ -20,6 +42,7 @@ class RpcServerImpl {
|
|
|
20
42
|
this.options = options;
|
|
21
43
|
this.localSubscriptions = new LocalSubscriptions_js_1.LocalSubscriptions();
|
|
22
44
|
this.invocationCache = new promises_js_1.PromiseCache();
|
|
45
|
+
this.connectionsServer = null;
|
|
23
46
|
this.call = async (connectionContext, itemName, parameters) => {
|
|
24
47
|
const item = this.getRemoteFunction(itemName);
|
|
25
48
|
if (!item) {
|
|
@@ -49,7 +72,7 @@ class RpcServerImpl {
|
|
|
49
72
|
const newDataJson = (0, json_js_1.safeStringify)(newData);
|
|
50
73
|
if (newDataJson != lastDataJson) {
|
|
51
74
|
lastDataJson = newDataJson;
|
|
52
|
-
this.connectionsServer
|
|
75
|
+
this.connectionsServer?.publish(connectionContext.clientId, itemName, parameters, newData);
|
|
53
76
|
}
|
|
54
77
|
}
|
|
55
78
|
catch (e) {
|
|
@@ -87,16 +110,22 @@ class RpcServerImpl {
|
|
|
87
110
|
}
|
|
88
111
|
});
|
|
89
112
|
}
|
|
90
|
-
this.connectionsServer = new ConnectionsServer_js_1.ConnectionsServer(this.httpServer, { pingInterval: options.pingInterval, path: options.path }, (clientId) => {
|
|
91
|
-
this.localSubscriptions.unsubscribeAll(clientId);
|
|
92
|
-
}, !("server" in this.options));
|
|
93
113
|
this.httpServer.addListener("request", (req, res) => (0, http_js_1.serveHttpRequest)(req, res, options.path, {
|
|
94
114
|
call: this.call,
|
|
95
115
|
subscribe: this.subscribe,
|
|
96
116
|
unsubscribe: this.unsubscribe,
|
|
97
117
|
}, options.createConnectionContext));
|
|
98
118
|
}
|
|
99
|
-
|
|
119
|
+
async createConnectionsServer() {
|
|
120
|
+
const { ConnectionsServer } = await Promise.resolve().then(() => __importStar(require("./ConnectionsServer.js")));
|
|
121
|
+
return new ConnectionsServer(this.httpServer, { pingInterval: this.options.pingInterval, path: this.options.path }, (clientId) => {
|
|
122
|
+
this.localSubscriptions.unsubscribeAll(clientId);
|
|
123
|
+
}, !("server" in this.options));
|
|
124
|
+
}
|
|
125
|
+
async start() {
|
|
126
|
+
this.connectionsServer = this.options.subscriptions
|
|
127
|
+
? await this.createConnectionsServer()
|
|
128
|
+
: null;
|
|
100
129
|
if ("server" in this.options) {
|
|
101
130
|
return Promise.resolve();
|
|
102
131
|
}
|
|
@@ -113,7 +142,7 @@ class RpcServerImpl {
|
|
|
113
142
|
}
|
|
114
143
|
}
|
|
115
144
|
async close() {
|
|
116
|
-
await this.connectionsServer
|
|
145
|
+
await this.connectionsServer?.close();
|
|
117
146
|
await new Promise((resolve, reject) => {
|
|
118
147
|
this.httpServer.closeIdleConnections();
|
|
119
148
|
this.httpServer.close((err) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RpcServerImpl.js","sourceRoot":"","sources":["../../src/server/RpcServerImpl.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RpcServerImpl.js","sourceRoot":"","sources":["../../src/server/RpcServerImpl.ts"],"names":[],"mappings":"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"}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export type PublishServicesOptions<C extends RpcContext> = {
|
|
|
21
21
|
path: string;
|
|
22
22
|
middleware: Middleware<C>[];
|
|
23
23
|
pingInterval: number;
|
|
24
|
+
subscriptions: boolean;
|
|
24
25
|
createConnectionContext(req: IncomingMessage): Promise<RpcConnectionContext>;
|
|
25
26
|
} & ({
|
|
26
27
|
server: http.Server;
|
package/dist/server/index.js
CHANGED
|
@@ -22,6 +22,7 @@ const defaultOptions = {
|
|
|
22
22
|
host: "0.0.0.0",
|
|
23
23
|
middleware: [],
|
|
24
24
|
pingInterval: 30 * 1000, // should be in-sync with client
|
|
25
|
+
subscriptions: true,
|
|
25
26
|
async createConnectionContext(req) {
|
|
26
27
|
return {
|
|
27
28
|
clientId: req.headersDistinct[rpc_js_1.CLIENT_ID_HEADER]?.[0] || "anon",
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";;;AAAA,sCAAsF;AAGtF,yDAAgD;AAGzC,KAAK,UAAU,eAAe,CACnC,QAAW,EACX,eAA8F;IAM9F,MAAM,OAAO,GAAG;QACd,GAAG,cAAc;QACjB,GAAG,eAAe;KACnB,CAAA;IAED,MAAM,SAAS,GAAG,IAAI,gCAAa,CAAO,QAAQ,EAAE,OAAO,CAAC,CAAA;IAE5D,MAAM,SAAS,CAAC,KAAK,EAAE,CAAA;IAEvB,OAAO;QACL,QAAQ,EAAE,SAAS,CAAC,0BAA0B,EAAE;QAChD,MAAM,EAAE,SAAS;QACjB,UAAU,EAAE,SAAS,CAAC,UAAU;KACjC,CAAA;AACH,CAAC;AAtBD,0CAsBC;AAyBD,MAAM,cAAc,GAAqD;IACvE,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,SAAS;IACf,UAAU,EAAE,EAAE;IACd,YAAY,EAAE,EAAE,GAAG,IAAI,EAAE,gCAAgC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";;;AAAA,sCAAsF;AAGtF,yDAAgD;AAGzC,KAAK,UAAU,eAAe,CACnC,QAAW,EACX,eAA8F;IAM9F,MAAM,OAAO,GAAG;QACd,GAAG,cAAc;QACjB,GAAG,eAAe;KACnB,CAAA;IAED,MAAM,SAAS,GAAG,IAAI,gCAAa,CAAO,QAAQ,EAAE,OAAO,CAAC,CAAA;IAE5D,MAAM,SAAS,CAAC,KAAK,EAAE,CAAA;IAEvB,OAAO;QACL,QAAQ,EAAE,SAAS,CAAC,0BAA0B,EAAE;QAChD,MAAM,EAAE,SAAS;QACjB,UAAU,EAAE,SAAS,CAAC,UAAU;KACjC,CAAA;AACH,CAAC;AAtBD,0CAsBC;AAyBD,MAAM,cAAc,GAAqD;IACvE,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,SAAS;IACf,UAAU,EAAE,EAAE;IACd,YAAY,EAAE,EAAE,GAAG,IAAI,EAAE,gCAAgC;IACzD,aAAa,EAAE,IAAI;IAEnB,KAAK,CAAC,uBAAuB,CAAC,GAAoB;QAChD,OAAO;YACL,QAAQ,EAAE,GAAG,CAAC,eAAe,CAAC,yBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM;SAC/D,CAAA;IACH,CAAC;CACF,CAAA"}
|
package/package.json
CHANGED
|
@@ -19,6 +19,7 @@ export class RpcClientImpl<S extends Services<S>> implements RpcClient {
|
|
|
19
19
|
url,
|
|
20
20
|
this.clientId,
|
|
21
21
|
{
|
|
22
|
+
subscriptions: options.subscriptions,
|
|
22
23
|
errorDelayMaxDuration: options.errorDelayMaxDuration,
|
|
23
24
|
reconnectDelay: options.reconnectDelay,
|
|
24
25
|
pingInterval: options.pingInterval,
|
|
@@ -72,6 +73,10 @@ export class RpcClientImpl<S extends Services<S>> implements RpcClient {
|
|
|
72
73
|
})
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
async connect() {
|
|
77
|
+
await this.connection.connect()
|
|
78
|
+
}
|
|
79
|
+
|
|
75
80
|
private call = (
|
|
76
81
|
itemName: string,
|
|
77
82
|
parameters: unknown[],
|
|
@@ -102,11 +107,7 @@ export class RpcClientImpl<S extends Services<S>> implements RpcClient {
|
|
|
102
107
|
consumer(cached)
|
|
103
108
|
}
|
|
104
109
|
|
|
105
|
-
|
|
106
|
-
this.connection.connect().catch((e) => {
|
|
107
|
-
// ignored
|
|
108
|
-
})
|
|
109
|
-
}
|
|
110
|
+
void this.connection.connect()
|
|
110
111
|
|
|
111
112
|
const data = await this.invoke(
|
|
112
113
|
itemName,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import WebSocket from "ws"
|
|
2
1
|
import {log} from "../logger.js"
|
|
3
2
|
import {safeParseJson} from "../utils/json.js"
|
|
4
3
|
import {adelay} from "../utils/promises.js"
|
|
@@ -8,14 +7,15 @@ export class WebSocketConnection {
|
|
|
8
7
|
private readonly url: string,
|
|
9
8
|
private readonly clientId: string,
|
|
10
9
|
private readonly options: {
|
|
10
|
+
subscriptions: boolean
|
|
11
11
|
reconnectDelay: number
|
|
12
12
|
errorDelayMaxDuration: number
|
|
13
|
-
pingInterval: number
|
|
13
|
+
pingInterval: number | null
|
|
14
14
|
},
|
|
15
15
|
private readonly consume: (itemName: string, parameters: unknown[], data: unknown) => void,
|
|
16
16
|
private readonly onConnected: () => void
|
|
17
17
|
) {
|
|
18
|
-
this.url = url
|
|
18
|
+
this.url = url.replace(/^https(.*)/, "wss$1").replace(/^http(.*)/, "ws$1")
|
|
19
19
|
this.clientId = clientId
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -23,7 +23,7 @@ export class WebSocketConnection {
|
|
|
23
23
|
this.disconnectedMark = true
|
|
24
24
|
|
|
25
25
|
if (this.socket) {
|
|
26
|
-
this.socket!.
|
|
26
|
+
this.socket!.close()
|
|
27
27
|
this.socket = null
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -38,8 +38,15 @@ export class WebSocketConnection {
|
|
|
38
38
|
* Never rejects
|
|
39
39
|
*/
|
|
40
40
|
connect() {
|
|
41
|
+
// no subscriptions support, no need to connect
|
|
42
|
+
if (!this.options.subscriptions) {
|
|
43
|
+
return Promise.resolve()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// already started connecting
|
|
41
47
|
if (this.socket || !this.disconnectedMark) return Promise.resolve()
|
|
42
48
|
|
|
49
|
+
// start connection process
|
|
43
50
|
this.disconnectedMark = false
|
|
44
51
|
|
|
45
52
|
return new Promise<void>(async (resolve) => {
|
|
@@ -61,7 +68,9 @@ export class WebSocketConnection {
|
|
|
61
68
|
onFirstConnection()
|
|
62
69
|
onFirstConnection = () => {}
|
|
63
70
|
},
|
|
64
|
-
() => {
|
|
71
|
+
(e) => {
|
|
72
|
+
log.warn("Unable to connect WS", e)
|
|
73
|
+
|
|
65
74
|
// 2. ... unable to establish connection
|
|
66
75
|
resolve()
|
|
67
76
|
}
|
|
@@ -101,7 +110,7 @@ export class WebSocketConnection {
|
|
|
101
110
|
|
|
102
111
|
let connected = false
|
|
103
112
|
|
|
104
|
-
socket.
|
|
113
|
+
socket.addEventListener("open", () => {
|
|
105
114
|
this.socket = socket
|
|
106
115
|
connected = true
|
|
107
116
|
resolve()
|
|
@@ -111,11 +120,11 @@ export class WebSocketConnection {
|
|
|
111
120
|
this.onConnected()
|
|
112
121
|
})
|
|
113
122
|
|
|
114
|
-
socket.
|
|
123
|
+
socket.addEventListener("ping", () => {
|
|
115
124
|
this.heartbeat()
|
|
116
125
|
})
|
|
117
126
|
|
|
118
|
-
socket.
|
|
127
|
+
socket.addEventListener("close", () => {
|
|
119
128
|
this.socket = null
|
|
120
129
|
|
|
121
130
|
if (connected) {
|
|
@@ -127,13 +136,11 @@ export class WebSocketConnection {
|
|
|
127
136
|
}
|
|
128
137
|
})
|
|
129
138
|
|
|
130
|
-
socket.
|
|
139
|
+
socket.addEventListener("error", (e) => {
|
|
131
140
|
if (!connected) {
|
|
132
141
|
reject(e)
|
|
133
142
|
}
|
|
134
143
|
|
|
135
|
-
log.warn("WS connection error", e.message)
|
|
136
|
-
|
|
137
144
|
try {
|
|
138
145
|
socket.close()
|
|
139
146
|
} catch (e) {
|
|
@@ -141,8 +148,8 @@ export class WebSocketConnection {
|
|
|
141
148
|
}
|
|
142
149
|
})
|
|
143
150
|
|
|
144
|
-
socket.
|
|
145
|
-
this.receiveSocketMessage(message)
|
|
151
|
+
socket.addEventListener("message", (message) => {
|
|
152
|
+
this.receiveSocketMessage(message.data)
|
|
146
153
|
})
|
|
147
154
|
} catch (e) {
|
|
148
155
|
reject(e)
|
|
@@ -159,12 +166,14 @@ export class WebSocketConnection {
|
|
|
159
166
|
clearTimeout(this.pingTimeout)
|
|
160
167
|
}
|
|
161
168
|
|
|
162
|
-
this.
|
|
163
|
-
this.
|
|
164
|
-
|
|
169
|
+
if (this.options.pingInterval) {
|
|
170
|
+
this.pingTimeout = setTimeout(() => {
|
|
171
|
+
this.socket?.close()
|
|
172
|
+
}, this.options.pingInterval * 1.5)
|
|
173
|
+
}
|
|
165
174
|
}
|
|
166
175
|
|
|
167
|
-
private async receiveSocketMessage(rawMessage:
|
|
176
|
+
private async receiveSocketMessage(rawMessage: string | ArrayBuffer | Blob) {
|
|
168
177
|
try {
|
|
169
178
|
const msg = rawMessage.toString()
|
|
170
179
|
|
package/src/client/index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {RpcContext, Services} from "../rpc.js"
|
|
2
2
|
import {ServicesWithSubscriptions} from "./remote.js"
|
|
3
|
-
import WebSocket from "ws"
|
|
4
3
|
import {RpcClientImpl} from "./RpcClientImpl.js"
|
|
5
4
|
import {Middleware} from "../utils/middleware.js"
|
|
6
5
|
|
|
@@ -15,11 +14,12 @@ export type RpcClient = {
|
|
|
15
14
|
|
|
16
15
|
export type ConsumeServicesOptions = {
|
|
17
16
|
callTimeout: number
|
|
18
|
-
subscribe: boolean
|
|
19
17
|
reconnectDelay: number
|
|
20
18
|
errorDelayMaxDuration: number
|
|
21
|
-
pingInterval: number
|
|
19
|
+
pingInterval: number | null
|
|
20
|
+
subscriptions: boolean
|
|
22
21
|
middleware: Middleware<RpcContext>[]
|
|
22
|
+
connectOnCreate: boolean
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export async function consumeServices<S extends Services<S>>(
|
|
@@ -40,6 +40,10 @@ export async function consumeServices<S extends Services<S>>(
|
|
|
40
40
|
|
|
41
41
|
const client = new RpcClientImpl<S>(url, options)
|
|
42
42
|
|
|
43
|
+
if (options.connectOnCreate) {
|
|
44
|
+
await client.connect()
|
|
45
|
+
}
|
|
46
|
+
|
|
43
47
|
return {
|
|
44
48
|
client,
|
|
45
49
|
remote: client.createRemote(),
|
|
@@ -48,9 +52,10 @@ export async function consumeServices<S extends Services<S>>(
|
|
|
48
52
|
|
|
49
53
|
const defaultOptions: ConsumeServicesOptions = {
|
|
50
54
|
callTimeout: 5 * 1000,
|
|
51
|
-
subscribe: true,
|
|
52
55
|
reconnectDelay: 0,
|
|
53
56
|
errorDelayMaxDuration: 15 * 1000,
|
|
54
|
-
pingInterval:
|
|
57
|
+
pingInterval: null, // if set, should be in-sync with server, ie 30 * 1000
|
|
58
|
+
subscriptions: true,
|
|
55
59
|
middleware: [],
|
|
60
|
+
connectOnCreate: false,
|
|
56
61
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {PublishServicesOptions, RpcServer} from "./index.js"
|
|
2
2
|
import {LocalSubscriptions} from "./LocalSubscriptions.js"
|
|
3
3
|
import http from "http"
|
|
4
|
-
import {ConnectionsServer} from "./ConnectionsServer.js"
|
|
4
|
+
import type {ConnectionsServer} from "./ConnectionsServer.js"
|
|
5
5
|
import {PromiseCache} from "../utils/promises.js"
|
|
6
6
|
import {serveHttpRequest} from "./http.js"
|
|
7
7
|
import {
|
|
@@ -38,15 +38,6 @@ export class RpcServerImpl<S extends Services<S>, C extends RpcContext> implemen
|
|
|
38
38
|
})
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
this.connectionsServer = new ConnectionsServer(
|
|
42
|
-
this.httpServer,
|
|
43
|
-
{pingInterval: options.pingInterval, path: options.path},
|
|
44
|
-
(clientId) => {
|
|
45
|
-
this.localSubscriptions.unsubscribeAll(clientId)
|
|
46
|
-
},
|
|
47
|
-
!("server" in this.options)
|
|
48
|
-
)
|
|
49
|
-
|
|
50
41
|
this.httpServer.addListener("request", (req, res) =>
|
|
51
42
|
serveHttpRequest(
|
|
52
43
|
req,
|
|
@@ -62,7 +53,24 @@ export class RpcServerImpl<S extends Services<S>, C extends RpcContext> implemen
|
|
|
62
53
|
)
|
|
63
54
|
}
|
|
64
55
|
|
|
65
|
-
|
|
56
|
+
private async createConnectionsServer() {
|
|
57
|
+
const {ConnectionsServer} = await import("./ConnectionsServer.js")
|
|
58
|
+
|
|
59
|
+
return new ConnectionsServer(
|
|
60
|
+
this.httpServer,
|
|
61
|
+
{pingInterval: this.options.pingInterval, path: this.options.path},
|
|
62
|
+
(clientId) => {
|
|
63
|
+
this.localSubscriptions.unsubscribeAll(clientId)
|
|
64
|
+
},
|
|
65
|
+
!("server" in this.options)
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async start() {
|
|
70
|
+
this.connectionsServer = this.options.subscriptions
|
|
71
|
+
? await this.createConnectionsServer()
|
|
72
|
+
: null
|
|
73
|
+
|
|
66
74
|
if ("server" in this.options) {
|
|
67
75
|
return Promise.resolve()
|
|
68
76
|
}
|
|
@@ -83,7 +91,7 @@ export class RpcServerImpl<S extends Services<S>, C extends RpcContext> implemen
|
|
|
83
91
|
}
|
|
84
92
|
|
|
85
93
|
async close() {
|
|
86
|
-
await this.connectionsServer
|
|
94
|
+
await this.connectionsServer?.close()
|
|
87
95
|
await new Promise<void>((resolve, reject) => {
|
|
88
96
|
this.httpServer.closeIdleConnections()
|
|
89
97
|
this.httpServer.close((err) => {
|
|
@@ -103,7 +111,7 @@ export class RpcServerImpl<S extends Services<S>, C extends RpcContext> implemen
|
|
|
103
111
|
|
|
104
112
|
private readonly localSubscriptions = new LocalSubscriptions()
|
|
105
113
|
private readonly invocationCache = new PromiseCache()
|
|
106
|
-
private
|
|
114
|
+
private connectionsServer: ConnectionsServer | null = null
|
|
107
115
|
readonly httpServer
|
|
108
116
|
|
|
109
117
|
private call = async (
|
|
@@ -169,7 +177,7 @@ export class RpcServerImpl<S extends Services<S>, C extends RpcContext> implemen
|
|
|
169
177
|
|
|
170
178
|
if (newDataJson != lastDataJson) {
|
|
171
179
|
lastDataJson = newDataJson
|
|
172
|
-
this.connectionsServer
|
|
180
|
+
this.connectionsServer?.publish(
|
|
173
181
|
connectionContext.clientId,
|
|
174
182
|
itemName,
|
|
175
183
|
parameters,
|
package/src/server/index.ts
CHANGED
|
@@ -36,10 +36,10 @@ export type RpcServer = {
|
|
|
36
36
|
|
|
37
37
|
export type PublishServicesOptions<C extends RpcContext> = {
|
|
38
38
|
host: string
|
|
39
|
-
|
|
40
39
|
path: string
|
|
41
40
|
middleware: Middleware<C>[]
|
|
42
41
|
pingInterval: number
|
|
42
|
+
subscriptions: boolean
|
|
43
43
|
createConnectionContext(req: IncomingMessage): Promise<RpcConnectionContext>
|
|
44
44
|
} & (
|
|
45
45
|
| {
|
|
@@ -56,6 +56,7 @@ const defaultOptions: Omit<PublishServicesOptions<RpcContext>, "port"> = {
|
|
|
56
56
|
host: "0.0.0.0",
|
|
57
57
|
middleware: [],
|
|
58
58
|
pingInterval: 30 * 1000, // should be in-sync with client
|
|
59
|
+
subscriptions: true,
|
|
59
60
|
|
|
60
61
|
async createConnectionContext(req: IncomingMessage): Promise<RpcConnectionContext> {
|
|
61
62
|
return {
|
package/tests/subscriptions.ts
CHANGED
|
@@ -17,7 +17,7 @@ describe("Subscriptions", () => {
|
|
|
17
17
|
|
|
18
18
|
let receivedItem
|
|
19
19
|
|
|
20
|
-
await client.test.item.subscribe(() => {
|
|
20
|
+
await client.test.item.subscribe((item) => {
|
|
21
21
|
receivedItem = item
|
|
22
22
|
})
|
|
23
23
|
|
|
@@ -25,6 +25,39 @@ describe("Subscriptions", () => {
|
|
|
25
25
|
assert.deepEqual(receivedItem, item)
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
+
it("disabled subscribe", async () => {
|
|
29
|
+
const item = {r: "1"}
|
|
30
|
+
|
|
31
|
+
const services = await startTestServer(
|
|
32
|
+
{
|
|
33
|
+
test: {
|
|
34
|
+
item: async () => item,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
subscriptions: false,
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
const client = await createTestClient<typeof services>({
|
|
43
|
+
subscriptions: false,
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
let receivedItem
|
|
47
|
+
|
|
48
|
+
await client.test.item.subscribe((item) => {
|
|
49
|
+
receivedItem = item
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
receivedItem = null
|
|
53
|
+
|
|
54
|
+
item.r = "2"
|
|
55
|
+
services.test.item.trigger()
|
|
56
|
+
await adelay(20)
|
|
57
|
+
|
|
58
|
+
assert.equal(receivedItem, null)
|
|
59
|
+
})
|
|
60
|
+
|
|
28
61
|
it("error in supplier breaks subscribe", async () => {
|
|
29
62
|
const services = await startTestServer({
|
|
30
63
|
item: async () => {
|
package/tests/testUtils.ts
CHANGED
package/tsconfig.cjs.json
CHANGED