Создание адекватной архитектуры Express + Socket.io приложения
Создаю небольшое MVC приложение на express + socket.io и совершенно не понимаю как адекватно написать архитектуру приложения вместе с сокетами.
Например, есть человек который заходит на сайт. В моем приложении это выглядит так:
app.js:
/* Здесь у меня подключение всех модулей включая socket.io создание сервера и РОУТЕРА */
const webRouter = require('./routes/web')
app.set('/', webRouter);
routes/web.js:
/* Здесь маршруты и вызов контроллеров, очевидно */
app.get('/', PageController.renderIndex)
Задача:
При подключении юзера вывести сообщение в консоль console.log(${username} connected)
Без сокетов я просто вывожу в PageController.renderIndex:
const renderIndex = (req, res) => {
console.log(${req.user.login} connected)
}
Вот собственно вопрос:
Документация socket.io предлагает мне писать всё в app.js, но в таком случае я не смогу передать данные юзера который зашел на сайт в socket.io как в случае с renderIndex, но я хочу сохранить читабельность кода и не превращать все это в спагетти.
Как правильно это сделать?
Неужели нужно отдельно писать какой-нить модуль для управления событиями и забыть про роутер?
Т.е в таком случае даже если юзер захочет добавить какой-нибудь пост на сайте он отправляет не post запрос на сервер а активирует событие которое обработает и добавит пост в базу?
Не нашел в интернете примеров использования сокетов в проектах больше чем чат.
Ответы (1 шт):
В общем, раз ответа нет – пришлось решать задачу самому. Не знаю на счет правильности решения, но выбора нет.
Решил создать отдельный сокет-модуль для каждого модуля проекта и в контроллерах использовать встроенный events в Node.js.
В контроллере вызываю внутренний events в нужном месте и при срабатывании события вызываю сокет-событие.
Пример:
Создал отдельную папку где создал для каждого модуля Events.js -
services/userEvents.js:
const Events = require('events')
class UserEvents extends Events {}
module.exports = new UserEvents()
Далее определил список внутренних событий проекта в которых уже создаю сокет-сервер и передаю данные в Socket.io -
events/user.js:
/* Создание сокет-соединения и подключение файлов и */
userEmitter.on('newEvent', data => {
socketServer.emit('newEvent', data)
})
В контроллере просто вызываю внутренние события -
controllers/userController.js:
/* Так же подключение файлов и тд. В нужном методе использую нужное событие */
const f = async (req, res) => {
console.log('test');
userEvent.emit('newEvent', req.user)
}
Ну а на клиенте уже сами все знаете, если юзаете сокеты