@epicgames-ps/lib-pixelstreamingsignalling-ue5.8 0.1.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/.lintstagedrc.mjs +7 -0
- package/.prettierignore +0 -0
- package/CHANGELOG.md +21 -0
- package/README.md +32 -0
- package/dist/cjs/Logger.js +148 -0
- package/dist/cjs/Logger.js.map +1 -0
- package/dist/cjs/LoggingUtils.js +64 -0
- package/dist/cjs/LoggingUtils.js.map +1 -0
- package/dist/cjs/PlayerConnection.js +220 -0
- package/dist/cjs/PlayerConnection.js.map +1 -0
- package/dist/cjs/PlayerRegistry.js +77 -0
- package/dist/cjs/PlayerRegistry.js.map +1 -0
- package/dist/cjs/SFUConnection.js +264 -0
- package/dist/cjs/SFUConnection.js.map +1 -0
- package/dist/cjs/SignallingServer.js +149 -0
- package/dist/cjs/SignallingServer.js.map +1 -0
- package/dist/cjs/StreamerConnection.js +172 -0
- package/dist/cjs/StreamerConnection.js.map +1 -0
- package/dist/cjs/StreamerRegistry.js +149 -0
- package/dist/cjs/StreamerRegistry.js.map +1 -0
- package/dist/cjs/Utils.js +19 -0
- package/dist/cjs/Utils.js.map +1 -0
- package/dist/cjs/WebServer.js +124 -0
- package/dist/cjs/WebServer.js.map +1 -0
- package/dist/cjs/pixelstreamingsignalling.js +28 -0
- package/dist/cjs/pixelstreamingsignalling.js.map +1 -0
- package/dist/esm/Logger.js +141 -0
- package/dist/esm/Logger.js.map +1 -0
- package/dist/esm/LoggingUtils.js +58 -0
- package/dist/esm/LoggingUtils.js.map +1 -0
- package/dist/esm/PlayerConnection.js +183 -0
- package/dist/esm/PlayerConnection.js.map +1 -0
- package/dist/esm/PlayerRegistry.js +73 -0
- package/dist/esm/PlayerRegistry.js.map +1 -0
- package/dist/esm/SFUConnection.js +227 -0
- package/dist/esm/SFUConnection.js.map +1 -0
- package/dist/esm/SignallingServer.js +112 -0
- package/dist/esm/SignallingServer.js.map +1 -0
- package/dist/esm/StreamerConnection.js +135 -0
- package/dist/esm/StreamerConnection.js.map +1 -0
- package/dist/esm/StreamerRegistry.js +145 -0
- package/dist/esm/StreamerRegistry.js.map +1 -0
- package/dist/esm/Utils.js +15 -0
- package/dist/esm/Utils.js.map +1 -0
- package/dist/esm/WebServer.js +117 -0
- package/dist/esm/WebServer.js.map +1 -0
- package/dist/esm/pixelstreamingsignalling.js +12 -0
- package/dist/esm/pixelstreamingsignalling.js.map +1 -0
- package/dist/types/Logger.d.ts +20 -0
- package/dist/types/LoggingUtils.d.ts +44 -0
- package/dist/types/PlayerConnection.d.ts +66 -0
- package/dist/types/PlayerRegistry.d.ts +66 -0
- package/dist/types/SFUConnection.d.ts +85 -0
- package/dist/types/SignallingServer.d.ts +48 -0
- package/dist/types/StreamerConnection.d.ts +61 -0
- package/dist/types/StreamerRegistry.d.ts +96 -0
- package/dist/types/Utils.d.ts +8 -0
- package/dist/types/WebServer.d.ts +42 -0
- package/dist/types/pixelstreamingsignalling.d.ts +9 -0
- package/docs/Logger/README.md +19 -0
- package/docs/Logger/functions/InitLogging.md +26 -0
- package/docs/Logger/interfaces/IConfig.md +41 -0
- package/docs/Logger/variables/Logger.md +15 -0
- package/docs/LoggingUtils/README.md +19 -0
- package/docs/LoggingUtils/functions/createHandlerListener.md +42 -0
- package/docs/LoggingUtils/functions/logForward.md +36 -0
- package/docs/LoggingUtils/functions/logIncoming.md +30 -0
- package/docs/LoggingUtils/functions/logOutgoing.md +30 -0
- package/docs/LoggingUtils/interfaces/IMessageLogger.md +29 -0
- package/docs/LoggingUtils/interfaces/IProtoLogObj.md +57 -0
- package/docs/PlayerConnection/README.md +11 -0
- package/docs/PlayerConnection/classes/PlayerConnection.md +177 -0
- package/docs/PlayerRegistry/README.md +16 -0
- package/docs/PlayerRegistry/classes/PlayerRegistry.md +423 -0
- package/docs/PlayerRegistry/interfaces/IPlayer.md +86 -0
- package/docs/PlayerRegistry/interfaces/IPlayerInfo.md +43 -0
- package/docs/README.md +19 -0
- package/docs/SFUConnection/README.md +11 -0
- package/docs/SFUConnection/classes/SFUConnection.md +554 -0
- package/docs/SignallingServer/README.md +19 -0
- package/docs/SignallingServer/classes/SignallingServer.md +76 -0
- package/docs/SignallingServer/interfaces/IServerConfig.md +92 -0
- package/docs/SignallingServer/type-aliases/ProtocolConfig.md +15 -0
- package/docs/StreamerConnection/README.md +11 -0
- package/docs/StreamerConnection/classes/StreamerConnection.md +507 -0
- package/docs/StreamerRegistry/README.md +16 -0
- package/docs/StreamerRegistry/classes/StreamerRegistry.md +431 -0
- package/docs/StreamerRegistry/interfaces/IStreamer.md +375 -0
- package/docs/StreamerRegistry/interfaces/IStreamerInfo.md +51 -0
- package/docs/Utils/README.md +12 -0
- package/docs/Utils/functions/beautify.md +23 -0
- package/docs/Utils/functions/stringify.md +23 -0
- package/docs/WebServer/README.md +15 -0
- package/docs/WebServer/classes/WebServer.md +50 -0
- package/docs/WebServer/interfaces/IWebServerConfig.md +76 -0
- package/docs/pixelstreamingsignalling/README.md +145 -0
- package/eslint.config.mjs +39 -0
- package/package.json +58 -0
- package/src/Logger.ts +189 -0
- package/src/LoggingUtils.ts +80 -0
- package/src/PlayerConnection.ts +257 -0
- package/src/PlayerRegistry.ts +116 -0
- package/src/SFUConnection.ts +329 -0
- package/src/SignallingServer.ts +214 -0
- package/src/StreamerConnection.ts +194 -0
- package/src/StreamerRegistry.ts +252 -0
- package/src/Utils.ts +16 -0
- package/src/WebServer.ts +213 -0
- package/src/pixelstreamingsignalling.ts +11 -0
- package/tsconfig.cjs.json +8 -0
- package/tsconfig.esm.json +8 -0
- package/tsconfig.json +29 -0
package/src/WebServer.ts
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import http from 'http';
|
|
6
|
+
import https from 'https';
|
|
7
|
+
import helmet from 'helmet';
|
|
8
|
+
import cors from 'cors';
|
|
9
|
+
import { Logger } from './Logger';
|
|
10
|
+
import RateLimit from 'express-rate-limit';
|
|
11
|
+
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
13
|
+
const hsts = require('hsts');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Options for configuring CORS on the Express app. When `enabled` is true the
|
|
17
|
+
* `cors` middleware is registered so that browser-based clients hosted on a
|
|
18
|
+
* different origin (e.g. a custom frontend) can call the REST API or other
|
|
19
|
+
* routes mounted on the app. Use `allowedOrigins` to restrict which origins
|
|
20
|
+
* are accepted; an empty / unset list means "allow all origins" (`*`).
|
|
21
|
+
*/
|
|
22
|
+
export interface ICorsConfig {
|
|
23
|
+
// If false (or unset) no CORS headers are added. Defaults to false.
|
|
24
|
+
enabled?: boolean;
|
|
25
|
+
|
|
26
|
+
// List of origins to allow. If empty/unset, all origins are allowed.
|
|
27
|
+
allowedOrigins?: string[];
|
|
28
|
+
|
|
29
|
+
// List of HTTP methods to allow. Defaults to the `cors` package default
|
|
30
|
+
// (`GET,HEAD,PUT,PATCH,POST,DELETE`).
|
|
31
|
+
allowedMethods?: string[];
|
|
32
|
+
|
|
33
|
+
// List of request headers to allow. If unset, the `cors` package mirrors
|
|
34
|
+
// the request's `Access-Control-Request-Headers` header.
|
|
35
|
+
allowedHeaders?: string[];
|
|
36
|
+
|
|
37
|
+
// Whether the request can include credentials (cookies, auth headers).
|
|
38
|
+
// Defaults to false.
|
|
39
|
+
credentials?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* An interface that describes the possible options to pass to
|
|
44
|
+
* WebServer.
|
|
45
|
+
*/
|
|
46
|
+
export interface IWebServerConfig {
|
|
47
|
+
// The port to run the webserver on. 80 by default.
|
|
48
|
+
httpPort: number;
|
|
49
|
+
|
|
50
|
+
// The root of the serve directory. Current working directory by default.
|
|
51
|
+
root: string;
|
|
52
|
+
|
|
53
|
+
// The filename to direct connections to if none suppllied in the url. player.html by default.
|
|
54
|
+
homepageFile: string;
|
|
55
|
+
|
|
56
|
+
// An optional rate limit to prevent overloading.
|
|
57
|
+
perMinuteRateLimit?: number;
|
|
58
|
+
|
|
59
|
+
// When set an https server will be created
|
|
60
|
+
httpsPort?: number;
|
|
61
|
+
|
|
62
|
+
// The ssl key data for https
|
|
63
|
+
ssl_key?: Buffer;
|
|
64
|
+
|
|
65
|
+
// The ssl cert data for https
|
|
66
|
+
ssl_cert?: Buffer;
|
|
67
|
+
|
|
68
|
+
// If true, connections to http will be redirected to https.
|
|
69
|
+
https_redirect?: boolean;
|
|
70
|
+
|
|
71
|
+
// If true, serve static content from `root` and a homepage handler at `/`.
|
|
72
|
+
// Defaults to false. When false, the HTTP listener still runs (so routes
|
|
73
|
+
// registered by other subsystems, such as a REST API, remain reachable),
|
|
74
|
+
// but no static files are served.
|
|
75
|
+
serveStatic?: boolean;
|
|
76
|
+
|
|
77
|
+
// Optional CORS configuration. When `cors.enabled` is true the cors
|
|
78
|
+
// middleware is registered before the rate limiter and any route handlers,
|
|
79
|
+
// so that all routes mounted on the app respond with CORS headers.
|
|
80
|
+
cors?: ICorsConfig;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* An object to manage the initialization of a web server. Used to serve the
|
|
85
|
+
* pixel streaming frontend.
|
|
86
|
+
*/
|
|
87
|
+
export class WebServer {
|
|
88
|
+
httpServer: http.Server | undefined;
|
|
89
|
+
httpsServer: https.Server | undefined;
|
|
90
|
+
|
|
91
|
+
constructor(app: express.Express, config: IWebServerConfig) {
|
|
92
|
+
Logger.debug('Starting WebServer with config: %s', config);
|
|
93
|
+
|
|
94
|
+
// only listen on the http port if we're not using https or if we want to redirect
|
|
95
|
+
if (!config.httpsPort || config.https_redirect) {
|
|
96
|
+
this.httpServer = http.createServer(app);
|
|
97
|
+
this.httpServer.listen(config.httpPort, () => {
|
|
98
|
+
Logger.info(`Http server listening on port ${config.httpPort}`);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* eslint-disable @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access */
|
|
103
|
+
|
|
104
|
+
// if using https listen on the given ports and setup some details
|
|
105
|
+
if (config.httpsPort) {
|
|
106
|
+
const options = { key: config.ssl_key, cert: config.ssl_cert };
|
|
107
|
+
this.httpsServer = https.createServer(options, app);
|
|
108
|
+
this.httpsServer.listen(config.httpsPort, () => {
|
|
109
|
+
Logger.info(`Https server listening on port ${config.httpsPort}`);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
app.use(
|
|
113
|
+
helmet({
|
|
114
|
+
contentSecurityPolicy: {
|
|
115
|
+
directives: {
|
|
116
|
+
'connect-src': ['*', "'self'"]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
app.use(
|
|
123
|
+
hsts({
|
|
124
|
+
maxAge: 15552000 // 180 days in seconds
|
|
125
|
+
})
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// Setup http -> https redirect if requested
|
|
129
|
+
if (config.https_redirect) {
|
|
130
|
+
app.use((req: any, res: any, next: any) => {
|
|
131
|
+
if (!req.secure) {
|
|
132
|
+
if (req.get('Host')) {
|
|
133
|
+
const hostAddressParts: string[] = req.get('Host').split(':') as string[];
|
|
134
|
+
let hostAddress = hostAddressParts[0];
|
|
135
|
+
if (config.httpsPort != 443) {
|
|
136
|
+
hostAddress = `${hostAddress}:${config.httpsPort}`;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return res.redirect(['https://', hostAddress, req.originalUrl].join(''));
|
|
140
|
+
} else {
|
|
141
|
+
Logger.error(
|
|
142
|
+
`Unable to get host name from header. Requestor ${req.ip}, url path: '${req.originalUrl}', available headers ${JSON.stringify(req.headers)}`
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
return res.status(400).send('Bad Request');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
next();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (config.cors?.enabled) {
|
|
154
|
+
const corsOptions: cors.CorsOptions = {};
|
|
155
|
+
|
|
156
|
+
if (config.cors.allowedOrigins && config.cors.allowedOrigins.length > 0) {
|
|
157
|
+
corsOptions.origin = config.cors.allowedOrigins;
|
|
158
|
+
}
|
|
159
|
+
if (config.cors.allowedMethods && config.cors.allowedMethods.length > 0) {
|
|
160
|
+
corsOptions.methods = config.cors.allowedMethods;
|
|
161
|
+
}
|
|
162
|
+
if (config.cors.allowedHeaders && config.cors.allowedHeaders.length > 0) {
|
|
163
|
+
corsOptions.allowedHeaders = config.cors.allowedHeaders;
|
|
164
|
+
}
|
|
165
|
+
if (config.cors.credentials) {
|
|
166
|
+
corsOptions.credentials = true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Register cors before the rate limiter so that preflight (OPTIONS)
|
|
170
|
+
// requests are answered with CORS headers even when an origin is
|
|
171
|
+
// close to the rate limit, and before any route handlers so the
|
|
172
|
+
// homepage, static files, and the REST API all respond uniformly.
|
|
173
|
+
app.use(cors(corsOptions));
|
|
174
|
+
|
|
175
|
+
Logger.info(
|
|
176
|
+
`CORS enabled. Allowed origins: ${corsOptions.origin ? JSON.stringify(corsOptions.origin) : '*'}`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const limiter = RateLimit({
|
|
181
|
+
windowMs: 60 * 1000, // 1 minute
|
|
182
|
+
max: config.perMinuteRateLimit ? config.perMinuteRateLimit : 3000
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// apply rate limiter to all requests. Registered before any route
|
|
186
|
+
// handler so that static files, the homepage route, and any routes
|
|
187
|
+
// registered on `app` by downstream code are all subject to it.
|
|
188
|
+
app.use(limiter);
|
|
189
|
+
|
|
190
|
+
if (config.serveStatic) {
|
|
191
|
+
app.use(express.static(config.root));
|
|
192
|
+
|
|
193
|
+
// Request has been sent to site root, send the homepage file
|
|
194
|
+
app.get('/', function (req: any, res: any) {
|
|
195
|
+
// Try a few paths, see if any resolve to a homepage file the user has set
|
|
196
|
+
const p = path.resolve(path.join(config.root, config.homepageFile));
|
|
197
|
+
if (fs.existsSync(p)) {
|
|
198
|
+
// Send the file for browser to display it
|
|
199
|
+
res.sendFile(p);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Catch file doesn't exist, and send back 404 if not
|
|
204
|
+
const error = 'Unable to locate file ' + config.homepageFile;
|
|
205
|
+
Logger.error(error);
|
|
206
|
+
res.status(404).send(error);
|
|
207
|
+
return;
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* eslint-enable @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access */
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
2
|
+
export * from './Logger';
|
|
3
|
+
export * from './LoggingUtils';
|
|
4
|
+
export * from './PlayerConnection';
|
|
5
|
+
export * from './PlayerRegistry';
|
|
6
|
+
export * from './SFUConnection';
|
|
7
|
+
export * from './SignallingServer';
|
|
8
|
+
export * from './StreamerConnection';
|
|
9
|
+
export * from './StreamerRegistry';
|
|
10
|
+
export * from './WebServer';
|
|
11
|
+
// keep Utils internal for now
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"noImplicitAny": true,
|
|
4
|
+
"esModuleInterop": true,
|
|
5
|
+
"target": "ES6",
|
|
6
|
+
"sourceMap": true,
|
|
7
|
+
"allowJs": true,
|
|
8
|
+
"strict": true,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"noImplicitOverride": true,
|
|
11
|
+
"noFallthroughCasesInSwitch": true,
|
|
12
|
+
"noImplicitReturns": true,
|
|
13
|
+
"noPropertyAccessFromIndexSignature": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"declarationDir": "./dist/types",
|
|
16
|
+
"moduleResolution": "bundler" // helps IDEs
|
|
17
|
+
},
|
|
18
|
+
"include": ["./src/*.ts"],
|
|
19
|
+
"typedocOptions": {
|
|
20
|
+
"entryPoints": ["src/**/*.ts"],
|
|
21
|
+
"out": "docs",
|
|
22
|
+
"excludeExternals": true,
|
|
23
|
+
"excludePrivate": true,
|
|
24
|
+
"excludeInternal": true,
|
|
25
|
+
"cleanOutputDir": false,
|
|
26
|
+
"plugin": "typedoc-plugin-markdown",
|
|
27
|
+
"readme": "none"
|
|
28
|
+
}
|
|
29
|
+
}
|