Add options to switch bridge backup WebSocket server port

This commit is contained in:
hensm
2020-02-26 16:31:18 +00:00
parent af521f9a0f
commit 78d8516287
8 changed files with 62 additions and 23 deletions

View File

@@ -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

View File

@@ -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."

View File

@@ -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

View File

@@ -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));

View File

@@ -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;

View File

@@ -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") }

View File

@@ -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">

View File

@@ -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;