@ski28

Как правильно отправить ответ на socket.io в ответ на запрос пользователя?

Добрый день. Гуглил ответа не нашёл. Точнее нашёл что такая структура не правильная. Поэтому хочу узнать у специалистов как правильно организовать то что я хочу.

Система : nodejs , expressjs , socket.io , ejs , mysql , apache2
Задача. Нужно выдать рандомный приз пользователю.
Как это решено сейчас : через ajax.
Проблема . Сайт начинает тормозить при 250-300 онлайн пользователей одновременно. Некоторые страницы отрендеренные я храню в переменной но и это не сильно помогло. Раньше тормозил при 150 онлайн. Также кэш отдаёт cloudflare что тоже сильно спасает.

Как я хочу разгрузить сайт.
Бонус вынести в js и подключаться им уже к главному socket
Как у меня получилось это сделать.

У пользователя
//Запрос на получение
socket.emit('bunus' , 'start');
//Ждём результат
socket.on( 'result' , (data) => {
       console.log(data);
});

На сервере

//Запрос пользователя
socket.on('bunus', function ( data ) {
	let r = {};
	     r.data = data;  
             //socket.id для ответа именно этому пользователю
	     r.user = socket.id;
             //id пользователя для проверки авторизован или нет
	     r.user_id = socket.handshake.session.userId; 
	io.emit( 'new_bunus' , r );
});
// Ответ от бонус js
socket.on('new_result', function ( data ) {
	io.to(data.user).emit( 'result', data); 
});


Бонус js

const socket = io.connect(config.connection_type + '://localhost:' + config.PORT , {
    secure: true,
    reconnect: true,
    rejectUnauthorized: false
});
socket.on('connect', function() {
	console.log('connect Успешно подключились к SocketIO! bonus.js : '+process.pid);
});
//Ждём запрос на выдачу бонуса
socket.on('new_bunus' , function ( data ) {
    data.bonus = "рандомный бонус";
    socket.emit('new_result', data );
});


Вот так работает. Но по мне это громадная конструкция. В socket.io есть callback и хотелось бы написать через него.

У пользователя
//Запрос на получение
socket.emit('bunus' , 'start'  , (data)=>{
    console.log(data);
});

На сервере

//Запрос пользователя
socket.on('bunus', function ( data , cb) {
	let r = {};
	     r.data = data;  
             //id пользователя для проверки авторизован или нет
	     r.user_id = socket.handshake.session.userId; 
	io.emit( 'new_bunus' , r  ,  (result)=>{
              cb(result);
        });
});


Бонус js

const socket = io.connect(config.connection_type + '://localhost:' + config.PORT , {
    secure: true,
    reconnect: true,
    rejectUnauthorized: false
});
socket.on('connect', function() {
	console.log('connect Успешно подключились к SocketIO! bonus.js : '+process.pid);
});
//Ждём запрос на выдачу бонуса
socket.on('new_bunus' , function ( data , cb) {
    data.bonus = "рандомный бонус";
    cb(data);
});


Вроде всё логично. Но получаю ошибку "Callbacks are not supported when broadcasting" (( .Подскажите как правильно написать , что бы было без лишнего.
  • Вопрос задан
  • 348 просмотров
Пригласить эксперта
Ответы на вопрос 1
@vshvydky
Socket.io из коробки дает возможность использовать room.
Флоу использования румов:
1. Клиент коннектится к сокету, проверяется токен пользователя, из него получается id пользователя.
2. Текущий сокет джойнится комнату с идентификатором пользователя (читай доку про join).
3. Сообщения пользователю отправляются как to(roomName).emit...
Какой профит имеем?
1. Не важно сколько страниц открыто у пользователя, не надо руками мапать какой сокет к какому юзеру и сколько сокетов открыто у одного пользователя.
2. Маршрутизация сообщений уходит на уровень кода библиотеки.
3. Другим пользователям не поступают сообщения , которые адресованы конкретному пользователю.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы