Socket.io Лучшая практика кодирования
Я разрабатываю приложение Node.js, которое использует Socket.io для обработки связи в реальном времени. Мой код полон функций On и Emit. Я также использую функцию комнаты. мое приложение выглядит так:
var server = require('http').Server();
var io = require('socket.io')(server);
io.on('connection', function(socket){
socket.on('event1', function(data){"lots of socket and non-socket codes" });
socket.on('event2', function(data){"lots of socket and non-socket codes" });
socket.on('event3', function(data){"lots of socket and non-socket codes" });
socket.on('disconnect', function(){"Some other code"});
});
server.listen(portNum);
он отлично работает, но это не мое идеальное решение.
Во-первых, в этом подходе все находится в одном большом файле вместо меньшего файла с изолированной функциональностью.
во-вторых, довольно сложно отлаживать и поддерживать это приложение, поскольку оно довольно беспорядочно, когда дело доходит до 1000+ строк кода.
Вот мой вопрос:
Существует ли предпочтительная/лучшая практика разработки корпоративных приложений Socke.io?
Если да, существует ли большое приложение Socket.io с открытым исходным кодом, которое демонстрирует этот подход или любую статью, которая поможет мне реорганизовать мой код в лучшую сторону?
Ответы
Ответ 1
Я думаю, начиная с размещения каждой функции обратного вызова в другой функции, которую вы выкладываете из io.on('connection'), и, возможно, также помещаете их в другой файл (используя module.exports), вы начнете с более четкое применение.
Хорошо, поэтому я напишу вам одну возможность, которую я использую, я не знаю, является ли она лучшим образцом юниверса для socket.io, но это хорошо, я думаю.
В вашем основном файле (файл с io.onconnection) вы можете иметь что-то вроде этого (вам не нужно использовать пространство имен, это просто пример):
var SocketEvent = require('./socketEvent');
io.of('/user').on('connection', function (socket) {
SocketEvent.load_common_event(socket);
SocketEvent.load_user_event(socket);
});
io.of('/operator').on('connection', function (socket) {
SocketEvent.load_common_event(socket);
SocketEvent.load_operator_event(socket);
});
И в загружаемом вами socketEvent.js вы можете получить следующее:
exports.load_common_event = function(socket){
socket.on('disconnect', function(){"Some other code"});
};
exports.load_user_event = function(socket){
socket.on('event1', function(data){"lots of socket and non-socket codes" });
socket.on('event2', function(data){"lots of socket and non-socket codes" });
socket.on('event3', function(data){"lots of socket and non-socket codes" });
};
exports.load_operator_event = function(socket){
socket.on('event4', function(data){"lots of socket and non-socket codes" });
socket.on('event5', function(data){"lots of socket and non-socket codes" });
socket.on('event6', function(data){"lots of socket and non-socket codes" });
};
Сообщите мне, если у вас есть вопрос
Дополнительные
Если вы хотите что-то вроде Socket.on('event', myModule.doSomething),
вы можете сделать это, я думаю, в модуле:
клиент:
var myModule = require('./socketModule');
io.on('connection', function (socket) {
socket.on('event' , myModule.doSomething(/*some parameters (socket)*/));
});
server socketModule.js:
exports.doSomething = function(/*some parameters (socket)*/){
/* Some processing around */
};
Ответ 2
Для тех, кто интересуется паролем, .bind
может быть вариантом
const events = require('./events.js')
io.of('/chat').on('connection', (socket) => {
socket.on('print', events.print.bind({socket, io}))
})
event.js
const util = require('util')
function print(data) {
console.log(util.inspect(this.socket).substr(0, 100))
console.log(util.inspect(this.io).substr(0, 100))
}
module.exports = {
print
}
Ответ 3
Больше использования страниц, меньше кода на каждой, делитесь ими независимо при необходимости: Примечание. Я полагаю, вы работаете с Express. Если нет, просто удалите экспресс из моих демонстраций.
// app.js
var app = require('express')();
module.exports = app;
// server.js
var app = require('./app');
var server = require('http').createServer(app);
module.exports = server;
//socket-io-redis.js
var server = require('../server');
var io = require('socket.io')(server);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
io.set('origins', '*:*');
module.exports = io;
Теперь на каждой странице вашего API или на вашем сервере вы можете просто импортировать экземпляр Io (справочный и эффективный) следующим образом:
var Io = require('../path/to/io-config-file');
console.log(Io); // object
Io.to(room).emit(event, payroll);
Вы также можете создать основной файл подключения следующим образом: Примечание. Я вставляю здесь точный код, который я на самом деле использую, просто для того, чтобы показать вам некоторые из моих лучших практик (конечно, адаптируйте и настройте его в соответствии с вашими потребностями):
var { Io } = require('@dependencies/_index');
var Defaults = require('@helpers/defaults');
var _index = require('./services/_index');
const {
validate,
get_user,
subscribe
} = _index;
Io.on("connection", socket => {
socket.on("join", async info => {
await validate(info);
await subscribe(await get_user(info), info, socket, 'join');
});
socket.on("leave", async info => {
await validate(info);
await subscribe(await get_user(info), info, socket, 'leave');
});
});
В приведенном выше примере я прослушиваю новые соединения и проверяю их подписку на соответствующие комнаты. Я использую сервисы для того, чтобы - они независимы, как я уже сказал, как должен выглядеть весь ваш код.