Files
mao1/shenyan-app/push-server.js

58 lines
1.5 KiB
JavaScript

const http = require('http');
const pending = [];
function parseBody(req) {
return new Promise((resolve, reject) => {
let body = '';
req.on('data', c => (body += c));
req.on('end', () => {
try {
resolve(body ? JSON.parse(body) : {});
} catch {
reject(new Error('Invalid JSON'));
}
});
});
}
const server = http.createServer(async (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === 'OPTIONS') {
res.writeHead(204);
return res.end();
}
// POST /push/send — queue a notification
if (req.method === 'POST' && req.url === '/push/send') {
const { title, body } = await parseBody(req);
const msg = {
id: Date.now(),
title: title || '沈晏',
body: body || '',
time: new Date().toISOString(),
};
pending.push(msg);
res.writeHead(200, { 'Content-Type': 'application/json' });
return res.end(JSON.stringify({ ok: true, queued: msg }));
}
// GET /push/poll — fetch pending messages, then clear
if (req.method === 'GET' && req.url === '/push/poll') {
const snapshot = [...pending];
pending.length = 0;
res.writeHead(200, { 'Content-Type': 'application/json' });
return res.end(JSON.stringify({ messages: snapshot }));
}
res.writeHead(404);
res.end('not found');
});
server.listen(3002, () => {
console.log('push-broker on http://localhost:3002');
});