Форум программистов, компьютерный форум, киберфорум
Наши страницы
JavaScript: Node.js
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
badwolf770
0 / 0 / 0
Регистрация: 22.06.2017
Сообщений: 2
#1

Дублируются сообщения при отправке конкретному пользователю через socket.io

22.06.2017, 13:31. Просмотров 507. Ответов 2
Метки нет (Все метки)

Всем добрый день!
Такая проблема. Делаю простой чат, в котором можно отправлять сообщения конкретным пользователям. Есть клиенты и есть операторы.Но есть проблема, если подключены несколько клиентских сокетов и мы отправляем сообщение на один из них, то сообщение дублируется у клиента, которому отправляем его. Допустим, если подключены два клиентских сокета,то у получателя сообщение дублируется 2 раза. Если 3 сокета, то 3 раза. А если подключен только один клиент, то у него сообщение не дублируется. Сообщения конкретному клиенту пробовал отправлять через socket.to(socketID)... и через socket.broadcast.to(socketID)...... Подскажите, пожалуйста.

Код сервера:

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('redis');
 
server.listen(8890);
 
io.on('connection', function (socket) {
 
console.log("new client connected");
 
var redisClient = redis.createClient();
 
redisClient.subscribe('notification');
 
 
redisClient.on("message", function (channel, message) {
    console.log("New message: " + message + ". In channel: " + channel);
    var json = JSON.parse(message);
    if (json.clientId != '' && json.operatorId == '') {
        socket.emit('newClient', message);
        socket.to(json.clientId).emit('notification', message);
        console.log(1);
    } else if (json.clientId != '' && json.operatorId != '') {
        socket.broadcast.to(json.clientId).emit('notification', message);
        socket.broadcast.to(json.operatorId).emit('notification', message);
        console.log(2);
    } else {
        console.log('не вышло');
    }
});
 
socket.on('disconnect', function () {
    redisClient.quit();
});
 
});
Код клиента:
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
jQuery(function ($) {
    $(document).ready(function () {
 
        var
                socket = io.connect('http://localhost:8890'),
                socketId;
 
        socket.on('connect', function () {
            socketId = socket.id;
            $('#chat-form input[name=client-id]').val(socketId);
        });
 
        socket.on('notification', function (data) {
 
            var message = JSON.parse(data);
 
            if (message.operatorId) {
                $('#chat-form input[name=operator-id]').val(message.operatorId);
            }
            $("#notifications").prepend("<p><strong>" + message.name + "</strong>: " + message.message + "</p>");
 
        });
 
    });
});
Код оператора:

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
jQuery(function ($) {
    $(document).ready(function () {
 
        var socket = io.connect('http://localhost:8890');
 
        socket.on('connect', function () {
            socketId = socket.id;
            $('#chat-form input[name=operator-id]').val(socketId);
 
        });
 
        socket.on('notification', function (data) {
 
            var message = JSON.parse(data);
 
            $("#notifications").prepend("<p><strong>" + message.name + "</strong>: " + message.message + "</p>");
 
        });
 
        socket.on('newClient', function (data) {
            var message = JSON.parse(data);
            alert(message.clientId + ' присоединился!');
            if (message.clientId) {
                $('#chat-form input[name=client-id]').val(message.clientId);
            }
 
        });
 
    });
});
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.06.2017, 13:31
Ответы с готовыми решениями:

Socket.io сообщения
В общем недавно набрел вот на такую статью, про то как организовать личные...

Node.js и socket.io сообщения между пользователями
Всем привет,не так давно наткнулся на статью,поставил ноду,установил всё,что...

Ошибка: Socket WouldBlock, при отправке сообщения от сервера к клиенту
Привет, есть некий сервер, раньше работало все четко, а после последних...

При отправке AJAX дублируются запросы
Имеется такой вот скрипт. $('.container').on('click', '', function (){ ...

Ошибка IP при отправке socket
Прошу прощенья если такое были, просто не знаю даже как гуглить (а похожих тем...

2
muxahuk1214
Coding is art
201 / 199 / 67
Регистрация: 04.09.2013
Сообщений: 610
22.06.2017, 23:02 #2
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var redisClient = redis.createClient();
 
redisClient.subscribe('notification');
 
 
redisClient.on("message", function (channel, message) {
    console.log("New message: " + message + ". In channel: " + channel);
    var json = JSON.parse(message);
    if (json.clientId != '' && json.operatorId == '') {
        socket.emit('newClient', message);
        socket.to(json.clientId).emit('notification', message);
        console.log(1);
    } else if (json.clientId != '' && json.operatorId != '') {
        socket.broadcast.to(json.clientId).emit('notification', message);
        socket.broadcast.to(json.operatorId).emit('notification', message);
        console.log(2);
    } else {
        console.log('не вышло');
    }
});
Вам вот эту часть кода нужно вынести из .on('connection', ... ) функции..

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

это как в хендлере клика вешать слушатель на передвежение мыши..
каждый раз как вы будете кликать будет ещё 1-н слушатель передвежения мыши..
0
badwolf770
0 / 0 / 0
Регистрация: 22.06.2017
Сообщений: 2
26.07.2017, 11:36  [ТС] #3
Цитата Сообщение от muxahuk1214 Посмотреть сообщение
Вам вот эту часть кода нужно вынести из .on('connection', ... ) функции..
Получается, что каждый раз когда кто-то заходит на сокет вы создаёте новое редис подключение и вешаете событие на отлов сообщений редиса.
это как в хендлере клика вешать слушатель на передвежение мыши..
каждый раз как вы будете кликать будет ещё 1-н слушатель передвежения мыши..
А подскажите тогда, пожалуйста, как быть, чтобы nodejs сервер создавал только одну подписку на редис при старте и всегда ее слушал, или это невозможно? Я наверно не понимаю как устроена работа nodejs. Сервер вешает обработчики событий, только когда на него подключаются клиенты или просто при старте сервера он устанавливает обработчики событий сам? Спасибо
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.07.2017, 11:36

Как создать програмно автозагрузку конкретному пользователю через реестр?
У меня на компьютере созданы пользователи для детей. Я хочу добавить свою...

Исключение при отправке сообщения
При отправке сообщения появляется исключение: Client does not have permissions...

Ошибка при отправке сообщения
Доброго времени суток. При отправке сообщения возникает ошибка: Порт 25,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru