Как организовать приложение на socket.io, node.js
Я собираюсь написать приложение на node.js с использованием socket.io. Все примеры что я видел в интернете достаточно простые, в них все вмещается в один файлик и приложение не имеет никакой структуры. Я же хочу написать более сложное приложение более правильно и у меня с этим возникли проблемы.
Я нашел на гитхабе один вариант как можно вынести всю логику, связанную с сокетами в отдельный файл.
В файле app.js создается веб сервер. Затем следующая строчка кода:
io.sockets.on('connection', Mysocket);
Mysocket это самодельный модуль, который подключен выше. В нем написан следующий код:
module.exports = function (socket) {
socket.on('test', (data) => {
io.to(socket.id).emit('test_1');
});
}
В этом подходе работает все кроме отправки сообщения клиенту. В файле Mysocket появляется ошибка о том, что io не определено. Если заменить io на socket (в целом я не понимаю в чем разница) ошибка не появляется, но сообщение не отправляется.
Были еще мысли создать отдельный модуль с созданием сервера, инициализацией socket.io и подключать его и к app.js и к Mysocket.js, но сомневаюсь что это адекватное решение, я такого нигде не видел.
В целом вопрос: как правильно организовать приложение с использованием socket.io достаточно крупное для того, чтоб держать все в одном файле.
Ответы (1 шт):
Написать отдельный модуль для создания объекта socket.io как раз очень адекватное решение. В нем можно описать подключение, добавление слушателей на базовые (системные) ивенты, реализовать механизм аутентификации и базовой обработки ошибок, добавить возможность подключаться по HTTPS и т.д.
Слушатели кастомных ивентов (Ваших, которые реализуют бизнес логику) можно сгрупировать по контроллерам в виде отдельных методов. Связать их все можно в отдельном модуле / классе - роутере. А вот уже в главном файле вызвать создание инстанса сокета, регистрацию всех роутов, модулю подключения к бд и т.д.
По поводу примера и объектов io и socket. Разница между ними в том, что в переменную io обычно назначают инстанс socket.io, а socket - объект конкретного подключения. Думаю, с примером будет нагляднее
io.on('connect', socket => {
socket.on('hi', data =>
console.log(data);
// Отправка сообщения конкретному сокету внутри колбека полдключения
socket.emit('hi-reply', {message: 'hi'});
);
});
Если же Вам необходимо отправить сообщение конкретному сокету вне колбека подключения, Вам необходимо отправить сообщение в комнату. Сделать это через глобальный объект io:
io.to(socket.id).emit('test_1');
В Вашем примере кода, это будет равносильно socket.emit('test_1'), так как вызов идет внутри колбека подключения.
https://socket.io/docs/server-api/ - в официальной документации для понимания того, что было названо в примере io, почитайте разделы server и namespace. Для socket - соответственно, socket