In general, such problems, it was necessary to realize that when typing a message, the interlocutor was sent a notification that you were typing the message, but I get that when I’m showing that I’m typing only me, but the interlocutor doesn’t, as I understand it does not send, send? and how best to "keydown" - "keyup" or "keypress"?

var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); app.get('/', function(req, res) { res.sendfile('index.html'); }); // socket.on - приём сообщения // io.emit - отправка сообщения io.on('connection', function(socket) { socket.on('chat message', function(msg, name, dodo) { io.emit('chat message', msg, name, dodo); }); }); http.listen(3000, function() { console.log('listening on *:3000'); }); 
 <!doctype html> <html> <head> <title>Socket.IO chat</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font: 13px Helvetica, Arial; } form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; } form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; } form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; } form button { width: 20%; background: rgb(130, 224, 255); border: none; padding: 10px; } #messages { list-style-type: none; margin: 0; padding: 0; } #messages li { padding: 5px 10px; } #messages li:nth-child(odd) { background: #eee; } </style> </head> <body> <span id="dodo"></span> <ul id="messages"></ul> <form action=""> <input type="text" id="user" placeholder="Who are you?"> <input type="text" id="message" placeholder="What do you want to say?"> <button type="submit">Send</button> </form> <script src="/socket.io/socket.io.js"></script> <script src="http://code.jquery.com/jquery-1.11.1.js"></script> <script> $(function() { var socket = io(); var $messages = $('#messages'); var $message = $('#message'); var $user = $('#user'); var dodo = $('#dodo'); $('form').submit(function() { // Отправка сообщения socket.emit('chat message', $message.val(), $user.val(), dodo.val()); // Очищаем текстовое окно сообщения $message.val(''); return false; }); // Приём сообщения с сервера socket.on('chat message', function(msg, name, dodo) { $messages.append($('<li>').text(dodo + name + ':' + msg)); $messages.append($('#dodo').text(dodo)); }); $($message).keydown(function() { $("#dodo").empty(); var mes = $("<b>пользователь печатает сообщение...</b>"); $("#dodo").last().append(mes); }); $($message).keyup(function() { $("#dodo").empty(); var mes = $("<b></b>"); $("#dodo").last().append(mes); }); }); </script> </body> </html> 

    3 answers 3

    You need, as well as for messages, to send and process notifications that the user prints through soket.io.

    In the server code, you need to add handling of this type of notification:

     var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); app.get('/', function(req, res) { res.sendfile('index.html'); }); // socket.on - приём сообщения // io.emit - отправка сообщения io.on('connection', function(socket) { socket.on('chat message', function(msg, name, dodo) { io.emit('chat message', msg, name, dodo); }); socket.on('typing', function(name) { io.emit('typing', name); }) }); http.listen(3000, function() { console.log('listening on *:3000'); }); 

    On the client, you need to send and process notifications:

     <!doctype html> <html> <head> <title>Socket.IO chat</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font: 13px Helvetica, Arial; } form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; } form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; } form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; } form button { width: 20%; background: rgb(130, 224, 255); border: none; padding: 10px; } #messages { list-style-type: none; margin: 0; padding: 0; } #messages li { padding: 5px 10px; } #messages li:nth-child(odd) { background: #eee; } </style> </head> <body> <span id="dodo"></span> <ul id="messages"></ul> <form action=""> <input type="text" id="user" placeholder="Who are you?"> <input type="text" id="message" placeholder="What do you want to say?"> <button type="submit">Send</button> </form> <script src="/socket.io/socket.io.js"></script> <script src="http://code.jquery.com/jquery-1.11.1.js"></script> <script> $(function() { var socket = io(); var $messages = $('#messages'); var $message = $('#message'); var $user = $('#user'); var dodo = $('#dodo'); $('form').submit(function() { // Отправка сообщения socket.emit('chat message', $message.val(), $user.val(), dodo.val()); // Очищаем текстовое окно сообщения $message.val(''); return false; }); // Приём сообщения с сервера socket.on('chat message', function(msg, name, dodo) { $messages.append($('<li>').text(dodo + name + ':' + msg)); $messages.append($('#dodo').text(dodo)); }); $($message).on('keydown keyup', function() { socket.emit('typing', $user.val()); }); socket.on('typing', function(name) { if (name != $user.val()) { $("#dodo").empty(); var msg = $('<b>' + name + ' печатает сообщение...</b>'); $("#dodo").last().append(msg); msg.fadeOut(3000, function() {$(this).remove()}); } }) }); </script> </body> </html> 
    • as @FFFFFF wrote, you need to add a delay in order not to burden the server once again.
    • Thank you so much) I understood what was wrong) - Sergey74rus
    1. To check for sure, open this page from another device (for example from a tablet)
    2. I would do a keyup, and it’s more correct to make a limit on the print speed. For example, I type very quickly and in a minute I can print about 400 characters - if I send every time, I get a lot of data transfer

    It is better to send requests only when the user does not type something for a while.

     var timeoutId = null; $('#input').on('keyup' function() { clearTimeout(timeoutId); timeoutId = setTimeout(function() { // Тут код отправки сообщения что пользователь печатает }, 3000); // Задержка в милисекундах }); 

    I looked more attentively - of course, another user doesn’t see what you are typing, because you don’t send this event to the socket so that it all works, try in my example above, add a message to the server in the place of a comment, like so:

     socket.emit('writing', 'Пользователь печатает сообщение'); 

    And do the handling of this event on the server

     socket.on('writing' ... 
    • Thank you so much) - Sergey74rus

    To the question

    and how best to "keydown" - "keyup" or "keypress"?

    Use keyup + setTimeout, something like a thread

     var timer; element.onkeydown = function () { clearTimeout(timer); }; element.onkeyup = function () { timer = setTimeout(function () { /* тут ваш код */ }, 1500); } 

    The bottom line is that we wait some time after the last key is released (not everyone can type quickly) and then send + keypress does not work with non-character keys (they do not generate it, for example, backspace) With the first part of the question, to Unfortunately, I can not help (

    • Thank you so much) - Sergey74rus