Разъем.событие ввода-вывода повторяется бесконечно при однократном срабатывании

#javascript #html #node.js #sockets #socket.io

Вопрос:

Поэтому я пытаюсь создать простой синхронизированный видеоплеер с NodeJS и socket.io, но когда я запускаю видео при просмотре события, оно повторяется и повторяется до тех пор, пока соединение не будет удалено. Я использую ту же версию сокета.ввод-вывод на стороне сервера и клиента.

Мой клиент:

 <video id="avideo" src="" onseeked="onSeeked()" controls></video>

      <script>

      var socket = io({transports: ['websocket'], upgrade: false});
        
      function onSeeked() {
        var timestamp = document.getElementById("avideo").currentTime;
        socket.emit("seekdone", timestamp);
        console.log('client seeked')
      }
      
      socket.on('seekdone', function(timestamp) {
        console.log('server seeked')
        document.getElementById("avideo").currentTime = timestamp;
      }); 
      
      </script>
 

На стороне сервера:

 var io = socket(listener);

io.on("connection", function(socket) {
  
  socket.on("seekdone", function(timestamp) {
    socket.broadcast.emit("seekdone", timestamp);
  });
  
});
 

Вывод, который я получаю в консоли после поиска на видео:

 client seeked
server seeked
client seeked
server seeked
client seeked
server seeked
client seeked
server seeked
client seeked
server seeked
client seeked
server seeked
client seeked
...
 

Я также попытался сделать так, чтобы список событий был виден, но результат тот же.
Я думаю, что здесь происходит то, что я ищу видео, сервер отправляет мне событие поиска в указанное время, и поэтому оно снова срабатывает.
когда я меняю его на socket.broadcast.emit на сервере, результат также остается тем же, но как только один пользователь уходит, цикл прекращается.

Комментарии:

1. currentTime поджигание seeked события. Вот где начинается цикл.

2. @CallumMorrisson Да, потому что я хочу, чтобы все другие клиенты искали время, которое я видел, поэтому их текущее время совпадает с моим, когда я ищу.

Ответ №1:

в вашем js на стороне клиента, если вы измените на:

       var socket = io({transports: ['websocket'], upgrade: false});
      var lastSeekFromServer = null; // NEW CODE
        
      function onSeeked() {
        var timestamp = document.getElementById("avideo").currentTime;
        if (timestamp !== lastSeekFromServer) { // NEW CODE
          socket.emit("seekdone", timestamp);
        } // NEW CODE
        console.log('client seeked')
      }
      
      socket.on('seekdone', function(timestamp) {
        console.log('server seeked')
        lastSeekFromServer = timestamp; // NEW CODE
        document.getElementById("avideo").currentTime = timestamp;
      }); 
 

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