Создание адекватной архитектуры 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 шт):

Автор решения: Senbonzakuraa

В общем, раз ответа нет – пришлось решать задачу самому. Не знаю на счет правильности решения, но выбора нет.

Решил создать отдельный сокет-модуль для каждого модуля проекта и в контроллерах использовать встроенный 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)
}

Ну а на клиенте уже сами все знаете, если юзаете сокеты

→ Ссылка