@itwin/core-mobile 4.0.0-dev.8 → 4.0.0-dev.81
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/CHANGELOG.md +48 -1
- package/README.md +1 -1
- package/lib/cjs/MobileBackend.d.ts +7 -7
- package/lib/cjs/MobileBackend.js +28 -24
- package/lib/cjs/MobileBackend.js.map +1 -1
- package/lib/cjs/MobileFrontend.d.ts +5 -5
- package/lib/cjs/MobileFrontend.js +25 -21
- package/lib/cjs/MobileFrontend.js.map +1 -1
- package/lib/cjs/__DOC_ONLY__.d.ts +33 -33
- package/lib/cjs/__DOC_ONLY__.js +56 -52
- package/lib/cjs/__DOC_ONLY__.js.map +1 -1
- package/lib/cjs/backend/MobileAuthorizationBackend.d.ts +17 -17
- package/lib/cjs/backend/MobileAuthorizationBackend.js +46 -46
- package/lib/cjs/backend/MobileAuthorizationBackend.js.map +1 -1
- package/lib/cjs/backend/MobileFileHandler.d.ts +112 -112
- package/lib/cjs/backend/MobileFileHandler.d.ts.map +1 -1
- package/lib/cjs/backend/MobileFileHandler.js +263 -263
- package/lib/cjs/backend/MobileFileHandler.js.map +1 -1
- package/lib/cjs/backend/MobileHost.d.ts +72 -72
- package/lib/cjs/backend/MobileHost.d.ts.map +1 -1
- package/lib/cjs/backend/MobileHost.js +149 -156
- package/lib/cjs/backend/MobileHost.js.map +1 -1
- package/lib/cjs/backend/MobileRpcServer.d.ts +19 -19
- package/lib/cjs/backend/MobileRpcServer.js +156 -156
- package/lib/cjs/backend/MobileRpcServer.js.map +1 -1
- package/lib/cjs/backend/Request.d.ts +117 -149
- package/lib/cjs/backend/Request.d.ts.map +1 -1
- package/lib/cjs/backend/Request.js +255 -267
- package/lib/cjs/backend/Request.js.map +1 -1
- package/lib/cjs/common/MobileAppChannel.d.ts +4 -4
- package/lib/cjs/common/MobileAppChannel.js +11 -11
- package/lib/cjs/common/MobileAppChannel.js.map +1 -1
- package/lib/cjs/common/MobileAppProps.d.ts +35 -35
- package/lib/cjs/common/MobileAppProps.d.ts.map +1 -1
- package/lib/cjs/common/MobileAppProps.js +26 -26
- package/lib/cjs/common/MobileAppProps.js.map +1 -1
- package/lib/cjs/common/MobileEventLoop.d.ts +11 -11
- package/lib/cjs/common/MobileEventLoop.js +30 -30
- package/lib/cjs/common/MobileEventLoop.js.map +1 -1
- package/lib/cjs/common/MobileIpc.d.ts +17 -17
- package/lib/cjs/common/MobileIpc.js +70 -70
- package/lib/cjs/common/MobileIpc.js.map +1 -1
- package/lib/cjs/common/MobilePush.d.ts +20 -20
- package/lib/cjs/common/MobilePush.js +53 -53
- package/lib/cjs/common/MobilePush.js.map +1 -1
- package/lib/cjs/common/MobileRpcManager.d.ts +40 -40
- package/lib/cjs/common/MobileRpcManager.js +110 -110
- package/lib/cjs/common/MobileRpcManager.js.map +1 -1
- package/lib/cjs/common/MobileRpcProtocol.d.ts +58 -58
- package/lib/cjs/common/MobileRpcProtocol.d.ts.map +1 -1
- package/lib/cjs/common/MobileRpcProtocol.js +277 -277
- package/lib/cjs/common/MobileRpcProtocol.js.map +1 -1
- package/lib/cjs/common/MobileRpcRequest.d.ts +20 -20
- package/lib/cjs/common/MobileRpcRequest.js +50 -50
- package/lib/cjs/common/MobileRpcRequest.js.map +1 -1
- package/lib/cjs/frontend/MobileApp.d.ts +23 -23
- package/lib/cjs/frontend/MobileApp.d.ts.map +1 -1
- package/lib/cjs/frontend/MobileApp.js +79 -80
- package/lib/cjs/frontend/MobileApp.js.map +1 -1
- package/lib/cjs/frontend/MobileAuthorizationFrontend.d.ts +17 -17
- package/lib/cjs/frontend/MobileAuthorizationFrontend.d.ts.map +1 -1
- package/lib/cjs/frontend/MobileAuthorizationFrontend.js +54 -46
- package/lib/cjs/frontend/MobileAuthorizationFrontend.js.map +1 -1
- package/lib/cjs/test/ios/MobilePlatform.test.d.ts +1 -1
- package/lib/cjs/test/ios/MobilePlatform.test.js +84 -84
- package/lib/cjs/test/ios/MobilePlatform.test.js.map +1 -1
- package/package.json +18 -26
|
@@ -1,157 +1,157 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*---------------------------------------------------------------------------------------------
|
|
3
|
-
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
-
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
-
*--------------------------------------------------------------------------------------------*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.setupMobileRpc = exports.MobileRpcServer = void 0;
|
|
8
|
-
const ws = require("ws");
|
|
9
|
-
const core_common_1 = require("@itwin/core-common");
|
|
10
|
-
const MobileRpcProtocol_1 = require("../common/MobileRpcProtocol");
|
|
11
|
-
const MobileRpcManager_1 = require("../common/MobileRpcManager");
|
|
12
|
-
const MobileHost_1 = require("./MobileHost");
|
|
13
|
-
const core_bentley_1 = require("@itwin/core-bentley");
|
|
14
|
-
let addon;
|
|
15
|
-
/** @internal */
|
|
16
|
-
class MobileRpcServer {
|
|
17
|
-
constructor() {
|
|
18
|
-
/* _pingTime is a fix for ios/mobile case where when the app moves into foreground from
|
|
19
|
-
* background backend restart ws.Server and then notify frontend to reconnect. But ws.Server
|
|
20
|
-
* listening event is not fired as node yield to kevent and wait for some io event to happen.
|
|
21
|
-
* This causes a delay in reconnection which may be as long a 40 secs. To solve the issue we
|
|
22
|
-
* create _pingTimer which causes kevent to yield back to uv poll so timer event can be fired.
|
|
23
|
-
* This allow listening event to go through quickly (max 5ms). Once the listening event occur we
|
|
24
|
-
* clear the timer. Here we use setInterval() just to make sure otherwise setTimeout() could equally
|
|
25
|
-
* be effective
|
|
26
|
-
*/
|
|
27
|
-
this._pingTimer = setInterval(() => { }, 5);
|
|
28
|
-
this._port = MobileRpcManager_1.MobileRpcConfiguration.setup.obtainPort();
|
|
29
|
-
this._server = new ws.Server({ port: this._port });
|
|
30
|
-
this._connectionId = ++MobileRpcServer._nextId;
|
|
31
|
-
MobileRpcServer.interop.connectionId = this._connectionId;
|
|
32
|
-
this._onListening();
|
|
33
|
-
this._onConnection();
|
|
34
|
-
}
|
|
35
|
-
_onListening() {
|
|
36
|
-
this._server.on("listening", () => {
|
|
37
|
-
const address = this._server.address();
|
|
38
|
-
this._port = address.port;
|
|
39
|
-
clearInterval(this._pingTimer);
|
|
40
|
-
this._notifyListening();
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
_notifyListening() {
|
|
44
|
-
MobileRpcServer.interop.port = this._port;
|
|
45
|
-
if (addon) {
|
|
46
|
-
addon.notifyListening(this._port);
|
|
47
|
-
}
|
|
48
|
-
if (this._connectionId !== 0) {
|
|
49
|
-
MobileHost_1.MobileHost.reconnect(this._port);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
_onConnection() {
|
|
53
|
-
this._server.on("connection", (connection) => {
|
|
54
|
-
this._connection = connection;
|
|
55
|
-
this._connection.on("message", (data) => this._onConnectionMessage(data));
|
|
56
|
-
this._createSender();
|
|
57
|
-
global.__iTwinJsRpcReady = true;
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
_createSender() {
|
|
61
|
-
const sender = (message, connectionId) => {
|
|
62
|
-
if (connectionId !== this._connectionId) {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
this._connection.send(message, (err) => {
|
|
66
|
-
if (err) {
|
|
67
|
-
throw err;
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
};
|
|
71
|
-
MobileRpcServer.interop.sendString = sender;
|
|
72
|
-
MobileRpcServer.interop.sendBinary = sender;
|
|
73
|
-
}
|
|
74
|
-
_onConnectionMessage(data) {
|
|
75
|
-
let message = data;
|
|
76
|
-
if (Array.isArray(message)) {
|
|
77
|
-
throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "Unsupported data type");
|
|
78
|
-
}
|
|
79
|
-
if (Buffer.isBuffer(message)) {
|
|
80
|
-
if (message.byteOffset !== 0 || message.byteLength !== message.buffer.byteLength) {
|
|
81
|
-
message = new Uint8Array(message.buffer, message.byteOffset, message.byteLength);
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
message = message.buffer;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
MobileRpcServer.interop.handler(message, this._connectionId);
|
|
88
|
-
}
|
|
89
|
-
dispose() {
|
|
90
|
-
clearInterval(this._pingTimer);
|
|
91
|
-
if (this._connection) {
|
|
92
|
-
MobileRpcServer.interop.sendString = () => { };
|
|
93
|
-
MobileRpcServer.interop.sendBinary = () => { };
|
|
94
|
-
this._connection.close();
|
|
95
|
-
}
|
|
96
|
-
this._server.close();
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
MobileRpcServer.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
let mobileReady = false;
|
|
109
|
-
let hasSuspended = false;
|
|
110
|
-
function setupMobileRpc() {
|
|
111
|
-
if (mobileReady) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
if (core_bentley_1.ProcessDetector.isMobileAppBackend) {
|
|
115
|
-
addon = process._linkedBinding("iModelJsMobile");
|
|
116
|
-
addon
|
|
117
|
-
}
|
|
118
|
-
let server = new MobileRpcServer();
|
|
119
|
-
/* The UV event loop (internal to node) is retained by handles,
|
|
120
|
-
such as those created for setInterval/setTimeout and client/server connections.
|
|
121
|
-
In a simple app, the RPC server may be the only handle retaining the UV loop.
|
|
122
|
-
Thus, we install a temporary timer on suspend to prevent the loop from exiting prematurely.
|
|
123
|
-
*/
|
|
124
|
-
let retainUvLoop;
|
|
125
|
-
MobileHost_1.MobileHost.onEnterBackground.addListener(() => {
|
|
126
|
-
hasSuspended = true;
|
|
127
|
-
if (server === null) {
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
retainUvLoop = setInterval(() => { }, 1000);
|
|
131
|
-
server.dispose();
|
|
132
|
-
server = null;
|
|
133
|
-
});
|
|
134
|
-
MobileHost_1.MobileHost.onEnterForeground.addListener(() => {
|
|
135
|
-
if (!hasSuspended) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
server = new MobileRpcServer();
|
|
139
|
-
clearInterval(retainUvLoop);
|
|
140
|
-
retainUvLoop = undefined;
|
|
141
|
-
});
|
|
142
|
-
MobileHost_1.MobileHost.onWillTerminate.addListener(() => {
|
|
143
|
-
if (typeof (retainUvLoop) !== "undefined") {
|
|
144
|
-
clearInterval(retainUvLoop);
|
|
145
|
-
retainUvLoop = undefined;
|
|
146
|
-
}
|
|
147
|
-
if (server === null) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
server.dispose();
|
|
151
|
-
server = null;
|
|
152
|
-
});
|
|
153
|
-
MobileRpcProtocol_1.MobileRpcProtocol.obtainInterop = () => MobileRpcServer.interop;
|
|
154
|
-
mobileReady = true;
|
|
155
|
-
}
|
|
156
|
-
exports.setupMobileRpc = setupMobileRpc;
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.setupMobileRpc = exports.MobileRpcServer = void 0;
|
|
8
|
+
const ws = require("ws");
|
|
9
|
+
const core_common_1 = require("@itwin/core-common");
|
|
10
|
+
const MobileRpcProtocol_1 = require("../common/MobileRpcProtocol");
|
|
11
|
+
const MobileRpcManager_1 = require("../common/MobileRpcManager");
|
|
12
|
+
const MobileHost_1 = require("./MobileHost");
|
|
13
|
+
const core_bentley_1 = require("@itwin/core-bentley");
|
|
14
|
+
let addon;
|
|
15
|
+
/** @internal */
|
|
16
|
+
class MobileRpcServer {
|
|
17
|
+
constructor() {
|
|
18
|
+
/* _pingTime is a fix for ios/mobile case where when the app moves into foreground from
|
|
19
|
+
* background backend restart ws.Server and then notify frontend to reconnect. But ws.Server
|
|
20
|
+
* listening event is not fired as node yield to kevent and wait for some io event to happen.
|
|
21
|
+
* This causes a delay in reconnection which may be as long a 40 secs. To solve the issue we
|
|
22
|
+
* create _pingTimer which causes kevent to yield back to uv poll so timer event can be fired.
|
|
23
|
+
* This allow listening event to go through quickly (max 5ms). Once the listening event occur we
|
|
24
|
+
* clear the timer. Here we use setInterval() just to make sure otherwise setTimeout() could equally
|
|
25
|
+
* be effective
|
|
26
|
+
*/
|
|
27
|
+
this._pingTimer = setInterval(() => { }, 5);
|
|
28
|
+
this._port = MobileRpcManager_1.MobileRpcConfiguration.setup.obtainPort();
|
|
29
|
+
this._server = new ws.Server({ port: this._port });
|
|
30
|
+
this._connectionId = ++MobileRpcServer._nextId;
|
|
31
|
+
MobileRpcServer.interop.connectionId = this._connectionId;
|
|
32
|
+
this._onListening();
|
|
33
|
+
this._onConnection();
|
|
34
|
+
}
|
|
35
|
+
_onListening() {
|
|
36
|
+
this._server.on("listening", () => {
|
|
37
|
+
const address = this._server.address();
|
|
38
|
+
this._port = address.port;
|
|
39
|
+
clearInterval(this._pingTimer);
|
|
40
|
+
this._notifyListening();
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
_notifyListening() {
|
|
44
|
+
MobileRpcServer.interop.port = this._port;
|
|
45
|
+
if (addon) {
|
|
46
|
+
addon.notifyListening(this._port);
|
|
47
|
+
}
|
|
48
|
+
if (this._connectionId !== 0) {
|
|
49
|
+
MobileHost_1.MobileHost.reconnect(this._port);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
_onConnection() {
|
|
53
|
+
this._server.on("connection", (connection) => {
|
|
54
|
+
this._connection = connection;
|
|
55
|
+
this._connection.on("message", (data) => this._onConnectionMessage(data));
|
|
56
|
+
this._createSender();
|
|
57
|
+
global.__iTwinJsRpcReady = true;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
_createSender() {
|
|
61
|
+
const sender = (message, connectionId) => {
|
|
62
|
+
if (connectionId !== this._connectionId) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
this._connection.send(message, (err) => {
|
|
66
|
+
if (err) {
|
|
67
|
+
throw err;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
MobileRpcServer.interop.sendString = sender;
|
|
72
|
+
MobileRpcServer.interop.sendBinary = sender;
|
|
73
|
+
}
|
|
74
|
+
_onConnectionMessage(data) {
|
|
75
|
+
let message = data;
|
|
76
|
+
if (Array.isArray(message)) {
|
|
77
|
+
throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "Unsupported data type");
|
|
78
|
+
}
|
|
79
|
+
if (Buffer.isBuffer(message)) {
|
|
80
|
+
if (message.byteOffset !== 0 || message.byteLength !== message.buffer.byteLength) {
|
|
81
|
+
message = new Uint8Array(message.buffer, message.byteOffset, message.byteLength);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
message = message.buffer;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
MobileRpcServer.interop.handler(message, this._connectionId);
|
|
88
|
+
}
|
|
89
|
+
dispose() {
|
|
90
|
+
clearInterval(this._pingTimer);
|
|
91
|
+
if (this._connection) {
|
|
92
|
+
MobileRpcServer.interop.sendString = () => { };
|
|
93
|
+
MobileRpcServer.interop.sendBinary = () => { };
|
|
94
|
+
this._connection.close();
|
|
95
|
+
}
|
|
96
|
+
this._server.close();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
MobileRpcServer._nextId = -1;
|
|
100
|
+
MobileRpcServer.interop = {
|
|
101
|
+
handler: (_payload) => { throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "Not implemented."); },
|
|
102
|
+
sendString: (_message, _connectionId) => { throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "No connection."); },
|
|
103
|
+
sendBinary: (_message, _connectionId) => { throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "No connection."); },
|
|
104
|
+
port: 0,
|
|
105
|
+
connectionId: 0,
|
|
106
|
+
};
|
|
107
|
+
exports.MobileRpcServer = MobileRpcServer;
|
|
108
|
+
let mobileReady = false;
|
|
109
|
+
let hasSuspended = false;
|
|
110
|
+
function setupMobileRpc() {
|
|
111
|
+
if (mobileReady) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (core_bentley_1.ProcessDetector.isMobileAppBackend) {
|
|
115
|
+
addon = process._linkedBinding("iModelJsMobile");
|
|
116
|
+
addon?.registerDeviceImpl();
|
|
117
|
+
}
|
|
118
|
+
let server = new MobileRpcServer();
|
|
119
|
+
/* The UV event loop (internal to node) is retained by handles,
|
|
120
|
+
such as those created for setInterval/setTimeout and client/server connections.
|
|
121
|
+
In a simple app, the RPC server may be the only handle retaining the UV loop.
|
|
122
|
+
Thus, we install a temporary timer on suspend to prevent the loop from exiting prematurely.
|
|
123
|
+
*/
|
|
124
|
+
let retainUvLoop;
|
|
125
|
+
MobileHost_1.MobileHost.onEnterBackground.addListener(() => {
|
|
126
|
+
hasSuspended = true;
|
|
127
|
+
if (server === null) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
retainUvLoop = setInterval(() => { }, 1000);
|
|
131
|
+
server.dispose();
|
|
132
|
+
server = null;
|
|
133
|
+
});
|
|
134
|
+
MobileHost_1.MobileHost.onEnterForeground.addListener(() => {
|
|
135
|
+
if (!hasSuspended) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
server = new MobileRpcServer();
|
|
139
|
+
clearInterval(retainUvLoop);
|
|
140
|
+
retainUvLoop = undefined;
|
|
141
|
+
});
|
|
142
|
+
MobileHost_1.MobileHost.onWillTerminate.addListener(() => {
|
|
143
|
+
if (typeof (retainUvLoop) !== "undefined") {
|
|
144
|
+
clearInterval(retainUvLoop);
|
|
145
|
+
retainUvLoop = undefined;
|
|
146
|
+
}
|
|
147
|
+
if (server === null) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
server.dispose();
|
|
151
|
+
server = null;
|
|
152
|
+
});
|
|
153
|
+
MobileRpcProtocol_1.MobileRpcProtocol.obtainInterop = () => MobileRpcServer.interop;
|
|
154
|
+
mobileReady = true;
|
|
155
|
+
}
|
|
156
|
+
exports.setupMobileRpc = setupMobileRpc;
|
|
157
157
|
//# sourceMappingURL=MobileRpcServer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobileRpcServer.js","sourceRoot":"","sources":["../../../src/backend/MobileRpcServer.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport * as ws from \"ws\";\r\nimport { BentleyStatus, IModelError } from \"@itwin/core-common\";\r\nimport { MobileRpcGateway, MobileRpcProtocol } from \"../common/MobileRpcProtocol\";\r\nimport { MobileRpcConfiguration } from \"../common/MobileRpcManager\";\r\nimport { MobileHost } from \"./MobileHost\";\r\nimport { ProcessDetector } from \"@itwin/core-bentley\";\r\n\r\n/* eslint-disable deprecation/deprecation */\r\n\r\ninterface MobileAddon {\r\n notifyListening: (port: number) => void;\r\n registerDeviceImpl: () => void;\r\n}\r\n\r\nlet addon: MobileAddon | undefined;\r\n\r\n/** @internal */\r\nexport class MobileRpcServer {\r\n private static _nextId = -1;\r\n\r\n public static interop: MobileRpcGateway = {\r\n handler: (_payload: ArrayBuffer | string) => { throw new IModelError(BentleyStatus.ERROR, \"Not implemented.\"); },\r\n sendString: (_message: string, _connectionId: number) => { throw new IModelError(BentleyStatus.ERROR, \"No connection.\"); },\r\n sendBinary: (_message: Uint8Array, _connectionId: number) => { throw new IModelError(BentleyStatus.ERROR, \"No connection.\"); },\r\n port: 0,\r\n connectionId: 0,\r\n };\r\n\r\n private _server: ws.Server;\r\n private _connection: ws | undefined;\r\n private _port: number;\r\n private _connectionId: number;\r\n private _pingTimer: NodeJS.Timeout;\r\n public constructor() {\r\n /* _pingTime is a fix for ios/mobile case where when the app moves into foreground from\r\n * background backend restart ws.Server and then notify frontend to reconnect. But ws.Server\r\n * listening event is not fired as node yield to kevent and wait for some io event to happen.\r\n * This causes a delay in reconnection which may be as long a 40 secs. To solve the issue we\r\n * create _pingTimer which causes kevent to yield back to uv poll so timer event can be fired.\r\n * This allow listening event to go through quickly (max 5ms). Once the listening event occur we\r\n * clear the timer. Here we use setInterval() just to make sure otherwise setTimeout() could equally\r\n * be effective\r\n */\r\n this._pingTimer = setInterval(() => { }, 5);\r\n this._port = MobileRpcConfiguration.setup.obtainPort();\r\n this._server = new ws.Server({ port: this._port });\r\n this._connectionId = ++MobileRpcServer._nextId;\r\n MobileRpcServer.interop.connectionId = this._connectionId;\r\n this._onListening();\r\n this._onConnection();\r\n }\r\n\r\n private _onListening() {\r\n this._server.on(\"listening\", () => {\r\n const address = this._server.address() as ws.AddressInfo;\r\n this._port = address.port;\r\n clearInterval(this._pingTimer);\r\n this._notifyListening();\r\n });\r\n }\r\n\r\n private _notifyListening() {\r\n MobileRpcServer.interop.port = this._port;\r\n\r\n if (addon) {\r\n addon.notifyListening(this._port);\r\n }\r\n\r\n if (this._connectionId !== 0) {\r\n MobileHost.reconnect(this._port);\r\n }\r\n }\r\n\r\n private _onConnection() {\r\n this._server.on(\"connection\", (connection) => {\r\n this._connection = connection;\r\n this._connection.on(\"message\", (data) => this._onConnectionMessage(data));\r\n this._createSender();\r\n (global as any).__iTwinJsRpcReady = true;\r\n });\r\n }\r\n\r\n private _createSender() {\r\n const sender = (message: string | Uint8Array, connectionId: number) => {\r\n if (connectionId !== this._connectionId) {\r\n return;\r\n }\r\n\r\n this._connection!.send(message, (err) => {\r\n if (err) {\r\n throw err;\r\n }\r\n });\r\n };\r\n\r\n MobileRpcServer.interop.sendString = sender;\r\n MobileRpcServer.interop.sendBinary = sender;\r\n }\r\n\r\n private _onConnectionMessage(data: ws.Data) {\r\n let message = data;\r\n if (Array.isArray(message)) {\r\n throw new IModelError(BentleyStatus.ERROR, \"Unsupported data type\");\r\n }\r\n\r\n if (Buffer.isBuffer(message)) {\r\n if (message.byteOffset !== 0 || message.byteLength !== message.buffer.byteLength) {\r\n message = new Uint8Array(message.buffer, message.byteOffset, message.byteLength);\r\n } else {\r\n message = message.buffer;\r\n }\r\n }\r\n\r\n MobileRpcServer.interop.handler(message, this._connectionId);\r\n }\r\n\r\n public dispose() {\r\n clearInterval(this._pingTimer);\r\n if (this._connection) {\r\n MobileRpcServer.interop.sendString = () => { };\r\n MobileRpcServer.interop.sendBinary = () => { };\r\n this._connection.close();\r\n }\r\n\r\n this._server.close();\r\n }\r\n}\r\n\r\nlet mobileReady = false;\r\nlet hasSuspended = false;\r\n\r\nexport function setupMobileRpc() {\r\n if (mobileReady) {\r\n return;\r\n }\r\n\r\n if (ProcessDetector.isMobileAppBackend) {\r\n addon = (process as any)._linkedBinding(\"iModelJsMobile\");\r\n addon?.registerDeviceImpl();\r\n }\r\n\r\n let server: MobileRpcServer | null = new MobileRpcServer();\r\n\r\n /* The UV event loop (internal to node) is retained by handles,\r\n such as those created for setInterval/setTimeout and client/server connections.\r\n In a simple app, the RPC server may be the only handle retaining the UV loop.\r\n Thus, we install a temporary timer on suspend to prevent the loop from exiting prematurely.\r\n */\r\n let retainUvLoop: NodeJS.Timer | undefined;\r\n\r\n MobileHost.onEnterBackground.addListener(() => {\r\n hasSuspended = true;\r\n\r\n if (server === null) {\r\n return;\r\n }\r\n\r\n retainUvLoop = setInterval(() => { }, 1000);\r\n server.dispose();\r\n server = null;\r\n });\r\n\r\n MobileHost.onEnterForeground.addListener(() => {\r\n if (!hasSuspended) {\r\n return;\r\n }\r\n\r\n server = new MobileRpcServer();\r\n clearInterval(retainUvLoop);\r\n retainUvLoop = undefined;\r\n });\r\n\r\n MobileHost.onWillTerminate.addListener(() => {\r\n if (typeof (retainUvLoop) !== \"undefined\") {\r\n clearInterval(retainUvLoop);\r\n retainUvLoop = undefined;\r\n }\r\n\r\n if (server === null) {\r\n return;\r\n }\r\n\r\n server.dispose();\r\n server = null;\r\n });\r\n\r\n MobileRpcProtocol.obtainInterop = () => MobileRpcServer.interop;\r\n mobileReady = true;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"MobileRpcServer.js","sourceRoot":"","sources":["../../../src/backend/MobileRpcServer.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport * as ws from \"ws\";\nimport { BentleyStatus, IModelError } from \"@itwin/core-common\";\nimport { MobileRpcGateway, MobileRpcProtocol } from \"../common/MobileRpcProtocol\";\nimport { MobileRpcConfiguration } from \"../common/MobileRpcManager\";\nimport { MobileHost } from \"./MobileHost\";\nimport { ProcessDetector } from \"@itwin/core-bentley\";\n\n/* eslint-disable deprecation/deprecation */\n\ninterface MobileAddon {\n notifyListening: (port: number) => void;\n registerDeviceImpl: () => void;\n}\n\nlet addon: MobileAddon | undefined;\n\n/** @internal */\nexport class MobileRpcServer {\n private static _nextId = -1;\n\n public static interop: MobileRpcGateway = {\n handler: (_payload: ArrayBuffer | string) => { throw new IModelError(BentleyStatus.ERROR, \"Not implemented.\"); },\n sendString: (_message: string, _connectionId: number) => { throw new IModelError(BentleyStatus.ERROR, \"No connection.\"); },\n sendBinary: (_message: Uint8Array, _connectionId: number) => { throw new IModelError(BentleyStatus.ERROR, \"No connection.\"); },\n port: 0,\n connectionId: 0,\n };\n\n private _server: ws.Server;\n private _connection: ws | undefined;\n private _port: number;\n private _connectionId: number;\n private _pingTimer: NodeJS.Timeout;\n public constructor() {\n /* _pingTime is a fix for ios/mobile case where when the app moves into foreground from\n * background backend restart ws.Server and then notify frontend to reconnect. But ws.Server\n * listening event is not fired as node yield to kevent and wait for some io event to happen.\n * This causes a delay in reconnection which may be as long a 40 secs. To solve the issue we\n * create _pingTimer which causes kevent to yield back to uv poll so timer event can be fired.\n * This allow listening event to go through quickly (max 5ms). Once the listening event occur we\n * clear the timer. Here we use setInterval() just to make sure otherwise setTimeout() could equally\n * be effective\n */\n this._pingTimer = setInterval(() => { }, 5);\n this._port = MobileRpcConfiguration.setup.obtainPort();\n this._server = new ws.Server({ port: this._port });\n this._connectionId = ++MobileRpcServer._nextId;\n MobileRpcServer.interop.connectionId = this._connectionId;\n this._onListening();\n this._onConnection();\n }\n\n private _onListening() {\n this._server.on(\"listening\", () => {\n const address = this._server.address() as ws.AddressInfo;\n this._port = address.port;\n clearInterval(this._pingTimer);\n this._notifyListening();\n });\n }\n\n private _notifyListening() {\n MobileRpcServer.interop.port = this._port;\n\n if (addon) {\n addon.notifyListening(this._port);\n }\n\n if (this._connectionId !== 0) {\n MobileHost.reconnect(this._port);\n }\n }\n\n private _onConnection() {\n this._server.on(\"connection\", (connection) => {\n this._connection = connection;\n this._connection.on(\"message\", (data) => this._onConnectionMessage(data));\n this._createSender();\n (global as any).__iTwinJsRpcReady = true;\n });\n }\n\n private _createSender() {\n const sender = (message: string | Uint8Array, connectionId: number) => {\n if (connectionId !== this._connectionId) {\n return;\n }\n\n this._connection!.send(message, (err) => {\n if (err) {\n throw err;\n }\n });\n };\n\n MobileRpcServer.interop.sendString = sender;\n MobileRpcServer.interop.sendBinary = sender;\n }\n\n private _onConnectionMessage(data: ws.Data) {\n let message = data;\n if (Array.isArray(message)) {\n throw new IModelError(BentleyStatus.ERROR, \"Unsupported data type\");\n }\n\n if (Buffer.isBuffer(message)) {\n if (message.byteOffset !== 0 || message.byteLength !== message.buffer.byteLength) {\n message = new Uint8Array(message.buffer, message.byteOffset, message.byteLength);\n } else {\n message = message.buffer;\n }\n }\n\n MobileRpcServer.interop.handler(message, this._connectionId);\n }\n\n public dispose() {\n clearInterval(this._pingTimer);\n if (this._connection) {\n MobileRpcServer.interop.sendString = () => { };\n MobileRpcServer.interop.sendBinary = () => { };\n this._connection.close();\n }\n\n this._server.close();\n }\n}\n\nlet mobileReady = false;\nlet hasSuspended = false;\n\nexport function setupMobileRpc() {\n if (mobileReady) {\n return;\n }\n\n if (ProcessDetector.isMobileAppBackend) {\n addon = (process as any)._linkedBinding(\"iModelJsMobile\");\n addon?.registerDeviceImpl();\n }\n\n let server: MobileRpcServer | null = new MobileRpcServer();\n\n /* The UV event loop (internal to node) is retained by handles,\n such as those created for setInterval/setTimeout and client/server connections.\n In a simple app, the RPC server may be the only handle retaining the UV loop.\n Thus, we install a temporary timer on suspend to prevent the loop from exiting prematurely.\n */\n let retainUvLoop: NodeJS.Timer | undefined;\n\n MobileHost.onEnterBackground.addListener(() => {\n hasSuspended = true;\n\n if (server === null) {\n return;\n }\n\n retainUvLoop = setInterval(() => { }, 1000);\n server.dispose();\n server = null;\n });\n\n MobileHost.onEnterForeground.addListener(() => {\n if (!hasSuspended) {\n return;\n }\n\n server = new MobileRpcServer();\n clearInterval(retainUvLoop);\n retainUvLoop = undefined;\n });\n\n MobileHost.onWillTerminate.addListener(() => {\n if (typeof (retainUvLoop) !== \"undefined\") {\n clearInterval(retainUvLoop);\n retainUvLoop = undefined;\n }\n\n if (server === null) {\n return;\n }\n\n server.dispose();\n server = null;\n });\n\n MobileRpcProtocol.obtainInterop = () => MobileRpcServer.interop;\n mobileReady = true;\n}\n"]}
|
|
@@ -1,150 +1,118 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import * as https from "https";
|
|
3
|
-
import { BentleyError, GetMetaDataFunction, HttpStatus } from "@itwin/core-bentley";
|
|
4
|
-
/** @internal */
|
|
5
|
-
export declare const requestIdHeaderName = "X-Correlation-Id";
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
static shouldRetry(error: any, response: any): boolean;
|
|
119
|
-
/**
|
|
120
|
-
* @internal
|
|
121
|
-
*/
|
|
122
|
-
static parseHttpStatus(statusType: number): HttpStatus;
|
|
123
|
-
/**
|
|
124
|
-
* @internal
|
|
125
|
-
*/
|
|
126
|
-
logMessage(): string;
|
|
127
|
-
/**
|
|
128
|
-
* Logs this error
|
|
129
|
-
* @internal
|
|
130
|
-
*/
|
|
131
|
-
log(): void;
|
|
132
|
-
}
|
|
133
|
-
/** Wrapper around making HTTP requests with the specific options.
|
|
134
|
-
*
|
|
135
|
-
* Usable in both a browser and node based environment.
|
|
136
|
-
*
|
|
137
|
-
* @param url Server URL to address the request
|
|
138
|
-
* @param options Options to pass to the request
|
|
139
|
-
* @returns Resolves to the response from the server
|
|
140
|
-
* @throws ResponseError if the request fails due to network issues, or if the returned status is *outside* the range of 200-299 (inclusive)
|
|
141
|
-
* @internal
|
|
142
|
-
*/
|
|
143
|
-
export declare function request(url: string, options: RequestOptions): Promise<Response>;
|
|
144
|
-
/**
|
|
145
|
-
* fetch json from HTTP request
|
|
146
|
-
* @param url server URL to address the request
|
|
147
|
-
* @internal
|
|
148
|
-
*/
|
|
149
|
-
export declare function getJson(url: string): Promise<any>;
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import * as https from "https";
|
|
3
|
+
import { BentleyError, GetMetaDataFunction, HttpStatus } from "@itwin/core-bentley";
|
|
4
|
+
/** @internal */
|
|
5
|
+
export declare const requestIdHeaderName = "X-Correlation-Id";
|
|
6
|
+
/** @internal */
|
|
7
|
+
export interface RequestQueryStringifyOptions {
|
|
8
|
+
delimiter?: string;
|
|
9
|
+
encode?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Option to control the time outs
|
|
12
|
+
* Use a short response timeout to detect unresponsive networks quickly, and a long deadline to give time for downloads on slow,
|
|
13
|
+
* but reliable, networks. Note that both of these timers limit how long uploads of attached files are allowed to take. Use long
|
|
14
|
+
* timeouts if you're uploading files.
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export interface RequestTimeoutOptions {
|
|
18
|
+
/** Sets a deadline (in milliseconds) for the entire request (including all uploads, redirects, server processing time) to complete.
|
|
19
|
+
* If the response isn't fully downloaded within that time, the request will be aborted
|
|
20
|
+
*/
|
|
21
|
+
deadline?: number;
|
|
22
|
+
/** Sets maximum time (in milliseconds) to wait for the first byte to arrive from the server, but it does not limit how long the entire
|
|
23
|
+
* download can take. Response timeout should be at least few seconds longer than just the time it takes the server to respond, because
|
|
24
|
+
* it also includes time to make DNS lookup, TCP/IP and TLS connections, and time to upload request data.
|
|
25
|
+
*/
|
|
26
|
+
response?: number;
|
|
27
|
+
}
|
|
28
|
+
/** @internal */
|
|
29
|
+
export interface RequestOptions {
|
|
30
|
+
method: string;
|
|
31
|
+
headers?: any;
|
|
32
|
+
body?: any;
|
|
33
|
+
responseType?: string;
|
|
34
|
+
timeout?: RequestTimeoutOptions;
|
|
35
|
+
stream?: any;
|
|
36
|
+
readStream?: any;
|
|
37
|
+
buffer?: any;
|
|
38
|
+
parser?: any;
|
|
39
|
+
accept?: string;
|
|
40
|
+
redirects?: number;
|
|
41
|
+
errorCallback?: (response: any) => ResponseError;
|
|
42
|
+
retryCallback?: (error: any, response: any) => boolean;
|
|
43
|
+
progressCallback?: ProgressCallback;
|
|
44
|
+
agent?: https.Agent;
|
|
45
|
+
retries?: number;
|
|
46
|
+
useCorsProxy?: boolean;
|
|
47
|
+
}
|
|
48
|
+
/** Response object if the request was successful. Note that the status within the range of 200-299 are considered as a success.
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
export interface Response {
|
|
52
|
+
body: any;
|
|
53
|
+
text: string | undefined;
|
|
54
|
+
header: any;
|
|
55
|
+
status: number;
|
|
56
|
+
}
|
|
57
|
+
/** @internal */
|
|
58
|
+
export interface ProgressInfo {
|
|
59
|
+
percent?: number;
|
|
60
|
+
total?: number;
|
|
61
|
+
loaded: number;
|
|
62
|
+
}
|
|
63
|
+
/** @internal */
|
|
64
|
+
export type ProgressCallback = (progress: ProgressInfo) => void;
|
|
65
|
+
/** Error object that's thrown/rejected if the Request fails due to a network error, or if the status is *not* in the range of 200-299 (inclusive)
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
export declare class ResponseError extends BentleyError {
|
|
69
|
+
protected _data?: any;
|
|
70
|
+
status?: number;
|
|
71
|
+
description?: string;
|
|
72
|
+
constructor(errorNumber: number | HttpStatus, message?: string, getMetaData?: GetMetaDataFunction);
|
|
73
|
+
/**
|
|
74
|
+
* Parses error from server's response
|
|
75
|
+
* @param response Http response from the server.
|
|
76
|
+
* @returns Parsed error.
|
|
77
|
+
* @internal
|
|
78
|
+
*/
|
|
79
|
+
static parse(response: any, log?: boolean): ResponseError;
|
|
80
|
+
/**
|
|
81
|
+
* Decides whether request should be retried or not
|
|
82
|
+
* @param error Error returned by request
|
|
83
|
+
* @param response Response returned by request
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
86
|
+
static shouldRetry(error: any, response: any): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
static parseHttpStatus(statusType: number): HttpStatus;
|
|
91
|
+
/**
|
|
92
|
+
* @internal
|
|
93
|
+
*/
|
|
94
|
+
logMessage(): string;
|
|
95
|
+
/**
|
|
96
|
+
* Logs this error
|
|
97
|
+
* @internal
|
|
98
|
+
*/
|
|
99
|
+
log(): void;
|
|
100
|
+
}
|
|
101
|
+
/** Wrapper around making HTTP requests with the specific options.
|
|
102
|
+
*
|
|
103
|
+
* Usable in both a browser and node based environment.
|
|
104
|
+
*
|
|
105
|
+
* @param url Server URL to address the request
|
|
106
|
+
* @param options Options to pass to the request
|
|
107
|
+
* @returns Resolves to the response from the server
|
|
108
|
+
* @throws ResponseError if the request fails due to network issues, or if the returned status is *outside* the range of 200-299 (inclusive)
|
|
109
|
+
* @internal
|
|
110
|
+
*/
|
|
111
|
+
export declare function request(url: string, options: RequestOptions): Promise<Response>;
|
|
112
|
+
/**
|
|
113
|
+
* fetch json from HTTP request
|
|
114
|
+
* @param url server URL to address the request
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
117
|
+
export declare function getJson(url: string): Promise<any>;
|
|
150
118
|
//# sourceMappingURL=Request.d.ts.map
|