Skip to content

Commit

Permalink
ported to webserver
Browse files Browse the repository at this point in the history
  • Loading branch information
foxriver76 committed Apr 27, 2024
1 parent 3023b11 commit b059d97
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 91 deletions.
6 changes: 6 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": ["@foxriver76/eslint-config"],
"rules": {
"unicorn/prefer-module": 0
}
}
10 changes: 5 additions & 5 deletions .github/workflows/test-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ jobs:

steps:
- uses: actions/checkout@v4
- name: Use Node.js 16.x
- name: Use Node.js 18.x
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 18.x


- name: Install Dependencies
Expand All @@ -57,7 +57,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [16.x, 18.x]
node-version: [18.x, 20.x]
os: [ubuntu-latest, windows-latest, macos-latest]

steps:
Expand Down Expand Up @@ -96,10 +96,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Use Node.js 16.x
- name: Use Node.js 18.x
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 18.x

- name: Extract the version and commit body from the tag
id: extract_release
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ You can set the option *Force Web-Sockets* to force using only web-sockets trans
-->

## Changelog
### **WORK IN PROGRESS**
* (foxriver76) ported to webserver

### 6.6.1 (2024-02-22)
* (bluefox) Just some packages were updated

Expand Down
184 changes: 101 additions & 83 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
'use strict';

const adapterName = require('./package.json').name.split('.').pop();
const utils = require('@iobroker/adapter-core'); // Get common adapter utils
const SocketIO = require('./lib/socketIO.js');
const LE = utils.commonTools.letsEncrypt;
const socketio = require('socket.io');
const utils = require('@iobroker/adapter-core'); // Get common adapter utils
const SocketIO = require('./lib/socketIO.js');
const socketio = require('socket.io');
const { WebServer } = require('@iobroker/webserver');

let webServer = null;
let secret = 'Zgfr56gFe87jJOM'; // Will be generated by first start
let webServer = null;
let secret = 'Zgfr56gFe87jJOM'; // Will be generated by first start

let adapter;
function startAdapter(options) {
options = options || {};

Object.assign(options, {name: adapterName});
Object.assign(options, { name: adapterName });

adapter = new utils.Adapter(options);

Expand All @@ -42,7 +42,9 @@ function startAdapter(options) {
try {
adapter.setState && adapter.setState('info.connected', '', true);
adapter.setState && adapter.setState('info.connection', false, true);
adapter.log.info(`terminating http${webServer.settings.secure ? 's' : ''} server on port ${webServer.settings.port}`);
adapter.log.info(
`terminating http${webServer.settings.secure ? 's' : ''} server on port ${webServer.settings.port}`
);
webServer.io.close();
webServer.server.close();

Expand All @@ -59,9 +61,9 @@ function startAdapter(options) {
if (!err && obj) {
if (!obj.native || !obj.native.secret) {
obj.native = obj.native || {};
require('crypto').randomBytes(24, (ex, buf) => {
require('node:crypto').randomBytes(24, (ex, buf) => {
secret = buf.toString('hex');
adapter.extendForeignObject('system.config', {native: {secret: secret}});
adapter.extendForeignObject('system.config', { native: { secret: secret } });
main();
});
} else {
Expand All @@ -78,7 +80,8 @@ function startAdapter(options) {
});

adapter.on('message', obj => {
if (!obj || obj.command !== 'im') { // if not instance message
if (!obj || obj.command !== 'im') {
// if not instance message
return;
}

Expand All @@ -92,8 +95,7 @@ function startAdapter(options) {
}
});

adapter.on('log', obj =>
webServer && webServer.io && webServer.io.sendLog(obj));
adapter.on('log', obj => webServer && webServer.io && webServer.io.sendLog(obj));

return adapter;
}
Expand All @@ -103,7 +105,7 @@ function main() {
// Load certificates
adapter.getCertificates((err, certificates, leConfig) => {
adapter.config.certificates = certificates;
adapter.config.leConfig = leConfig;
adapter.config.leConfig = leConfig;
webServer = initWebServer(adapter.config);
});
} else {
Expand All @@ -119,10 +121,10 @@ function main() {
//}
function initWebServer(settings) {
const server = {
app: null,
app: null,
server: null,
io: null,
settings,
io: null,
settings
};
let store = null;

Expand All @@ -133,86 +135,102 @@ function initWebServer(settings) {
return null;
}

settings.crossDomain = true;
settings.ttl = settings.ttl || 3600;
settings.crossDomain = true;
settings.ttl = settings.ttl || 3600;
settings.forceWebSockets = settings.forceWebSockets || false;

if (settings.auth) {
const session = require('express-session');
const AdapterStore = utils.commonTools.session(session, settings.ttl);
const session = require('express-session');
const AdapterStore = utils.commonTools.session(session, settings.ttl);
// Authentication checked by server itself
store = new AdapterStore({adapter});
settings.forceWebSockets = settings.forceWebSockets || false;
store = new AdapterStore({ adapter });
settings.forceWebSockets = settings.forceWebSockets || false;
}

adapter.getPort(settings.port, (!settings.bind || settings.bind === '0.0.0.0') ? undefined : settings.bind || undefined, async port => {
if (parseInt(port, 10) !== settings.port && !adapter.config.findNextPort) {
adapter.log.error(`port ${settings.port} already in use`);
return adapter.terminate ? adapter.terminate(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION) : process.exit(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION);
}

settings.port = port;

try {
if (typeof LE.createServerAsync === 'function')
server.server = await LE.createServerAsync((req, res) => {
res.writeHead(501);
res.end('Not Implemented');
}, settings, adapter.config.certificates, adapter.config.leConfig, adapter.log, adapter);
else {
server.server = LE.createServer((req, res) => {
res.writeHead(501);
res.end('Not Implemented');
}, settings, adapter.config.certificates, adapter.config.leConfig, adapter.log);
adapter.getPort(
settings.port,
!settings.bind || settings.bind === '0.0.0.0' ? undefined : settings.bind || undefined,
async port => {
if (parseInt(port, 10) !== settings.port && !adapter.config.findNextPort) {
adapter.log.error(`port ${settings.port} already in use`);
return adapter.terminate
? adapter.terminate(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION)
: process.exit(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION);
}
} catch (err) {
adapter.log.error(`Cannot create webserver: ${err}`);
adapter.terminate ? adapter.terminate(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION) : process.exit(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION);
return;
}
if (!server.server) {
adapter.log.error(`Cannot create webserver`);
adapter.terminate ? adapter.terminate(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION) : process.exit(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION);
return;
}

let serverListening = false;
server.server.on('error', e => {
if (e.toString().includes('EACCES') && port <= 1024) {
adapter.log.error(`node.js process has no rights to start server on the port ${port}.\n` +
'Do you know that on linux you need special permissions for ports under 1024?\n' +
'You can call in shell following scrip to allow it for node.js: "iobroker fix"'
);
} else {
adapter.log.error(`Cannot start server on ${settings.bind || '0.0.0.0'}:${port}: ${e}`);
settings.port = port;

try {
const webserver = new WebServer({
app: server.app,
adapter,
secure: adapter.config.secure
});
// initialize and you can use your server as known
server.server = await webserver.init();
} catch (err) {
adapter.log.error(`Cannot create webserver: ${err}`);
adapter.terminate
? adapter.terminate(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION)
: process.exit(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION);
return;
}
if (!serverListening) {
adapter.terminate ? adapter.terminate(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION) : process.exit(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION);
if (!server.server) {
adapter.log.error(`Cannot create webserver`);
adapter.terminate
? adapter.terminate(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION)
: process.exit(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION);
return;
}
});

// Start the web server
server.server.listen(settings.port, (!settings.bind || settings.bind === '0.0.0.0') ? undefined : settings.bind || undefined, () => {
adapter.setState('info.connection', true, true);
serverListening = true
});
let serverListening = false;
server.server.on('error', e => {
if (e.toString().includes('EACCES') && port <= 1024) {
adapter.log.error(
`node.js process has no rights to start server on the port ${port}.\n` +
'Do you know that on linux you need special permissions for ports under 1024?\n' +
'You can call in shell following scrip to allow it for node.js: "iobroker fix"'
);
} else {
adapter.log.error(`Cannot start server on ${settings.bind || '0.0.0.0'}:${port}: ${e}`);
}
if (!serverListening) {
adapter.terminate
? adapter.terminate(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION)
: process.exit(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION);
}
});

// Start the web server
server.server.listen(
settings.port,
!settings.bind || settings.bind === '0.0.0.0' ? undefined : settings.bind || undefined,
() => {
adapter.setState('info.connection', true, true);
serverListening = true;
}
);

server.io = new SocketIO(settings, adapter);
const socketOptions = {
pingInterval: 120000,
pingTimeout: 30000,
cors: {
// for socket.4.x
origin: `*`,
allowedHeaders: ['*'],
credentials: true
}
};

server.io = new SocketIO(settings, adapter);
const socketOptions = {
pingInterval: 120000,
pingTimeout: 30000,
cors: { // for socket.4.x
origin: `*`,
allowedHeaders: ['*'],
credentials: true
},
};

server.io.start(server.server, socketio, {store, secret}, socketOptions);
});
server.io.start(server.server, socketio, { store, secret }, socketOptions);
}
);
} else {
adapter.log.error('port missing');
adapter.terminate ? adapter.terminate(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION) : process.exit(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION);
adapter.terminate
? adapter.terminate(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION)
: process.exit(utils.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION);
}

return server;
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,21 @@
"node": ">= 16"
},
"dependencies": {
"@iobroker/adapter-core": "^3.0.4",
"@iobroker/adapter-core": "^3.1.4",
"@iobroker/socket-classes": "1.5.0",
"@iobroker/webserver": "^1.0.3",
"express-session": "^1.18.0",
"socket.io": "^2.5.0"
},
"devDependencies": {
"@alcalzone/release-script": "^3.7.0",
"@alcalzone/release-script-plugin-iobroker": "^3.7.0",
"@alcalzone/release-script-plugin-license": "^3.7.0",
"@foxriver76/eslint-config": "^1.0.4",
"@iobroker/adapter-dev": "^1.3.0",
"@iobroker/legacy-testing": "^1.0.9",
"socket.io-client": "^2.5.0",
"gulp": "^4.0.2"
"gulp": "^4.0.2",
"socket.io-client": "^2.5.0"
},
"bugs": {
"url": "https://github.com/ioBroker/ioBroker.socketio/issues"
Expand Down
1 change: 1 addition & 0 deletions prettier.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('@foxriver76/eslint-config/prettier');

0 comments on commit b059d97

Please sign in to comment.