Я создаю систему уведомлений для блоггера, где он получает уведомление, когда его блогпост получает комментарий от конкретного пользователя в приложении.Для создания этой системы я использую Node.js (язык приложения), Socket.io (система обмена сообщениями) и Redis (система хранения).В моей текущей настройке я могу создать уведомление и передать его клиенту для отображения, но я не уверен, что лучше всего подходят две функции уведомлений.
- Изолировать уведомления пользователю, который написалblogpost.
- Отображение нескольких уведомлений о комментариях, которые могут быть удалены пользователем, нажав и "x"
Вот мой код на стороне клиента:
При отправке формы комментария я сохраняю комментарий, идентификатор блога и идентификатор пользователя комментатора в client-notification
.
Затем клиент получает с сервера полное имя комментатора, URL-адресblog и заголовок блога
notifications.js (получение данных с сервера socket-io):
$(document).ready(function() {
console.log("notifications.js working");
var socket = io.connect('http://localhost:3000');
socket.on('notification', function (data) {
console.log(data);
var notification = data.commentor + " left you a comment on <a href='" + data.url + "'>" + data.title + "</a>";
});
});
blog-comment.js(Отправка тела комментария от клиента к сокету сервера io):
//Blog Comment - Comment Form
class CommentForm extends React.Component {
constructor(props){
super(props);
this.state = {
value: '',
flash: '',
socket: `${API_ROOT}`
};
console.log(this.state.socket);
this.postComment = this.postComment.bind(this);
this.onChange = this.onChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
//POST /app/blog/:blogId/comment
postComment(comment, blogId, csrfToken, userId) {
var body = { comment: comment, userId: userId }; //Sent to socket-io with body.blogId coming after POST response
var route = `${API_ROOT}` + '/api/blog/' + blogId + '/comment';
fetch(route,
{
method: 'POST',
body: JSON.stringify(body),
headers: {
'X-CSRF-Token': csrfToken,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => {
const socket = socketIOClient(this.state.endpoint);
body.blogId = blogId; //Set blog Id to body variable
socket.emit('client-notification', { body }); //Socket-io 'client-notification' body store
return res.json();
})
.catch(err => {
console.log(err);
this.setState({'flash': 'error'});
});
}
Вот мой код на стороне сервера:
На стороне сервераОбработка уведомлений (обратите внимание, что файл cookie сеанса пользователя содержит идентификатор пользователя, который будет соответствоватьдля идентификатора пользователя установлен объект userNotification
, так что это может быть способом фильтрации уведомлений для конкретного пользователя):
var redisAdapter = require('socket.io-redis');
var models = require('../../models/db-index');
module.exports = function(server){
var io = require("socket.io").listen(server);
io.adapter(redisAdapter({
host: process.env.REDIS_ENDPOINT || 'localhost',
port: 6379
}));
var userNotification = {};
io.sockets.on('connection', function(socket) {
socket.emit('notification', { "url": "localhost:3000/app/blog/" + userNotification.blogId, "title": userNotification.title, "commentor": userNotification.fullName });
//Client Notification
socket.on('client-notification', function(data) {
var blogId = data.body.blogId
var commentorId = data.body.userId;
var comment = data.body.comment;
var blog;
//Find Blog where comment occurred
models.blog.find({
where: {
blogId: blogId
},
attributes: ['title', 'userId']
}).then(function(_blog){
blog = _blog;
//Set Blog ID, Blog User ID and Blog Title
userNotification.blogId = data.body.blogId;
userNotification.userId = blog.userId;
userNotification.title = blog.title;
//Find Comment on Blog
models.blogComment.find({
where: {
blogId: blogId,
userId: commentorId,
comment: comment
},
include: [{
model: models.SynotateUser,
attributes: ['firstName', 'lastName']
}]
}).then(function(comment){
//Set Blog Comment User Full Name
var fullName = comment.synotate_user.firstName + " " + comment.synotate_user.lastName;
userNotification.fullName = fullName;
});
});
});
});
return io;
};