mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-12 10:39:57 +00:00
Add options to switch bridge backup WebSocket server port
This commit is contained in:
@@ -3,13 +3,27 @@
|
|||||||
import { spawn } from "child_process";
|
import { spawn } from "child_process";
|
||||||
import { Readable } from "stream";
|
import { Readable } from "stream";
|
||||||
|
|
||||||
|
import minimist from "minimist";
|
||||||
import WebSocket from "ws";
|
import WebSocket from "ws";
|
||||||
|
|
||||||
import { DecodeTransform
|
import { DecodeTransform
|
||||||
, EncodeTransform } from "../transforms";
|
, EncodeTransform } from "../transforms";
|
||||||
|
|
||||||
|
|
||||||
const wss = new WebSocket.Server({ port: 9556 });
|
const argv = minimist(process.argv.slice(2), {
|
||||||
|
string: [ "port" ]
|
||||||
|
, default: {
|
||||||
|
port: "9556"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const port = parseInt(argv.port);
|
||||||
|
if (!port || port < 1025 || port > 65535) {
|
||||||
|
console.error("Invalid port specified!");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const wss = new WebSocket.Server({ port });
|
||||||
|
|
||||||
wss.on("connection", socket => {
|
wss.on("connection", socket => {
|
||||||
// Stream for incoming WebSocket messages
|
// Stream for incoming WebSocket messages
|
||||||
|
|||||||
@@ -202,8 +202,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
, "optionsBridgeBackupEnabled": {
|
, "optionsBridgeBackupEnabled": {
|
||||||
"message": "Enable backup daemon connection"
|
"message": "Enable backup daemon connection on port $numberInput$"
|
||||||
, "description": "Backup daemon checkbox label."
|
, "description": "Backup daemon checkbox label. An HTML number input is inserted inline at the numberInput substitution."
|
||||||
|
, "placeholders": {
|
||||||
|
"numberInput": {
|
||||||
|
"content": "$1"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
, "optionsBridgeBackupEnabledDescription": {
|
, "optionsBridgeBackupEnabledDescription": {
|
||||||
"message": "If the regular bridge connection fails, attempt to connect to a bridge running in daemon mode."
|
"message": "If the regular bridge connection fails, attempt to connect to a bridge running in daemon mode."
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { Options } from "./lib/options";
|
|||||||
export default {
|
export default {
|
||||||
bridgeApplicationName: APPLICATION_NAME
|
bridgeApplicationName: APPLICATION_NAME
|
||||||
, bridgeBackupEnabled: false
|
, bridgeBackupEnabled: false
|
||||||
|
, bridgeBackupPort: 9556
|
||||||
, mediaEnabled: true
|
, mediaEnabled: true
|
||||||
, mediaOverlayEnabled: false
|
, mediaOverlayEnabled: false
|
||||||
, mediaSyncElement: false
|
, mediaSyncElement: false
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import logger from "./logger";
|
|||||||
import options from "./options";
|
import options from "./options";
|
||||||
|
|
||||||
|
|
||||||
const WEBSOCKET_DAEMON_URL = "ws://localhost:9556";
|
const WEBSOCKET_DAEMON_URL_PREFIX = "ws://localhost:";
|
||||||
|
|
||||||
|
|
||||||
type DisconnectListener = (port: browser.runtime.Port) => void;
|
type DisconnectListener = (port: browser.runtime.Port) => void;
|
||||||
@@ -114,7 +114,8 @@ function connectNative (application: string) {
|
|||||||
if (port.error && !isNativeHostStatusKnown) {
|
if (port.error && !isNativeHostStatusKnown) {
|
||||||
isNativeHostStatusKnown = true;
|
isNativeHostStatusKnown = true;
|
||||||
|
|
||||||
socket = new WebSocket(WEBSOCKET_DAEMON_URL);
|
const port = await options.get("bridgeBackupPort");
|
||||||
|
socket = new WebSocket(`${WEBSOCKET_DAEMON_URL_PREFIX}${port}`);
|
||||||
|
|
||||||
socket.addEventListener("open", () => {
|
socket.addEventListener("open", () => {
|
||||||
// Send all messages in queue
|
// Send all messages in queue
|
||||||
@@ -171,8 +172,10 @@ async function sendNativeMessage (
|
|||||||
throw logger.error("Bridge connection failed and backup not enabled.");
|
throw logger.error("Bridge connection failed and backup not enabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const port = await options.get("bridgeBackupPort");
|
||||||
|
|
||||||
return await new Promise((resolve, reject) => {
|
return await new Promise((resolve, reject) => {
|
||||||
const ws = new WebSocket(WEBSOCKET_DAEMON_URL);
|
const ws = new WebSocket(`${WEBSOCKET_DAEMON_URL_PREFIX}${port}`);
|
||||||
|
|
||||||
ws.addEventListener("open", () => {
|
ws.addEventListener("open", () => {
|
||||||
ws.send(JSON.stringify(message));
|
ws.send(JSON.stringify(message));
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ const storageArea = new TypedStorageArea<{
|
|||||||
export interface Options {
|
export interface Options {
|
||||||
bridgeApplicationName: string;
|
bridgeApplicationName: string;
|
||||||
bridgeBackupEnabled: boolean;
|
bridgeBackupEnabled: boolean;
|
||||||
|
bridgeBackupPort: number;
|
||||||
mediaEnabled: boolean;
|
mediaEnabled: boolean;
|
||||||
mediaOverlayEnabled: boolean;
|
mediaOverlayEnabled: boolean;
|
||||||
mediaSyncElement: boolean;
|
mediaSyncElement: boolean;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import semver from "semver";
|
import semver from "semver";
|
||||||
|
|
||||||
import options from "../../lib/options";
|
import options, { Options } from "../../lib/options";
|
||||||
|
|
||||||
import { BridgeInfo } from "../../lib/bridge";
|
import { BridgeInfo } from "../../lib/bridge";
|
||||||
import { getNextEllipsis } from "../../lib/utils";
|
import { getNextEllipsis } from "../../lib/utils";
|
||||||
@@ -62,6 +62,8 @@ const BridgeStats = (props: BridgeStatsProps) => (
|
|||||||
interface BridgeProps {
|
interface BridgeProps {
|
||||||
info?: BridgeInfo;
|
info?: BridgeInfo;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
options?: Options;
|
||||||
|
onChange: (ev: React.ChangeEvent<HTMLInputElement>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BridgeState {
|
interface BridgeState {
|
||||||
@@ -69,7 +71,6 @@ interface BridgeState {
|
|||||||
isUpdateAvailable: boolean;
|
isUpdateAvailable: boolean;
|
||||||
wasErrorCheckingUpdates: boolean;
|
wasErrorCheckingUpdates: boolean;
|
||||||
checkUpdatesEllipsis: string;
|
checkUpdatesEllipsis: string;
|
||||||
bridgeBackupEnabled?: boolean;
|
|
||||||
updateStatus?: string;
|
updateStatus?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,11 +88,6 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
|
|||||||
, checkUpdatesEllipsis: "..."
|
, checkUpdatesEllipsis: "..."
|
||||||
};
|
};
|
||||||
|
|
||||||
options.get("bridgeBackupEnabled")
|
|
||||||
.then(bridgeBackupEnabled => {
|
|
||||||
this.setState({ bridgeBackupEnabled });
|
|
||||||
});
|
|
||||||
|
|
||||||
this.onCheckUpdates = this.onCheckUpdates.bind(this);
|
this.onCheckUpdates = this.onCheckUpdates.bind(this);
|
||||||
this.onCheckUpdatesResponse = this.onCheckUpdatesResponse.bind(this);
|
this.onCheckUpdatesResponse = this.onCheckUpdatesResponse.bind(this);
|
||||||
this.onCheckUpdatesError = this.onCheckUpdatesError.bind(this);
|
this.onCheckUpdatesError = this.onCheckUpdatesError.bind(this);
|
||||||
@@ -99,6 +95,9 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public render () {
|
public render () {
|
||||||
|
const [ backupMessageStart, backupMessageEnd ]
|
||||||
|
= _("optionsBridgeBackupEnabled", "\0").split("\0");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bridge">
|
<div className="bridge">
|
||||||
{ this.props.loading
|
{ this.props.loading
|
||||||
@@ -108,20 +107,26 @@ export default class Bridge extends Component<BridgeProps, BridgeState> {
|
|||||||
</div> )
|
</div> )
|
||||||
: this.renderStatus() }
|
: this.renderStatus() }
|
||||||
|
|
||||||
{ !this.props.loading && this.state.bridgeBackupEnabled !== undefined &&
|
{ !this.props.loading && this.props.options &&
|
||||||
<div className="bridge__options">
|
<div className="bridge__options">
|
||||||
<label className="option option--inline">
|
<label className="option option--inline">
|
||||||
<div className="option__control">
|
<div className="option__control">
|
||||||
<input name="bridgeBackupEnabled"
|
<input name="bridgeBackupEnabled"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={ this.state.bridgeBackupEnabled }
|
checked={ this.props.options.bridgeBackupEnabled }
|
||||||
onChange={ ev => {
|
onChange={ this.props.onChange } />
|
||||||
options.set("bridgeBackupEnabled"
|
|
||||||
, ev.target.checked);
|
|
||||||
}} />
|
|
||||||
</div>
|
</div>
|
||||||
<div className="option__label">
|
<div className="option__label">
|
||||||
{ _("optionsBridgeBackupEnabled") }
|
{ backupMessageStart }
|
||||||
|
<input className="bridge__backup-port"
|
||||||
|
name="bridgeBackupPort"
|
||||||
|
type="number"
|
||||||
|
required
|
||||||
|
min="1025"
|
||||||
|
max="65535"
|
||||||
|
value={ this.props.options.bridgeBackupPort }
|
||||||
|
onChange={ this.props.onChange } />
|
||||||
|
{ backupMessageEnd }
|
||||||
</div>
|
</div>
|
||||||
<div className="option__description">
|
<div className="option__description">
|
||||||
{ _("optionsBridgeBackupEnabledDescription") }
|
{ _("optionsBridgeBackupEnabledDescription") }
|
||||||
|
|||||||
@@ -171,9 +171,6 @@ class OptionsApp extends Component<{}, OptionsAppState> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Bridge info={ this.state.bridgeInfo }
|
|
||||||
loading={ this.state.bridgeLoading } />
|
|
||||||
|
|
||||||
<form id="form" ref={ form => { this.form = form; }}
|
<form id="form" ref={ form => { this.form = form; }}
|
||||||
onSubmit={ this.handleFormSubmit }
|
onSubmit={ this.handleFormSubmit }
|
||||||
onChange={ this.handleFormChange }>
|
onChange={ this.handleFormChange }>
|
||||||
@@ -415,6 +412,12 @@ class OptionsApp extends Component<{}, OptionsAppState> {
|
|||||||
{ _("optionsSave") }
|
{ _("optionsSave") }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{ // Workaround for form default button }
|
||||||
|
<Bridge info={ this.state.bridgeInfo }
|
||||||
|
loading={ this.state.bridgeLoading }
|
||||||
|
options={ this.state.options }
|
||||||
|
onChange={ this.handleInputChange } /> }
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<details className="about">
|
<details className="about">
|
||||||
|
|||||||
@@ -69,6 +69,7 @@
|
|||||||
.bridge {
|
.bridge {
|
||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
order: -1;
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,6 +195,12 @@
|
|||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bridge__backup-port {
|
||||||
|
width: 75px;
|
||||||
|
margin-left: 0.5em;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.category {
|
.category {
|
||||||
border: initial;
|
border: initial;
|
||||||
|
|||||||
Reference in New Issue
Block a user