Прослушиватель событий Socket.io вызывается несколько раз, хотя он отправляется только один раз с моего js-сервера узла - PullRequest
0 голосов
/ 02 октября 2018

Итак, у меня в клиенте AngularJS 1.x есть пользовательский прослушиватель событий сокета, называемый newMessage.

Теперь, чтобы помочь мне лучше задать вопрос, подумайте о сессиях, как о чате, который мы провели в комнате и собираемсяиз комнаты будет конец сеанса.

Теперь, хотя мой сервер генерирует событие «newMessage» только один раз, мой клиентский прослушиватель запускается несколько раз, и количество равно количеству сеансов, которые мыранее.

Таким образом, для более ясного объяснения, на первом сеансе он работает как ожидалось ... только одно сообщение на чат.

Но при присоединении к чату во второй раз слушательвыстрелил дважды.Когда запускается третий сеанс, вы догадались об этом 3 раза.

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

Может кто-нибудь, пожалуйста, помогите мне, как не продолжать добавлять прослушиватель newMesaage, если он уже находится вместо.Я попытался socket.hasListener и добавил, если он не существует, но он все еще не работает

Вот фрагменты из моего кода: Angualar клиент:

socket.on('newMessage', function (message) {
console.log(message);
var html = `<p>${message.from} : ${message.text}</p>`;
$('.chat-box').append(html);
$scope.scrollToBottom();
});

Узел сервер:

io.in(room).emit('newMessage', generateMessage('Admin:', `Welcome`));

также другой источник этого события в коде моего сервера

io.in(room).emit('newMessage', generateMessage(user.username, message.text));

generateMessage () - это файл util js на моем сервере, и у него нет проблем.

Так что на каждомВ socket.on (newMessage) происходит нечто особенное.он вызывается несколько раз, хотя на сервере он излучает только один раз.И еще одна интересная вещь: это повторяется количество раз, когда мы входили в сокетное соединение без разъединения.

Также при разъединении (как перезагрузка вместо маршрутизации в моем углу) сеанс начинается с # 1 всеснова.но по мере того, как происходит больше сеансов, наблюдается поведение, о котором я упоминал.

Я нахожу это очень странным ... Кто-то, пожалуйста, помогите мне, и это будет действительно оценено.Спасибо!

Редактировать: Добавление дополнительного кода

Это мой код сокета в app.js на сервере.Дали два метода, которые испускают это событие.Другие методы, которые я сократил, обнаружив, что это не имеет ничего общего с этой ошибкой события.

io.on('connection', socket => {
  var currentRoomId;
  socket.on('disconnect', () => {
    io.in(currentRoomId).emit('endgameclient');
    onlineRooms.forEach((room, i) => {
      if (room === currentRoomId) {
        onlineRooms.splice(i, 1);
      }
    });
  });
  socket.on('startgame', (secret, callback) => {
    var room = secret.toString();
    var curplayers = players.getPlayerList(room);
    io.in(room).emit('startgameclient', players.getPlayerList(room));
    if (curplayers) {
      io.in(room).emit('newMessage', generateMessage('Admin:', `Game on ${curplayers[0].username} & ${curplayers[1].username}`));
    }
    callback();
  });
  socket.on('createNewMessage', (message, callback) => {
    var room = message.secret.toString();
    var player = players.getPlayer(socket.id);
    io.in(room).emit('newMessage', generateMessage(player.username, message.text));
    callback(null, true);
  });
  socket.on('playerjoin', (joinUser, callback) => {
    ....
  });
  socket.on('getplayers', (secret, callback) => {
    ...
  });
  socket.on('checkplayercount', (secret, callback) => {
    ...
  });
  socket.on('getrooms', (none, callback) => {
    ....
  });
  socket.on('playerleft', (secret) => {
    ....
  });

});

И это мой угловой клиентский код, в котором я дал два метода, которые обрабатывают сообщения.

app.controller('TictactoeCtrl', ['$scope', '$transitions', '$http', '$state', '$stateParams', 'authFactory', 'playersService', 'socket', function ($scope, $transitions, $http, $state, $stateParams, authFactory, playersService, socket) {

  socket.on('disconnect', function () {

  });

  socket.on('newMessage', function (message) {
    console.log(message);
    var html = `<p>${message.from} : ${message.text}</p>`;
    $('.chat-box').append(html);
    $scope.scrollToBottom();
  });

  $scope.sendNewMessage = function (e) {
    socket.emit('createNewMessage', { text: $("#message-input").val(), secret: $scope.secret }, function () {
      $("#message-input").val('').blur();
    });
  };

  socket.on('updateplayers', function (players) {
    ....
  });

  socket.on('canstartgame', function (players) {
    ....
  });

  socket.on('startgameclient', function (players) {
    ....
  });

  socket.on('endgameclient', function () {
    ....
  });

  $scope.startGame = function () {
    ...
  };

  $scope.goHome = function () {
    ...
  };
  $scope.logOut = function () {
    ....
  };

  $scope.scrollToBottom = function () {
    ....
  }
}]);

Надеюсь, это описывает мой код более подробно.

1 Ответ

0 голосов
/ 03 октября 2018

Таким образом, я создавал новые экземпляры обработчиков событий сокетов каждый раз, когда заходил в этот угловой контроллер через представление.Поэтому, хотя он не был внутри обработчика событий, он все еще дублировался каждый раз, когда я приходил к этому конкретному контроллеру, и, следовательно, код вел себя так.Поэтому, чтобы решить эту проблему, я просто отключил все прослушиватели событий, когда оставил свое представление с помощью $ transition.И вуаля, это работает!

Кстати, я использовал функцию off ().

if ($transition.$from().name === 'tictactoe') {
    socket.off()

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...