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');
  });
});

В приведенном выше примере я прослушиваю новые соединения и проверяю их подписку на соответствующие комнаты. Я использую сервисы для того, чтобы - они независимы, как я уже сказал, как должен выглядеть весь ваш код.