feat: Node.js consumer amqplib
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "iot-consumer",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "server.js",
|
||||||
|
"scripts": { "start": "node server.js" },
|
||||||
|
"dependencies": { "amqplib": "^0.10.0", "express": "^4.21.0", "redis": "^4.7.0", "mongodb": "^6.0.0" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Flask>=3.0
|
||||||
|
gunicorn>=21.2
|
||||||
|
redis>=5.0
|
||||||
|
pymongo>=4.0
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
const amqp = require("amqplib");
|
||||||
|
const express = require("express");
|
||||||
|
const { createClient } = require("redis");
|
||||||
|
const { MongoClient } = require("mongodb");
|
||||||
|
|
||||||
|
const RMQ_HOST = process.env.RMQ_HOST || "localhost";
|
||||||
|
const RMQ_PORT = parseInt(process.env.RMQ_PORT || "5672");
|
||||||
|
const RMQ_USER = process.env.RMQ_USER || "guest";
|
||||||
|
const RMQ_PASS = process.env.RMQ_PASS || "guest";
|
||||||
|
const RMQ_QUEUE = process.env.RMQ_QUEUE || "iot-events";
|
||||||
|
|
||||||
|
const REDIS_HOST = process.env.REDIS_HOST || "localhost";
|
||||||
|
const REDIS_PORT = parseInt(process.env.REDIS_PORT || "6379");
|
||||||
|
const REDIS_PASS = process.env.REDIS_PASS || undefined;
|
||||||
|
|
||||||
|
const MONGO_URI = process.env.MONGO_URI || "mongodb://localhost:27017/iot";
|
||||||
|
const MONGO_DB = process.env.MONGO_DB || "iot";
|
||||||
|
|
||||||
|
let consumed = 0, errors = 0;
|
||||||
|
let redis, mongo, mongoColl;
|
||||||
|
|
||||||
|
async function getRedis() {
|
||||||
|
if (!redis) {
|
||||||
|
redis = createClient({ socket: { host: REDIS_HOST, port: REDIS_PORT }, password: REDIS_PASS });
|
||||||
|
redis.on("error", () => {});
|
||||||
|
await redis.connect();
|
||||||
|
console.log("Redis connected");
|
||||||
|
}
|
||||||
|
return redis;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getMongo() {
|
||||||
|
if (!mongo) {
|
||||||
|
mongo = new MongoClient(MONGO_URI);
|
||||||
|
await mongo.connect();
|
||||||
|
mongoColl = mongo.db(MONGO_DB).collection("iot_events");
|
||||||
|
await mongoColl.createIndex({ timestamp: 1 }, { expireAfterSeconds: 604800 });
|
||||||
|
console.log("MongoDB connected");
|
||||||
|
}
|
||||||
|
return mongoColl;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function store(event) {
|
||||||
|
const r = await getRedis();
|
||||||
|
await r.hSet("iot:latest", event.sensor_id, JSON.stringify({
|
||||||
|
value: event.value, unit: event.unit, location: event.location, timestamp: event.timestamp,
|
||||||
|
}));
|
||||||
|
await r.hIncrBy("iot:counters", event.device_type, 1);
|
||||||
|
await r.zAdd("iot:recent", [{ score: 0, value: JSON.stringify(event) }]);
|
||||||
|
await r.zRemRangeByRank("iot:recent", 0, -1001);
|
||||||
|
const coll = await getMongo();
|
||||||
|
await coll.insertOne({
|
||||||
|
event_id: event.event_id, sensor_id: event.sensor_id,
|
||||||
|
device_type: event.device_type, location: event.location,
|
||||||
|
value: event.value, unit: event.unit, timestamp: new Date(event.timestamp),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function start() {
|
||||||
|
const conn = await amqp.connect(`amqp://${RMQ_USER}:${RMQ_PASS}@${RMQ_HOST}:${RMQ_PORT}`);
|
||||||
|
const ch = await conn.createChannel();
|
||||||
|
await ch.assertQueue(RMQ_QUEUE, { durable: true });
|
||||||
|
ch.prefetch(10);
|
||||||
|
await ch.consume(RMQ_QUEUE, async (msg) => {
|
||||||
|
try {
|
||||||
|
if (msg) {
|
||||||
|
const event = JSON.parse(msg.content.toString());
|
||||||
|
await store(event);
|
||||||
|
consumed++;
|
||||||
|
ch.ack(msg);
|
||||||
|
if (consumed % 10 === 0) console.log(`Consumed ${consumed} events`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
errors++;
|
||||||
|
console.error("Error:", e.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(`Consumer listening on queue: ${RMQ_QUEUE}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
app.get("/", (req, res) => res.json({ service: "iot-consumer", status: "running", queue: RMQ_QUEUE, consumed, errors }));
|
||||||
|
app.get("/health", (req, res) => res.json({ status: "ok" }));
|
||||||
|
app.listen(process.env.PORT || 3000, () => { console.log("Consumer started"); start(); });
|
||||||
Reference in New Issue
Block a user