parent
3f814cc97f
commit
694ddd0b87
@ -0,0 +1,9 @@
|
|||||||
|
FROM node:20-alpine
|
||||||
|
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm ci --omit=dev
|
||||||
|
COPY src/. .
|
||||||
|
|
||||||
|
EXPOSE 4000 7000
|
||||||
|
CMD [ "node", "src/main.js" ]
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
STORAGE_URL = gitea.bjornmossa.net
|
||||||
|
IMAGE_NAME = $(STORAGE_URL)/radioiceberg/metadata
|
||||||
|
GIT_TAG = $(shell git describe --abbrev=0 --tags)
|
||||||
|
|
||||||
|
login:
|
||||||
|
docker login $(STORAGE_URL)
|
||||||
|
|
||||||
|
start:
|
||||||
|
npx live-server ./src
|
||||||
|
|
||||||
|
build:
|
||||||
|
docker build . -t $(IMAGE_NAME):$(GIT_TAG)
|
||||||
|
|
||||||
|
bump-latest:
|
||||||
|
docker tag $(IMAGE_NAME):$(GIT_TAG) $(IMAGE_NAME):latest
|
||||||
|
|
||||||
|
push-current: login
|
||||||
|
docker push $(IMAGE_NAME):$(GIT_TAG)
|
||||||
|
|
||||||
|
push-latest: login
|
||||||
|
docker push $(IMAGE_NAME):latest
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "iceberg-metadata",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Microservice for updating metadata on radio",
|
||||||
|
"main": "main.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/Arseniusz/radioiceberg.git"
|
||||||
|
},
|
||||||
|
"author": "radio iceberg team",
|
||||||
|
"license": "GPL-3.0-or-later",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/Arseniusz/radioiceberg/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/Arseniusz/radioiceberg#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"ws": "^8.13.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
import { createServer } from "node:http";
|
||||||
|
import { randomUUID } from "node:crypto";
|
||||||
|
import { WebSocketServer } from "ws";
|
||||||
|
import { notifier } from "./notifier.js";
|
||||||
|
|
||||||
|
const wss = new WebSocketServer({ port: 7000 });
|
||||||
|
|
||||||
|
wss.on("connection", (ws) => {
|
||||||
|
const id = randomUUID();
|
||||||
|
const message = {
|
||||||
|
command: "clientConnected",
|
||||||
|
data: {
|
||||||
|
socket: ws,
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
notifier.processMessage(message);
|
||||||
|
|
||||||
|
ws.on("close", () => {
|
||||||
|
const message = {
|
||||||
|
command: "cliendDisconnected",
|
||||||
|
data: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
notifier.processMessage(message);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
createServer((req, res) => {
|
||||||
|
let body = "";
|
||||||
|
|
||||||
|
req.on("data", (chunk) => {
|
||||||
|
body += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on("end", () => {
|
||||||
|
try {
|
||||||
|
const message = JSON.parse(body);
|
||||||
|
notifier.processMessage(message);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res.end();
|
||||||
|
}).listen(4000);
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
import { state } from "./state.js";
|
||||||
|
|
||||||
|
function updateMeta(message) {
|
||||||
|
const { data } = message;
|
||||||
|
this.state.lastPlayed = data;
|
||||||
|
this.notifyAll(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startOnline(message) {
|
||||||
|
this.state.isOnline = true;
|
||||||
|
this.notifyAll(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopOnline(message) {
|
||||||
|
this.state.isOnline = false;
|
||||||
|
this.notifyAll(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addClient({ data }) {
|
||||||
|
const { socket, id } = data;
|
||||||
|
this.clients.set(id, socket);
|
||||||
|
this.notifyOne(socket, { command: "setState", data: this.state });
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteClient({ data }) {
|
||||||
|
const { id } = data;
|
||||||
|
this.clients.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
clientConnected: addClient,
|
||||||
|
cliendDisconnected: deleteClient,
|
||||||
|
metadataChange: updateMeta,
|
||||||
|
liveStarted: startOnline,
|
||||||
|
liveEnded: stopOnline,
|
||||||
|
};
|
||||||
|
|
||||||
|
const notifier = {
|
||||||
|
__proto__: state,
|
||||||
|
notifyAll: function (message) {
|
||||||
|
const messageStrinified = JSON.stringify(message);
|
||||||
|
this.clients.forEach((c) => c.send(messageStrinified));
|
||||||
|
},
|
||||||
|
notifyOne: function (socket, message) {
|
||||||
|
const messageStrinified = JSON.stringify(message);
|
||||||
|
console.log("NOTIFY ONE:", message);
|
||||||
|
socket.send(messageStrinified);
|
||||||
|
},
|
||||||
|
processMessage: function (message) {
|
||||||
|
const action = actions[message.command];
|
||||||
|
if (action) {
|
||||||
|
action.call(this, message);
|
||||||
|
console.log("PERFORM ACTION", message.command);
|
||||||
|
} else {
|
||||||
|
console.log("no avaible command for state mutation", message.command);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export { notifier };
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
const state = {
|
||||||
|
state: {
|
||||||
|
lastPlayed: null,
|
||||||
|
isOnline: false,
|
||||||
|
},
|
||||||
|
clients: new Map(),
|
||||||
|
};
|
||||||
|
|
||||||
|
export { state };
|
||||||
Reference in new issue