mirror of https://github.com/Fabio286/mizar.git
refactor: improved typings
This commit is contained in:
parent
57c2af2c2b
commit
4e896244d1
100
CONTRIBUTING.md
100
CONTRIBUTING.md
|
@ -1,100 +0,0 @@
|
||||||
# Contributors Guide
|
|
||||||
|
|
||||||
Antares SQL is an application based on [Electron.js](https://www.electronjs.org/) that uses [Vue.js](https://vuejs.org/) and [Spectre.css](https://picturepan2.github.io/spectre/) as frontend frameworks.
|
|
||||||
For the build process it takes advantage of [electron-builder](https://www.electron.build/).
|
|
||||||
This application uses [Pinia🍍](https://pinia.vuejs.org/) as application state manager and [electron-store](https://github.com/sindresorhus/electron-store) to save the various settings on disc.
|
|
||||||
This guide aims to provide useful information and guidelines to everyone wants to contribute with this open-source project.
|
|
||||||
For every other question related to this project please [contact me](https://github.com/Fabio286).
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
The main files of the application are located inside `src` folder and are groupped in three subfolders.
|
|
||||||
|
|
||||||
### `common`
|
|
||||||
|
|
||||||
This folder contains small libraries, classes and objects. The purpose of `common` folder is to group together utilities used by **renderer** and **main** processes.
|
|
||||||
Noteworthy is the `customizations` folder that contains clients related customizations. Those settings are merged with `default.js` that lists every option.
|
|
||||||
Client related customizations are stored on Pinia and can be accessed by `customizations` property of current workspace object, or importing `common/customizations`.
|
|
||||||
|
|
||||||
An use case of customizations object can be the following:
|
|
||||||
|
|
||||||
```js
|
|
||||||
computed: {
|
|
||||||
defaultEngine () {
|
|
||||||
if (this.workspace.customizations.engines)
|
|
||||||
return this.workspace.engines.find(engine => engine.isDefault).name;
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In this case the computed property `defaultEngine` returns the default engine for MySQL client, or an empty string with PostgreSQL that doesn't have engines.
|
|
||||||
Customization properties are also useful **if some features are ready for one client but not others**.
|
|
||||||
|
|
||||||
### `main`
|
|
||||||
|
|
||||||
Inside this folder are located all files required by main process.
|
|
||||||
`ipc-handlers` subfolder includes all IPC handlers for events sent from renderer process.
|
|
||||||
`libs` subfolder includes classes related to clients and **query and connection logics**.
|
|
||||||
**Everything above client's class level should be "client agnostic"** with a neutral and uniformed api interface
|
|
||||||
|
|
||||||
### `renderer`
|
|
||||||
|
|
||||||
In this folder is located the structure of Vue frontend application.
|
|
||||||
|
|
||||||
## Build
|
|
||||||
|
|
||||||
The command to build Antares SQL locally is `npm run build`.
|
|
||||||
|
|
||||||
## Conventions
|
|
||||||
|
|
||||||
### Electron
|
|
||||||
|
|
||||||
- **kebab-case** for IPC event names.
|
|
||||||
|
|
||||||
### Vue
|
|
||||||
|
|
||||||
- **PascalCase** for file names (with .vue extension) and including components inside others (`<MyComponent/>`).
|
|
||||||
- "**Base**" prefix for [base component names](https://vuejs.org/v2/style-guide/#Base-component-names-strongly-recommended).
|
|
||||||
- "**The**" prefix for [single-instance component names](https://vuejs.org/v2/style-guide/#Single-instance-component-names-strongly-recommended).
|
|
||||||
- [Tightly coupled component names](https://vuejs.org/v2/style-guide/#Tightly-coupled-component-names-strongly-recommended).
|
|
||||||
- [Order of words in component names](https://vuejs.org/v2/style-guide/#Order-of-words-in-component-names-strongly-recommended).
|
|
||||||
- **kebab-case** in templates for property and event names.
|
|
||||||
|
|
||||||
### Code Style
|
|
||||||
|
|
||||||
The project includes [ESlint](https://eslint.org/) and [StyleLint](https://stylelint.io/) config files with style rules. I recommend to set the lint on-save option in your code editor.
|
|
||||||
Alternatively you can launch following commands to lint the project.
|
|
||||||
|
|
||||||
Check if all the style rules have been followed:
|
|
||||||
|
|
||||||
```console
|
|
||||||
npm run lint
|
|
||||||
```
|
|
||||||
|
|
||||||
Apply style rules globally if possible:
|
|
||||||
|
|
||||||
```console
|
|
||||||
npm run lint:fix
|
|
||||||
```
|
|
||||||
|
|
||||||
### Other recommendations
|
|
||||||
|
|
||||||
Please, use if possible **template literals** to compose strings and **avoid unnecessary dependencies**.
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
|
|
||||||
The commit style adopted for this project is [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
|
|
||||||
Basicly it's important to have **single scoped commits with a prefix** that follows this style because Antares SQL uses [standard-version](https://github.com/conventional-changelog/standard-version) to generate new releases and [CHANGELOG.md](https://github.com/Fabio286/antares/blob/master/CHANGELOG.md) file to track all notable changes.
|
|
||||||
For Visual Studio Code users may be useful [Conventional Commits](https://marketplace.visualstudio.com/items?itemName=vivaxy.vscode-conventional-commits) extension.
|
|
||||||
|
|
||||||
## Debug
|
|
||||||
|
|
||||||
**Debug mode**:
|
|
||||||
|
|
||||||
```console
|
|
||||||
npm run debug
|
|
||||||
```
|
|
||||||
|
|
||||||
After running the debug mode Antares will listen on port 9222 (main process) for a debugger.
|
|
||||||
On **Visual Studio Code** just launch "*Electron: Main*" configurations after running Antares in debug mode.
|
|
16
package.json
16
package.json
|
@ -87,26 +87,12 @@
|
||||||
"artifactName": "${productName}-${version}-portable.exe"
|
"artifactName": "${productName}-${version}-portable.exe"
|
||||||
},
|
},
|
||||||
"appx": {
|
"appx": {
|
||||||
"displayName": "Antares SQL",
|
"displayName": "Mizar TCP Tester",
|
||||||
"backgroundColor": "transparent",
|
"backgroundColor": "transparent",
|
||||||
"showNameOnTiles": true,
|
"showNameOnTiles": true,
|
||||||
"identityName": "62514FabioDiStasio.AntaresSQLClient",
|
"identityName": "62514FabioDiStasio.AntaresSQLClient",
|
||||||
"publisher": "CN=1A2729ED-865C-41D2-9038-39AE2A63AA52",
|
"publisher": "CN=1A2729ED-865C-41D2-9038-39AE2A63AA52",
|
||||||
"applicationId": "FabioDiStasio.AntaresSQLClient"
|
"applicationId": "FabioDiStasio.AntaresSQLClient"
|
||||||
},
|
|
||||||
"dmg": {
|
|
||||||
"contents": [
|
|
||||||
{
|
|
||||||
"x": 130,
|
|
||||||
"y": 220
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 410,
|
|
||||||
"y": 220,
|
|
||||||
"type": "link",
|
|
||||||
"path": "/Applications"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -3,6 +3,18 @@ import { ClientHost, ClientMessage } from 'common/interfaces';
|
||||||
import * as ElectronStore from 'electron-store';
|
import * as ElectronStore from 'electron-store';
|
||||||
const persistentStore = new ElectronStore({ name: 'client' });
|
const persistentStore = new ElectronStore({ name: 'client' });
|
||||||
|
|
||||||
|
interface SenderParams {
|
||||||
|
closeOnEcho: boolean;
|
||||||
|
persistentConnection: boolean;
|
||||||
|
nMsgs: number;
|
||||||
|
tMin: number;
|
||||||
|
tMax: number;
|
||||||
|
nClients: number;
|
||||||
|
trace: boolean;
|
||||||
|
alertReset: boolean;
|
||||||
|
loop: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
class Sender {
|
class Sender {
|
||||||
process: NodeJS.Process;
|
process: NodeJS.Process;
|
||||||
closeOnEcho: boolean;
|
closeOnEcho: boolean;
|
||||||
|
@ -17,15 +29,14 @@ class Sender {
|
||||||
nConnected: number;
|
nConnected: number;
|
||||||
nClosed: number;
|
nClosed: number;
|
||||||
nTryConnect: number;
|
nTryConnect: number;
|
||||||
nReceived: any[];
|
nReceived: number[];
|
||||||
nSent: number;
|
nSent: number;
|
||||||
timeStart: Date;
|
timeStart: Date;
|
||||||
hosts: ClientHost[];
|
hosts: ClientHost[];
|
||||||
messages: ClientMessage[];
|
messages: ClientMessage[];
|
||||||
nHostClients: any[];
|
nHostClients: number[];
|
||||||
nHostBytes: any[];
|
nHostBytes: number[];
|
||||||
nHostMsgs: any[];
|
nHostMsgs: number[];
|
||||||
storagePath: string;
|
|
||||||
loop: boolean;
|
loop: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +66,6 @@ class Sender {
|
||||||
this.nHostClients = [];
|
this.nHostClients = [];
|
||||||
this.nHostBytes = [];
|
this.nHostBytes = [];
|
||||||
this.nHostMsgs = [];
|
this.nHostMsgs = [];
|
||||||
this.storagePath = '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +84,7 @@ class Sender {
|
||||||
* @param {*} params
|
* @param {*} params
|
||||||
* @memberof Sender
|
* @memberof Sender
|
||||||
*/
|
*/
|
||||||
setParams (params: any) {
|
setParams (params: SenderParams) {
|
||||||
this.closeOnEcho = params.closeOnEcho;
|
this.closeOnEcho = params.closeOnEcho;
|
||||||
this.persistentConnection = params.persistentConnection;
|
this.persistentConnection = params.persistentConnection;
|
||||||
this.nMsgs = params.nMsgs;
|
this.nMsgs = params.nMsgs;
|
||||||
|
@ -86,16 +96,6 @@ class Sender {
|
||||||
this.loop = params.loop;
|
this.loop = params.loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Setta il percorso della cartella storage
|
|
||||||
*
|
|
||||||
* @param {string} storagePath
|
|
||||||
* @memberof Sender
|
|
||||||
*/
|
|
||||||
setStoragePath (storagePath: string) {
|
|
||||||
this.storagePath = storagePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Carica i messaggi in memoria
|
* Carica i messaggi in memoria
|
||||||
*
|
*
|
||||||
|
@ -188,7 +188,7 @@ class Sender {
|
||||||
|
|
||||||
const msg = this.randMsg();
|
const msg = this.randMsg();
|
||||||
|
|
||||||
client.write(msg, (err: any) => {
|
client.write(msg, (err: Error) => {
|
||||||
if (err)
|
if (err)
|
||||||
this.sendLog(`Socket #${clientId} su ${params.host}:${params.port}:\nErrore messaggio: ${err}`, 'red');
|
this.sendLog(`Socket #${clientId} su ${params.host}:${params.port}:\nErrore messaggio: ${err}`, 'red');
|
||||||
else {
|
else {
|
||||||
|
@ -208,7 +208,7 @@ class Sender {
|
||||||
this.sendLog(`Socket #${clientId} su ${params.host}:${params.port}:\n${err}`, 'red');
|
this.sendLog(`Socket #${clientId} su ${params.host}:${params.port}:\n${err}`, 'red');
|
||||||
}
|
}
|
||||||
|
|
||||||
client.on('connect', (err: any) => {
|
client.on('connect', (err: Error) => {
|
||||||
this.nTryConnect++;
|
this.nTryConnect++;
|
||||||
if (err)
|
if (err)
|
||||||
this.sendLog(`Errore connessione #${clientId} su ${params.host}:${params.port}:\n${err}`, 'red');
|
this.sendLog(`Errore connessione #${clientId} su ${params.host}:${params.port}:\n${err}`, 'red');
|
||||||
|
@ -236,7 +236,7 @@ class Sender {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('error', (err: any) => {
|
client.on('error', (err: Error & { code: string }) => {
|
||||||
switch (err.code) {
|
switch (err.code) {
|
||||||
case 'ECONNRESET':
|
case 'ECONNRESET':
|
||||||
if (this.alertReset)
|
if (this.alertReset)
|
||||||
|
@ -281,7 +281,7 @@ class Sender {
|
||||||
this.sendLog(`Socket #${clientId} su ${params.host}:${params.port}:\n${err}`, 'red');
|
this.sendLog(`Socket #${clientId} su ${params.host}:${params.port}:\n${err}`, 'red');
|
||||||
}
|
}
|
||||||
|
|
||||||
client.on('connect', (err: any) => {
|
client.on('connect', (err: Error) => {
|
||||||
this.nTryConnect++;
|
this.nTryConnect++;
|
||||||
if (err)
|
if (err)
|
||||||
this.sendLog(`Errore connessione #${clientId} su ${params.host}:${params.port}:\n${err}`, 'red');
|
this.sendLog(`Errore connessione #${clientId} su ${params.host}:${params.port}:\n${err}`, 'red');
|
||||||
|
@ -305,7 +305,7 @@ class Sender {
|
||||||
if (this.trace) this.sendLog(`Socket #${clientId} su ${params.host}:${params.port} chiuso`);
|
if (this.trace) this.sendLog(`Socket #${clientId} su ${params.host}:${params.port} chiuso`);
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('error', (err: any) => {
|
client.on('error', (err: Error & { code: string }) => {
|
||||||
switch (err.code) {
|
switch (err.code) {
|
||||||
case 'ECONNRESET':
|
case 'ECONNRESET':
|
||||||
if (this.alertReset)
|
if (this.alertReset)
|
||||||
|
@ -350,7 +350,7 @@ class Sender {
|
||||||
|
|
||||||
const msg = this.randMsg();
|
const msg = this.randMsg();
|
||||||
|
|
||||||
client.write(msg, (err: any) => {
|
client.write(msg, (err: Error) => {
|
||||||
if (err)
|
if (err)
|
||||||
this.sendLog(`Socket #${clientId} su ${params.host}:${params.port}:\nErrore messaggio: ${err}`, 'red');
|
this.sendLog(`Socket #${clientId} su ${params.host}:${params.port}:\nErrore messaggio: ${err}`, 'red');
|
||||||
else {
|
else {
|
||||||
|
@ -417,4 +417,4 @@ class Sender {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export { Sender };
|
export { Sender, SenderParams };
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
import { ServerPort } from 'common/interfaces';
|
import { ServerPort } from 'common/interfaces';
|
||||||
import * as net from 'net';
|
import * as net from 'net';
|
||||||
|
|
||||||
|
interface ServerParams {
|
||||||
|
trace: boolean;
|
||||||
|
echo: boolean;
|
||||||
|
alertReset: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
process: NodeJS.Process;
|
process: NodeJS.Process;
|
||||||
trace: boolean;
|
trace: boolean;
|
||||||
echo: boolean;
|
echo: boolean;
|
||||||
alertReset: boolean;
|
alertReset: boolean;
|
||||||
ports: ServerPort[];
|
ports: ServerPort[];
|
||||||
server: any[];
|
server: net.Server[];
|
||||||
nBytes: any[];
|
nBytes: number[];
|
||||||
nMsgs: any[];
|
nMsgs: number[];
|
||||||
|
|
||||||
constructor (process: NodeJS.Process) {
|
constructor (process: NodeJS.Process) {
|
||||||
this.process = process;
|
this.process = process;
|
||||||
|
@ -28,7 +34,7 @@ class Server {
|
||||||
* @param {*} ports
|
* @param {*} ports
|
||||||
* @memberof Server
|
* @memberof Server
|
||||||
*/
|
*/
|
||||||
setPorts (ports: any) {
|
setPorts (ports: ServerPort[]) {
|
||||||
this.ports = ports;
|
this.ports = ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +53,7 @@ class Server {
|
||||||
this.process.send(log);
|
this.process.send(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
startServer (params: any) {
|
startServer (params: ServerParams) {
|
||||||
this.trace = params.trace;
|
this.trace = params.trace;
|
||||||
this.echo = params.echo;
|
this.echo = params.echo;
|
||||||
this.alertReset = params.alertReset;
|
this.alertReset = params.alertReset;
|
||||||
|
@ -59,10 +65,10 @@ class Server {
|
||||||
this.nBytes[i] = 0;
|
this.nBytes[i] = 0;
|
||||||
this.nMsgs[i] = 0;
|
this.nMsgs[i] = 0;
|
||||||
|
|
||||||
this.server[i].on('connection', (socket: any) => {
|
this.server[i].on('connection', (socket: net.Socket) => {
|
||||||
if (this.trace) this.sendLog(`Client connesso su porta ${port}`);
|
if (this.trace) this.sendLog(`Client connesso su porta ${port}`);
|
||||||
|
|
||||||
socket.on('data', (msg: any) => {
|
socket.on('data', (msg: Buffer) => {
|
||||||
const msgString = msg.toString();
|
const msgString = msg.toString();
|
||||||
if (this.echo) socket.write(msg);
|
if (this.echo) socket.write(msg);
|
||||||
this.nBytes[i] += msg.length;
|
this.nBytes[i] += msg.length;
|
||||||
|
@ -75,7 +81,7 @@ class Server {
|
||||||
if (this.trace) this.sendLog(`Client disconnesso su porta ${port}`);
|
if (this.trace) this.sendLog(`Client disconnesso su porta ${port}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('error', (err: any) => {
|
socket.on('error', (err: Error & { code: string }) => {
|
||||||
switch (err.code) {
|
switch (err.code) {
|
||||||
case 'ECONNRESET':
|
case 'ECONNRESET':
|
||||||
if (this.alertReset)
|
if (this.alertReset)
|
||||||
|
@ -89,7 +95,7 @@ class Server {
|
||||||
});
|
});
|
||||||
});// <- server
|
});// <- server
|
||||||
|
|
||||||
this.server[i].on('error', (err: any) => {
|
this.server[i].on('error', (err: Error) => {
|
||||||
this.sendLog(`Errore server su porta ${port}: \n${err}`, 'red');
|
this.sendLog(`Errore server su porta ${port}: \n${err}`, 'red');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -102,7 +108,7 @@ class Server {
|
||||||
stopServer (callback: () => void) {
|
stopServer (callback: () => void) {
|
||||||
(async () => {
|
(async () => {
|
||||||
for (let i = 0; i < this.server.length; i++) {
|
for (let i = 0; i < this.server.length; i++) {
|
||||||
await this.server[i].close(function () {
|
this.server[i].close(() => {
|
||||||
this.server[i].unref();
|
this.server[i].unref();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -111,16 +117,16 @@ class Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
getReports () {
|
getReports () {
|
||||||
const reportList: any[] = [];
|
const reportList: {port: number; sockets: number; data: number; messages: number}[] = [];
|
||||||
for (let i = 0; i < this.server.length; i++) {
|
for (let i = 0; i < this.server.length; i++) {
|
||||||
const report = {
|
const report = {
|
||||||
port: this.server[i].address().port,
|
port: (this.server[i].address() as net.AddressInfo).port,
|
||||||
sockets: null as any,
|
sockets: null as number,
|
||||||
data: this.nBytes[i],
|
data: this.nBytes[i],
|
||||||
messages: this.nMsgs[i]
|
messages: this.nMsgs[i]
|
||||||
};
|
};
|
||||||
|
|
||||||
this.server[i].getConnections((err: any, nSockets: any) => {
|
this.server[i].getConnections((err: Error, nSockets: number) => {
|
||||||
if (err) this.sendLog(`Errore report: \n${err}`, 'red');
|
if (err) this.sendLog(`Errore report: \n${err}`, 'red');
|
||||||
report.sockets = nSockets;
|
report.sockets = nSockets;
|
||||||
reportList.push(report);
|
reportList.push(report);
|
||||||
|
@ -143,4 +149,4 @@ class Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export { Server };
|
export { Server, ServerParams };
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { app, BrowserWindow, nativeImage, ipcMain, Menu } from 'electron';
|
import { app, BrowserWindow, /* nativeImage, */ ipcMain, Menu } from 'electron';
|
||||||
import * as fs from 'fs';
|
// import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as Store from 'electron-store';
|
import * as Store from 'electron-store';
|
||||||
import { ChildProcess, fork, Serializable } from 'child_process';
|
import { ChildProcess, fork, Serializable } from 'child_process';
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { Sender } from '../libs/Sender';
|
import { ClientHost } from 'common/interfaces';
|
||||||
|
import { Sender, SenderParams } from '../libs/Sender';
|
||||||
|
|
||||||
const Sends = new Sender(process);
|
const Sends = new Sender(process);
|
||||||
let clientTimer: NodeJS.Timer;
|
let clientTimer: NodeJS.Timer;
|
||||||
|
|
||||||
process.on('message', (message: any) => {
|
process.on('message', (message: { event: string; hosts: ClientHost[]; params: SenderParams}) => {
|
||||||
switch (message.event) {
|
switch (message.event) {
|
||||||
case 'start':
|
case 'start':
|
||||||
Sends.setHosts(message.hosts);
|
Sends.setHosts(message.hosts);
|
||||||
Sends.setParams(message.params);
|
Sends.setParams(message.params);
|
||||||
Sends.setStoragePath(message.storagePath);
|
|
||||||
|
|
||||||
Sends.startFullTest(() => {
|
Sends.startFullTest(() => {
|
||||||
const response = {
|
const response = {
|
||||||
|
@ -31,7 +31,6 @@ process.on('message', (message: any) => {
|
||||||
case 'startStep':
|
case 'startStep':
|
||||||
Sends.setHosts(message.hosts);
|
Sends.setHosts(message.hosts);
|
||||||
Sends.setParams(message.params);
|
Sends.setParams(message.params);
|
||||||
Sends.setStoragePath(message.storagePath);
|
|
||||||
|
|
||||||
Sends.connectClients(() => {
|
Sends.connectClients(() => {
|
||||||
const response = {
|
const response = {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { Server } from '../libs/Server';
|
import { ServerPort } from 'common/interfaces';
|
||||||
|
import { Server, ServerParams } from '../libs/Server';
|
||||||
|
|
||||||
const myServer = new Server(process);
|
const myServer = new Server(process);
|
||||||
let serverTimer: NodeJS.Timer;
|
let serverTimer: NodeJS.Timer;
|
||||||
|
|
||||||
process.on('message', (message: {event: string; ports: string; params: any}) => {
|
process.on('message', (message: {event: string; ports: ServerPort[]; params: ServerParams}) => {
|
||||||
switch (message.event) {
|
switch (message.event) {
|
||||||
case 'start':
|
case 'start':
|
||||||
myServer.setPorts(message.ports);
|
myServer.setPorts(message.ports);
|
||||||
|
|
Loading…
Reference in New Issue