@pureweb/platform-streaming-agent
Version:
The PureWeb platform streaming agent enables your game to communicate and stream through the PureWeb Platform
255 lines (254 loc) • 13.6 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable @typescript-eslint/no-unused-vars */
const platform_sdk_1 = require("@pureweb/platform-sdk");
const platform_sdk_2 = require("@pureweb/platform-sdk");
const Log_1 = __importDefault(require("./Log"));
const SidecarExtension_1 = require("./extensions/sidecar/SidecarExtension");
const LeasingExtension_1 = require("./extensions/leasing/LeasingExtension");
const StreamExtension_1 = require("./extensions/stream/StreamExtension");
const PresenceMonitorExtension_1 = require("./extensions/presence/PresenceMonitorExtension");
const SteamVRLogMonitorExtension_1 = require("./extensions/ovr/SteamVRLogMonitorExtension");
const Configuration_1 = require("./Configuration");
const yargs_1 = __importDefault(require("yargs"));
const boxen_1 = __importDefault(require("boxen"));
const ConnectionStates_1 = require("./ConnectionStates");
const ExitCodes_1 = require("./ExitCodes");
const RuntimeExtension_1 = require("./extensions/runtime/RuntimeExtension");
function showBanner(agent, platform, configuration) {
const info = new platform_sdk_2.Info();
let streamerDetails;
streamerDetails = `PureWeb Streaming Agent ${platform_sdk_1.PlatformNext.version}\n\n`;
streamerDetails += `SDK version: ${info.sdkVersion}\n`;
streamerDetails += `Configuration file: ${configuration.configFile}\n`;
streamerDetails += `Agent id: ${agent.id}\n`;
streamerDetails += `Project id: ${platform.credentials.projectId}\n`;
streamerDetails += `Environment id: ${platform.credentials.environmentId}\n`;
streamerDetails += `\n`;
streamerDetails += `Streamer Port: ${configuration.streamerPort}\n`;
streamerDetails += `Leasing Enabled: ${configuration.leaseUrl ? `YES [${configuration.leaseUrl}]` : 'NO'}\n`;
streamerDetails += `Sidecar Port: ${configuration.sidecarPort ? `YES [${configuration.sidecarPort}]` : 'NO'}\n`;
streamerDetails += `Stream service: ${configuration.streamService ? configuration.streamService : 'webRTC'}\n`;
streamerDetails += `\n`;
streamerDetails += `Timeouts\n`;
streamerDetails += `\n`;
streamerDetails += ` Rendezvous: ${configuration.rendezvousTimeoutSeconds > -1 ? `YES [${configuration.rendezvousTimeoutSeconds} seconds]` : 'NO'}\n`;
streamerDetails += ` Streamer Rendezvous: ${configuration.streamerTimeoutSeconds > -1 ? `YES [${configuration.streamerTimeoutSeconds} seconds]` : 'NO'}\n`;
streamerDetails += ` Streamer Claimed Timeout: ${configuration.claimedTimeoutSeconds ? `YES [${configuration.claimedTimeoutSeconds} seconds]` : 'NO'}\n`;
streamerDetails += ` Maximum runtime: ${configuration.maximumRuntime > -1 ? `YES [${configuration.maximumRuntime} seconds]` : 'NO'}\n`;
streamerDetails += ` Linger: ${configuration.lingerTimeoutSeconds > -1 ? `YES [${configuration.lingerTimeoutSeconds} seconds]` : 'NO'}\n`;
streamerDetails += ` Standby Mode: ${configuration.standbyMode === true ? 'YES' : 'NO'}\n`;
Log_1.default.info('\n' + (0, boxen_1.default)(streamerDetails, { padding: 1 }));
}
async function startServices(agent, platform, configuration) {
try {
let leasingService;
let sidecarService;
const steamVRMonitor = new SteamVRLogMonitorExtension_1.SteamVRLogMonitorExtension();
// Presence Monitor Extension
const presenceMonitor = new PresenceMonitorExtension_1.PresenceMonitorExtension();
// Streaming Extension
const streamService = new StreamExtension_1.StreamExtension();
// runtime Extension
const runtimeService = new RuntimeExtension_1.RuntimeExtension();
let agentEnvReconnectTimer = null;
agent.onConnection((state) => {
Log_1.default.info('Agent connection state changed: ' + state);
switch (state) {
case platform_sdk_1.AgentConnectionStatus.INITIALIZING:
break;
case platform_sdk_1.AgentConnectionStatus.CONNECTED:
if (agentEnvReconnectTimer) {
clearTimeout(agentEnvReconnectTimer);
agentEnvReconnectTimer = null;
}
streamService.reconnect();
break;
case platform_sdk_1.AgentConnectionStatus.OFFLINE:
if (!agentEnvReconnectTimer) {
agentEnvReconnectTimer = setTimeout(() => {
connectionStateChanged(configuration, ConnectionStates_1.ConnectionStates.AGENT_DISCONNECTED);
}, configuration.reconnectTimeoutMilliseconds);
}
break;
case platform_sdk_1.AgentConnectionStatus.ERROR:
connectionStateChanged(configuration, ConnectionStates_1.ConnectionStates.AGENT_DISCONNECTED);
break;
default:
Log_1.default.info('Unhandled agent connection state: ' + state);
break;
}
});
// Runtime Monitor Extension Initializatin
runtimeService.onStateChanged((state) => {
connectionStateChanged(configuration, state);
});
runtimeService.initialize(agent, configuration, platform, presenceMonitor);
await runtimeService.start();
Log_1.default.info('Runtime monitor started');
// Presence Monitor Extension Initialization
presenceMonitor.onStateChanged((state) => {
connectionStateChanged(configuration, state);
});
if (configuration.streamService === 'cloudXR') {
steamVRMonitor.onStateChanged((state) => {
connectionStateChanged(configuration, state);
});
steamVRMonitor.initialize(agent, configuration, platform, presenceMonitor);
await steamVRMonitor.start();
Log_1.default.info('steamVRMonitor started');
}
else {
presenceMonitor.initialize(agent, configuration, platform);
await presenceMonitor.start();
Log_1.default.info('Presence monitor started');
// Streaming Extension Initialization
streamService.onStateChanged((state) => {
connectionStateChanged(configuration, state);
});
streamService.initialize(agent, configuration, platform, presenceMonitor);
await streamService.start();
Log_1.default.info('Streaming service started');
}
// Lease Extension
if (configuration.leaseUrl) {
leasingService = new LeasingExtension_1.LeasingExtension();
leasingService.onStateChanged((state) => {
connectionStateChanged(configuration, state);
});
leasingService.initialize(agent, configuration);
await leasingService.start();
Log_1.default.info('Leasing service started');
}
else {
Log_1.default.warn('Leasing service diabled. No Lease URL provided');
}
// Sidecar Extension
if (configuration.sidecarPort) {
sidecarService = new SidecarExtension_1.SidecarExtension();
sidecarService.onStateChanged((state) => {
connectionStateChanged(configuration, state);
});
sidecarService.initialize(agent, configuration);
await sidecarService
.start()
.then(() => {
Log_1.default.info('Sidecar service started');
})
.catch((reason) => {
Log_1.default.error('Failed to start sidecar service');
return Promise.reject(reason);
});
}
else {
Log_1.default.warn('Sidecar service diabled. No sidecar provided');
}
}
catch (err) {
return Promise.reject(err);
}
}
function connectionStateChanged(configuration, state) {
if (state === ConnectionStates_1.ConnectionStates.GRPC_DISCONNECTED && configuration.shutdownOnDisconnect) {
Log_1.default.info('Sidecar disconnected, Streaming Agent shutting down');
process.exit(ExitCodes_1.ExitCodes.ErrorGRPCDisconnected);
}
else if (state === ConnectionStates_1.ConnectionStates.GRPC_TIMEOUT) {
Log_1.default.info('Sidecar connection timeout, Streaming Agent shutting down');
process.exit(ExitCodes_1.ExitCodes.ErrorGRPCTimeout);
}
else if (state === ConnectionStates_1.ConnectionStates.LEASE_DENIED) {
Log_1.default.info('Lease was denied, Streaming Agent shutting down');
process.exit(ExitCodes_1.ExitCodes.ErrorLeaseDenied);
}
else if (state === ConnectionStates_1.ConnectionStates.STREAMER_PORT_UNAVAILABLE) {
Log_1.default.info('Streamer port unavailable, Streaming Agent shutting down');
process.exit(ExitCodes_1.ExitCodes.ErrorStreamerPortUnavailable);
}
else if (state === ConnectionStates_1.ConnectionStates.AGENT_RENDEZVOUS_MISSED) {
Log_1.default.info('No agent peer arrived within the rendezvous window. Streaming Agent shutting down');
process.exit(ExitCodes_1.ExitCodes.ErrorAgentRendezvousMissed);
}
else if (state === ConnectionStates_1.ConnectionStates.STREAMER_RENDEZVOUS_MISSED) {
Log_1.default.info('No Streamer connected within the rendezvous window. Streaming Agent shutting down');
process.exit(ExitCodes_1.ExitCodes.ErrorStreamerRendezvousMissed);
}
else if (state === ConnectionStates_1.ConnectionStates.AGENT_DISCONNECTED) {
Log_1.default.info('Disconnected from agent environment. Streaming Agent shutting down');
process.exit(ExitCodes_1.ExitCodes.ErrorAgentDisconnected);
}
else if (state === ConnectionStates_1.ConnectionStates.PEERS_EXITED) {
Log_1.default.info('All agent peers have left the environment. Streaming agent shutting down');
process.exit(ExitCodes_1.ExitCodes.None);
}
else if (state === ConnectionStates_1.ConnectionStates.INTERNAL_ERROR) {
Log_1.default.info('Internal error detected, Streaming Agent shutting down');
process.exit(ExitCodes_1.ExitCodes.ErrorUnknown);
}
else if (state === ConnectionStates_1.ConnectionStates.STREAMER_CONNECTION_ERROR) {
Log_1.default.info('Streamer encounter connection error. Streaming agent shutting down');
process.exit(ExitCodes_1.ExitCodes.ErrorStreamerConnection);
}
else if (state === ConnectionStates_1.ConnectionStates.STREAMER_DISCONNECTED) {
Log_1.default.info('Streamer disconnected. Streaming agent shutting down');
process.exit(ExitCodes_1.ExitCodes.ErrorStreamerDisconnected);
}
else if (state === ConnectionStates_1.ConnectionStates.STREAMER_DUPLICATE_CONNECTION) {
Log_1.default.info('The second streamer attempting connection. Streaming agent shutting down');
process.exit(ExitCodes_1.ExitCodes.ErrorDuplicateStreamer);
}
else if (state === ConnectionStates_1.ConnectionStates.MAXIMUM_RUNTIME_REACHED) {
Log_1.default.info('Maximum runtime reached. Streaming agent shutting down');
process.exit(ExitCodes_1.ExitCodes.ErrorMaximumRuntimeReached);
}
else if (state === ConnectionStates_1.ConnectionStates.STANDBY_TIMEOUT) {
Log_1.default.info('Standby timeout reached. Streaming agent shutting down');
process.exit(ExitCodes_1.ExitCodes.None);
}
else if (state === ConnectionStates_1.ConnectionStates.TERMINATED) {
Log_1.default.info('Streaming agent terminated');
process.exit(ExitCodes_1.ExitCodes.None);
}
else if (state === ConnectionStates_1.ConnectionStates.CLAIMED_TIMOUT) {
Log_1.default.info('Launch request claimed timeout reached. Streaming agent shutting down');
process.exit(ExitCodes_1.ExitCodes.None);
}
else {
return;
}
}
async function main() {
try {
const configuration = new Configuration_1.Configuration();
configuration.init(yargs_1.default.argv, process.env);
const credentials = new platform_sdk_1.PlatformCredentials();
credentials.agent = configuration.agentToken;
const platform = new platform_sdk_1.PlatformNext();
platform.initialize({ endpoint: credentials.agent.issuer });
platform.credentials = credentials;
// parse launch request id, if available
const launchRequestId = configuration.leaseUrl
? configuration.leaseUrl.substring(configuration.leaseUrl.lastIndexOf('/') + 1)
: undefined;
Log_1.default.settings.minLevel = +configuration.logLevel;
const agent = await platform.connect();
showBanner(agent, platform, configuration);
startServices(agent, platform, configuration)
.then(() => {
Log_1.default.info(`Streaming agent services started successfully`);
})
.catch((reason) => {
Log_1.default.error(`Streaming agent services failed to start: ${reason}`);
process.exit(ExitCodes_1.ExitCodes.ErrorUnknown);
});
}
catch (exception) {
Log_1.default.error(`Streaming agent startup failed: ${exception}`);
process.exit(ExitCodes_1.ExitCodes.ErrorUnknown);
}
}
main();
;