Автор оригинала: Saurabh Kashyap.
Позвольте мне сказать вам, почему Web Push-уведомление необходим для любого веб-приложения.
Это помогает в трансляции коротких сообщений с подписчиком веб-приложения и, а также, а также поможет поддержать взаимодействие пользователя с вашим приложением, чтобы уведомить каждые подписчики, это действительно трудно любую организацию отправить уведомление по электронной почте для короткого обмена сообщениями или трансляцией Сообщения, такие как предложения и обновления коротких сообщений, а также повышает стоимость серверных операций, чтобы решение было Web Push-уведомление .it Помогите вашу максимальную доступность пост.
Позвольте мне сказать вам, как это работает.
Сервисский работник является главным ключевым ингредиатом и рыцарями этой функции, которая устанавливает в клиент Broswer и запускает интенсивность в качестве приложения после включения в браузере в качестве сервисного работника, который регулярно отправляет запрос к серверу поставщика, и попросить любое новое событие, а также отвечать на любое новое событие, а не отвечать на клиент, если на сервере происходит какое-либо новое событие, которое он всплывает сообщение, как
Нажмите на кнопку «Разрешить работник службы» Начните устанавливать в браузере клиента и отправить запрос на обещание для подписчика с Публичный ключ Vapib и проверьте на сервере, чтобы пользователь уже подписаться уведомление или нет, если он уже подписывается, он отправил обратный запрос с ложным утверждением, в противном случае сервер отправил истинный запрос. И сделал это это. Теперь давайте приходим к разделу кодирования и как реализовать эту функцию в вашем приложении без использования сторонних платных услуг и использовании до тех пор, пока вы.
Шаг 1
Нужна предварительная преследование, которые перечислены ниже, если у вас нет в вашей системе. Перыефы:
Теперь давайте начнем с следующего шага
Шаг 2
Откройте свою IDE Визуальный студийный код И чем запустить команду в интегрированном терминале с вашей IDE
git init
Чем добавьте все поля или пропустить, как хотите, и, чем снова запустить команду, чтобы включить все зависимость с
npm install express web-push body-parser mongoose q --save
и нажмите Enter и ждать установки все зависимость правильно устанавливалось в вашем проекте, чем запустить снова запустить команду для создания нового файла запуска приложения в том же папке проекта
touch server.js
И снова нужно создать три папки в том же каталоге проекта по командам, как показано ниже
mkdir config cd config touch keys.js touch keys_prod.js touch keys_dev.js
mkdir model cd model touch subscribers_model.js
mkdir router cd router touch push.js touch subscriber.js touch index.js
Теперь все основные папки и файлы создаются и в этом проекте мы переходим к следующим запчагам кодирования на следующем шаге.
Шаг 3
Структура файла этого проекта ниже
| | |________________________./config | | | |____keys_prod.js | |____keys_dev.js | |____keys.js | |________________________./public | | | |____index.html | |____sw.js | |____app.js | |________________________./model | | | |____subscribers_model.js | |________________________./router | | | |____push.js | |____subscribe.js | |___________________________server.js
Теперь начните с создания модели базы данных для базы данных MongoDB. Так что теперь я использую Мангуст ODM ORM Библиотека для Монгодб который уже установлен в проекте
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const SubscriberSchema = new Schema({ endpoint: String, keys: Schema.Types.Mixed, createDate: { type: Date, default: Date.now } }); mongoose.model('subscribers', SubscriberSchema, 'subscribers');
Так что теперь давайте приедем в файл конфигурации
cd config
и чем откройте файл keys.js, который уже создан в этой папке
if (process.env.NODE_ENV === 'production') { module.exports = require('./keys_prod'); } else { module.exports = require('./keys_dev'); }
И обновите файл Keys.js с помощью этого кода, фактически этот код предоставляет адрес аутентификации базы данных Smart Switch между производственным и разработкой. Перед обновлением Keys_Prod.js и файл keys_dev.js генерируют кнопки VAPID для браузера клиентского устройства и между запуском сервера. Используя эту команду
./node_modules/.bin/web-push generate-vapid-keys
Вы увидите, что две клавиши сгенерированы, один является частным, а другой – открытый ключ, который отображается ниже. Скопируйте как клавиши и вставьте в Keys_dev.js или на конфигурации сервера Encireoment Envireoment.
module.exports = { //i used mlab database for fast and realiable pace development enviroment mongoURI: 'mongodb://web-push:webpush123@ds213053.mlab.com:13053/web-push', privateKey: 'ayTIBl3f0gcI-koFq-ZXPxSR4qicC0GcMNHA1dpHaj0' || process.env.VAPID_PRIVATE_KEY, publicKey: 'BK3Q7j8fcGFws03RiU5XakzDJ7KGEiRhdIX2H5U8eNmhhkdHT_j0_SD09KL96aFZOH_bsjr3uRuQPTd77SRP3DI' || process.env.VAPID_PUBLIC_KEY }
process.env.vapid_public_key или Process.env.vapid_private_key Понять в качестве конфигурации среды выполнения среды производства сервера.
Примечание: Пожалуйста, убедитесь, что вы всегда используете или генерируете свои собственные PAPID-ключевые ключи для вашего приложения для более безопасного приложения и убедитесь, что ваши закрытые ключи не выставляют в Интернете.
Итак, теперь все важные настройки структуры приложений сделают сейчас начать кодирование в server.js который существует на вершине папки проекта
const express = require('express'); const path = require('path'); const mongoose = require('mongoose'); const bodyParser = require('body-parser'); require('./model/subscribers_model'); // Load Routes const index = require('./router'); // subscriber route load push const push = require('./router/push'); // subscriber route load const subscribe = require('./router/subscribe'); // Load Keys const keys = require('./config/keys'); //Handlebars Helpers mongoose.Promise = global.Promise; // Mongoose Connect mongoose.connect(keys.mongoURI, { useMongoClient: true }) .then(() => console.log('MongoDB Connected')) .catch(err => console.log(err)); //Create Express middleware const app = express(); app.set('trust proxy', true); // parse application/json app.use(bodyParser.json()); // parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: true })); // Set static folder app.use(express.static(path.join(__dirname, 'public'))); // app.set('views', __dirname + '/public/js'); // Set global vars app.use((req, res, next) => { res.locals.user = req.user || null; next(); }); // Use Routes app.use('/', index); app.use('/subscribe', subscribe); app.use('/push', push); // catch 404 and forward to error handler app.use(function (req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function (err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function (err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); }); const port = process.env.PORT || 3000; app.listen(port, () => { console.log(`Server started on port ${port}`); });
И теперь приходите к папке Маршрутизатор Сначала начните с подписки .js, который уже создан командой. Откройте этот файл на новой вкладке, а затем вставьте этот код в свой Подписки.js файл
const express = require('express'); const router = express.Router(); const mongoose = require('mongoose'); const Subscription = mongoose.model('subscribers'); //Post route of subscribe url is as http://host:3000/subscribe router.post('/', (req, res) => { const subscriptionModel = new Subscription(req.body); subscriptionModel.save((err, subscription) => { if (err) { console.error(`Error occurred while saving subscription. Err: ${err}`); res.status(500).json({ error: 'Technical error occurred' }); } else { res.json({ data: 'Subscription saved.' }); } }); }); // fixed the error get request for this route with a meaningful callback router.get('/', (req, res) => { res.json({ data: 'Invalid Request Bad' }); }); module.exports = router;
Сохраните изменения и перейти к следующему файлу push.js и вставить этот код в уже созданный push.js Файл по командной строке
const express = require('express'); const router = express.Router(); const mongoose = require('mongoose'); const Subscription = mongoose.model('subscribers'); const q = require('q'); const webPush = require('web-push'); const keys = require('./../config/keys'); //Post route of push url is as http://host:3000/push router.post('/', (req, res) => { const payload = { title: req.body.title, message: req.body.message, url: req.body.url, ttl: req.body.ttl, icon: req.body.icon, image: req.body.image, badge: req.body.badge, tag: req.body.tag }; Subscription.find({}, (err, subscriptions) => { if (err) { console.error(`Error occurred while getting subscriptions`); res.status(500).json({ error: 'Technical error occurred' }); } else { let parallelSubscriptionCalls = subscriptions.map((subscription) => { return new Promise((resolve, reject) => { const pushSubscription = { endpoint: subscription.endpoint, keys: { p256dh: subscription.keys.p256dh, auth: subscription.keys.auth } }; const pushPayload = JSON.stringify(payload); const pushOptions = { vapidDetails: { subject: "http://example.com", privateKey: keys.privateKey, publicKey: keys.publicKey }, TTL: payload.ttl, headers: {} }; webPush.sendNotification( pushSubscription, pushPayload, pushOptions ).then((value) => { resolve({ status: true, endpoint: subscription.endpoint, data: value }); }).catch((err) => { reject({ status: false, endpoint: subscription.endpoint, data: err }); }); }); }); q.allSettled(parallelSubscriptionCalls).then((pushResults) => { console.info(pushResults); }); res.json({ data: 'Push triggered' }); } }); }); // fixed the error get request for this route with a meaningful callback router.get('/', (req, res) => { res.json({ data: 'Invalid Request Bad' }); }); module.exports = router;
Опять же убедитесь, что этот код изменяется в вашем push.js Файл с этим кодом теперь снова перейдите к index.js Файл и обновите код с этим следующим
const express = require('express'); const router = express.Router(); router.get('/', (req, res) => { res.locals.metaTags = { title: 'web-push-api', description: 'Web Push Notification Full Stack Application With Node Js Restful API', keywords: 'Web Push Notification Full Stack Application With Node Js Restful API', generator: '0.0.0.1', author: 'Saurabh Kashyap' }; res.json({ status: 'ok', message: 'Server is running' }); }); module.exports = router;
и сохранить изменения в файле Server.js с вышеуказанным кодом в server.js Команда файла и запуска Нажмите эту команду запуска
node server.js
Пожалуйста, убедитесь, что вы увидите эти сообщения после удара этой команды.
Нажмите еще раз закройте приложение после проверки приложения. Так что теперь выполняется серверный код на стороне приложения. Теперь давайте начнем с следующего шага
Шаг 4.
Создайте новую папку с публичным именем и создайте файл с этими командами, как показано ниже
mkdir public cd public touch index.html touch sw.js touch app.js
Теперь давайте подчеркиваем базовый HTML-код в index.html файл
Web-Push Application with Restful Api This is a web-push notification example
Сохраните этот код и перейдите к следующему файлу app.js Где сервисный работник браузера проверяет и зарегистрируйте рабочую услугу в браузере, а также отправлять запрос AJAX в API приложения http://Хост: 3000/Подписаться Для подписки на службу в браузере клиента.
let isSubscribed = false; let swRegistration = null; let applicationKey = "put_your_public_key_here"; // Url Encription function urlB64ToUint8Array(base64String) { const padding = '='.repeat((4 - base64String.length % 4) % 4); const base64 = (base64String + padding) .replace(/\-/g, '+') .replace(/_/g, '/'); const rawData = window.atob(base64); const outputArray = new Uint8Array(rawData.length); for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } return outputArray; } // Installing service worker if ('serviceWorker' in navigator && 'PushManager' in window) { console.log('Service Worker and Push is supported'); navigator.serviceWorker.register('sw.js') .then(function (swReg) { console.log('service worker registered'); swRegistration = swReg; swRegistration.pushManager.getSubscription() .then(function (subscription) { isSubscribed = !(subscription === null); if (isSubscribed) { console.log('User is subscribed'); } else { swRegistration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlB64ToUint8Array(applicationKey) }) .then(function (subscription) { console.log(subscription); console.log('User is subscribed'); saveSubscription(subscription); isSubscribed = true; }) .catch(function (err) { console.log('Failed to subscribe user: ', err); }) } }) }) .catch(function (error) { console.error('Service Worker Error', error); }); } else { console.warn('Push messaging is not supported'); } // Send request to database for add new subscriber function saveSubscription(subscription) { let xmlHttp = new XMLHttpRequest(); //put here API address xmlHttp.open("POST", "/subscribe"); xmlHttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); xmlHttp.onreadystatechange = function () { if (xmlHttp.readyState != 4) return; if (xmlHttp.status != 200 && xmlHttp.status != 304) { console.log('HTTP error ' + xmlHttp.status, null); } else { console.log("User subscribed to server"); } }; xmlHttp.send(JSON.stringify(subscription)); }
И теперь сохраните все файлы и начните кодирование для обслуживания, давайте начнем сейчас
let notificationUrl = ''; //notification registered feature for getting update automatically from server api self.addEventListener('push', function (event) { console.log('Push received: ', event); let _data = event.data ? JSON.parse(event.data.text()) : {}; notificationUrl = _data.url; event.waitUntil( self.registration.showNotification(_data.title, { body: _data.message, icon: _data.icon, tag: _data.tag }) ); }); //notification url redirect event click self.addEventListener('notificationclick', function (event) { event.notification.close(); event.waitUntil( clients.matchAll({ type: "window" }) .then(function (clientList) { if (clients.openWindow) { return clients.openWindow(notificationUrl); } }) ); });
NAD Сохранить все код. АГА..!! Выполнено. Так что теперь мы должны проверить, работает ли он или нет. Поэтому снова запустите команду в вашем терминале
node server.js
открыть URL: http://localhot: 3000 в вашем браузере сейчас
После нажатия Allo, вы видите сообщение, как в консоли браузера
и сохранить весь код. АГА..!! Выполнено. Так что теперь мы должны проверить, работает ли он или нет. Поэтому снова запустите команду в вашем терминале
node server.js
открыть URL: http://localhot: 3000 в вашем браузере сейчас
После нажатия позволяю увидеть сообщение в вашем браузере консоль
и открыть почтальон с для отправки Push-сообщения для подписчиков.
Нажимать пример отправки
{ "title": "StoryBook", "message": "welcome friends", "url": "https://new-storybook.herokuapp.com", "ttl": 36000, "icon": "https://cdn3.iconfinder.com/data/icons/happy-x-mas/501/santa15-128.png", "badge": "https://cdn3.iconfinder.com/data/icons/happy-x-mas/501/santa15-128.png", "data":"Hello New World", "tag": "Book Story" }
Исходный код здесь Считаю, что вы успешно сделаны!