added basic rest api
This commit is contained in:
parent
e3a30f9396
commit
0fa7ca78a6
7 changed files with 122 additions and 30 deletions
59
classes/Api.js
Normal file
59
classes/Api.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
const AudioServer = require("./AudioServer");
|
||||
|
||||
class Api {
|
||||
|
||||
constructor() {
|
||||
this.get = new Map();
|
||||
this.post = new Map();
|
||||
this.#setup();
|
||||
}
|
||||
|
||||
async handleRequest(request) {
|
||||
if (request === undefined) {
|
||||
return this.#createRequestResult(500);
|
||||
}
|
||||
const fn = this.#getFunction(request.url, request.method.toLowerCase());
|
||||
if (fn === undefined) {
|
||||
return this.#createRequestResult(501);
|
||||
}
|
||||
await fn();
|
||||
return this.#createRequestResult();
|
||||
}
|
||||
|
||||
#createRequestResult(code, message) {
|
||||
if (code === undefined) {
|
||||
code = 200;
|
||||
}
|
||||
const result = {
|
||||
code: code
|
||||
};
|
||||
if (message !== undefined) {
|
||||
result.message = message;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#setup() {
|
||||
this.#registerEndpoint(constants.API_PLAY, constants.REQUEST_METHOD_POST, () => {
|
||||
new AudioServer('/mnt/kingston/public/LEFTOVER.flac');
|
||||
});
|
||||
}
|
||||
|
||||
#getFunction(url, method) {
|
||||
if (url === undefined || method === undefined || this[method] === undefined) {
|
||||
return;
|
||||
}
|
||||
return this[method].get(url);
|
||||
}
|
||||
|
||||
#registerEndpoint(url, method, fn) {
|
||||
if (url === undefined || method === undefined || fn === undefined || this[method] === undefined) {
|
||||
return false;
|
||||
}
|
||||
this[method].set(url, fn);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Api;
|
43
classes/ApiServer.js
Normal file
43
classes/ApiServer.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
const Api = require('./Api.js');
|
||||
const http = require('http');
|
||||
|
||||
class ApiServer {
|
||||
|
||||
constructor() {
|
||||
this.listen = config.api?.listen || "0.0.0.0";
|
||||
this.port = config.api?.port || 9000;
|
||||
this.api = new Api();
|
||||
this.server = http.createServer();
|
||||
this.requestId = 0;
|
||||
}
|
||||
|
||||
start() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.server.listen(this.port, this.listen).on('listening', () => {
|
||||
this.port = this.server.address().port;
|
||||
logger.info('api server listening on ' + this.listen + ':' + this.port + '...');
|
||||
this.#handleRequests();
|
||||
resolve();
|
||||
});
|
||||
this.server.on('error', (err) => {
|
||||
reject('an unexpected error occured: ' + err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#handleRequests() {
|
||||
this.server.on('request', async (request, response) => {
|
||||
request.timestamp = Date.now();
|
||||
request.id = this.requestId;
|
||||
this.requestId++;
|
||||
logger.debug('handling api request #' + request.id + ' \'' + request.url + '\'...');
|
||||
const result = await this.api.handleRequest(request);
|
||||
response.writeHead(result.code);
|
||||
response.end(result.message);
|
||||
logger.debug('handling api request #' + request.id + '\'' + request.url + '\' took ' + (Date.now() - request.timestamp) + 'ms');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = ApiServer;
|
|
@ -48,30 +48,6 @@ class Logger {
|
|||
this.timestamp = value || 'DD.MM.YYYY HH:mm:ss:SS';
|
||||
}
|
||||
|
||||
// log a http request - response object
|
||||
http(object) {
|
||||
if (object === undefined) {
|
||||
return;
|
||||
}
|
||||
let message = '[' + object.request.method + ':' + object.code + '] url: \'' + object.request.url + '\'';
|
||||
let counter = 1;
|
||||
for (let param in object.request.body) {
|
||||
message += ', parameter ' + counter + ': \'' + param + '=' + object.request.body[param] + '\'';
|
||||
counter++;
|
||||
}
|
||||
if (object.request.timestamp) {
|
||||
message += ' > ' + (new Date().getTime() - object.request.timestamp) + 'ms';
|
||||
}
|
||||
if (object.data) {
|
||||
message += ' > data: ' + object.data;
|
||||
}
|
||||
if (object.code != 200) {
|
||||
error(message.trim());
|
||||
return;
|
||||
}
|
||||
this.debug(message.trim());
|
||||
}
|
||||
|
||||
// prefix log with 'info'
|
||||
info(message) {
|
||||
if (this.loglevel > LOGLEVEL_INFO) {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
const net = require('net');
|
||||
|
||||
const Client = require('./Client.js');
|
||||
|
||||
const AudioServer = require('./AudioServer.js');
|
||||
const net = require('net');
|
||||
|
||||
class Server {
|
||||
|
||||
|
@ -18,6 +16,7 @@ class Server {
|
|||
this.server.listen(this.port, this.listen).on('listening', () => {
|
||||
this.port = this.server.address().port;
|
||||
logger.info('communication server listening on ' + this.listen + ':' + this.port + '...');
|
||||
resolve();
|
||||
});
|
||||
this.server.on('connection', (socket) => {
|
||||
this.#addClient(socket);
|
||||
|
@ -44,7 +43,6 @@ class Server {
|
|||
|
||||
#addClient(socket) {
|
||||
this.clients.push(new Client(socket));
|
||||
new AudioServer('/mnt/kingston/public/DOPESMOKER.flac');
|
||||
}
|
||||
|
||||
removeClient(client) {
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
"port": 3000,
|
||||
"heartbeat": 10000
|
||||
},
|
||||
"api": {
|
||||
"enabled": true,
|
||||
"listen": "0.0.0.0",
|
||||
"port": 9000
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"timestamp": "DD.MM.YYYY HH:mm:ss:SS"
|
||||
|
@ -22,7 +27,7 @@
|
|||
"password": "kannon"
|
||||
},
|
||||
"audio": {
|
||||
"threshold": 30,
|
||||
"threshold": 10,
|
||||
"bufferlimit": 64
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ const Database = require('./classes/Database.js');
|
|||
const Queue = require('./classes/Queue.js');
|
||||
const Watcher = require('./classes/Watcher.js');
|
||||
const EventParser = require('./classes/EventParser');
|
||||
const ApiServer = require('./classes/ApiServer.js');
|
||||
|
||||
const INTERRUPTS = ['beforeExit', 'SIGINT', 'SIGTERM'];
|
||||
|
||||
|
@ -36,6 +37,11 @@ async function main() {
|
|||
global.server = new Server();
|
||||
await global.server.start();
|
||||
}
|
||||
// api server
|
||||
if (util.isEnabled(global.config.api)) {
|
||||
global.apiserver = new ApiServer();
|
||||
global.apiserver.start();
|
||||
}
|
||||
// queue and watcher
|
||||
if (util.isEnabled(global.config.library)) {
|
||||
global.queue = new Queue();
|
||||
|
|
|
@ -10,5 +10,10 @@ module.exports = {
|
|||
CLIENT_STATE_PLAYING: 'playing',
|
||||
CLIENT_STATE_PAUSED: 'paused',
|
||||
CLIENT_STATE_STOPPED: 'stopped',
|
||||
CLIENT_STATE_ERROR: 'error'
|
||||
CLIENT_STATE_ERROR: 'error',
|
||||
|
||||
REQUEST_METHOD_GET: 'get',
|
||||
REQUEST_METHOD_POST: 'post',
|
||||
|
||||
API_PLAY: '/play'
|
||||
}
|
Loading…
Reference in a new issue