【问题标题】:Socket.io how to check if user is typing and broadcast it to other usersSocket.io 如何检查用户是否正在输入并将其广播给其他用户
【发布时间】:2013-05-21 21:58:17
【问题描述】:

我正在尝试设置 socket.io 聊天服务器。我已经准备好从服务器和客户端发送和接收消息。如果有人正在打字,我有兴趣向用户展示。我知道当有些人从客户端输入到服务器时我可以发出,我也可以将它广播给其他用户。但是在每个键位上都这样做会有效吗?我该如何处理这种情况?下面是我现在的代码:

$("#textbox").keyup(function (e)  {
 if (e.keyCode == 13)  {
  socket.emit('send', {nickname: $('#nickname').val() , msg: $("#textbox").val()});
      $('#textbox').val('');  }
 else{
  socket.emit('is typing',  {nickname: $('#nickname').val()});
     }
});

在服务器端:

socket.on('is typing', function(data){
 socket.broadcast.emit('typing', {nickname: data.nickname});
});

【问题讨论】:

    标签: node.js socket.io


    【解决方案1】:

    您可以使用超时来发送“开始输入”和“停止输入”消息,如下所示:

    var typing = false;
    var timeout = undefined;
    
    function timeoutFunction(){
      typing = false;
      socket.emit(noLongerTypingMessage);
    }
    
    function onKeyDownNotEnter(){
      if(typing == false) {
        typing = true
        socket.emit(typingMessage);
        timeout = setTimeout(timeoutFunction, 5000);
      } else {
        clearTimeout(timeout);
        timeout = setTimeout(timeoutFunction, 5000);
      }
    
    }
    

    这很粗略,但你应该明白。

    【讨论】:

    • 我应该在哪里打电话onKeyDownNotEnter??
    【解决方案2】:

    只是想我会在 abject_error 给出的非常有用的答案上添加我的变体。这允许输入状态以及停止输入但输入了消息。我没有使用 socket.io,但你明白了。

    var typingStatus=0; //0=Not typing: message blank, 1=typing, 2=typing: something there
    var typingStatus_timeout = undefined;
    
    //called when timeout kicks in that we've stopped typing
    function function_typingStatus_timeout(){
        //message entered
        if ($('#chat_message').val().trim()) {
            typingStatus=2;
        //message is blank
        } else {
            typingStatus=0;
        }
        //send new status
        connection.send(JSON.stringify({
            action:'typingStatus',
            typingStatus:typingStatus,
        }));
    }
    
    $(document).ready(function(){
        //TYPING
        $('#chat_message').keydown(function(e) {
            //only record typing if enter not pressed
            if(e.which!=13 && e.keyCode!=13) {
                //weren't typing before but are now
                if (typingStatus!=1) {
                    //switch to 1 for in progress
                    typingStatus=1;
                    //broadcast
                    connection.send(JSON.stringify({
                        action:'typingStatus',
                        typingStatus:typingStatus,
                    }));        
                //were typing before and still are, clear the timeout, we're going to reset it in the next step
                } else {
                    clearTimeout(typingStatus_timeout);
                }
                //either way, set the timeout to trigger after a second of not typing
                typingStatus_timeout=setTimeout(function_typingStatus_timeout,1000);
    
            //if enter was pressed we want to not have it register as a keydown at all.  there's a separate function on keyup that looks for enter being pressed and sends the message
            } else {
                e.preventDefault();
            }
        });
    });
    

    【讨论】:

      【解决方案3】:

      按照本教程在此处添加我的代码:https://www.youtube.com/watch?v=FvArk8-qgCk&index=5&list=PL4cUxeGkcC9i4V-_ZVwLmOusj8YAUhj_9

      // Make connection
      var socket = io.connect('http://localhost:4000');
      var timeout
      // Query DOM
      var message = document.getElementById('message'),
            handle = document.getElementById('handle'),
            btn = document.getElementById('send'),
            output = document.getElementById('output'),
            feedback = document.getElementById('feedback');
      
      // Emit events
      btn.addEventListener('click', function(){
          socket.emit('chat', {
              message: message.value,
              handle: handle.value
          });
          message.value = "";
      });
      
      function timeoutFunction() {
        socket.emit("typing", false);
      }
      
      message.addEventListener('keyup',function(){
       socket.emit('typing', handle.value);
       clearTimeout(timeout)
       timeout = setTimeout(timeoutFunction, 2000)
      })
      
      
      // Listen for events
      socket.on('chat', function(data){
          feedback.innerHTML = '';
          output.innerHTML += '<p><strong>' + data.handle + ': </strong>' + data.message + '</p>';
      });
      
      socket.on('typing', function(data){
          if (data) {
            feedback.innerHTML = '<p><em>' + data + ' is typing...</em></p>';
          } else {
            feedback.innerHTML = ''
          }
      });
      

      注意它不需要输入布尔变量

      【讨论】:

        【解决方案4】:
           function typingtimeoutFunction (){                 
        
              socket.emit('typingMessage', 'stopped typing');    
            },
        
            onKeyDownNotEnter: function (){
                 clearTimeout(this.typingtimeout);
                 socket.emit('typingMessage', 'istyping');
                this.typingtimeout = setTimeout(function() {ajaxChat.typingtimeoutFunction();}, 5000);      
            },
        

        【讨论】:

          【解决方案5】:

          虽然这已经回答并且有点陈旧,但您可能会考虑使用 debounce 函数(例如来自 lodash)的用户输入来延迟调用函数:

          _.debounce

          【讨论】:

            猜你喜欢
            • 2018-09-01
            • 1970-01-01
            • 2012-02-18
            • 1970-01-01
            • 2015-10-13
            • 2021-11-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多