user6562256 user6562256 - 4 months ago 28
PHP Question

Trigger web socket onmessage event manually

I have a small shoutbox chat written with PHP and Ratchet.

In JS, I have the following event, which fires a regular js function which happens on pressing enter at the moment:

socket.onmessage = function(evt) {
var data = JSON.parse(evt.data);
addMessage(data.msg);
};


That works, but I want to write a message "user is typing" while the user is typing and before the message is actually sent, so I am guessing I need to call the
onmessage
event manually, is that possible?

relevant js:

var chat = $('#chatwindow');
var msg = $('#messagebox');

function addMessage(msg) {
chat.append("<p>" + msg + "</p>");
}

msg.keypress(function( event ) {
if ( event.which != 13 ) {
return;
}

event.preventDefault();

if (msg.val() == "" || !open) {
return;
}

socket.send(JSON.stringify({
msg: msg.val()
}));

addMessage(msg.val());
msg.val("");

});

socket.onmessage = function(evt) {
var data = JSON.parse(evt.data);
addMessage(data.msg);
};

Answer

You have evt.data which is being passed from the server. Add another type of event, which will trigger when a user is typing.

Something like:

socket.onmessage = function(evt) {
    var data = JSON.parse(evt.data);
    if ( data.type == 'message' ) {
        addMessage(data.msg);
    } else if ( data.type == 'typing' ) {
        showUserIsTyping();
    } else if ( data.type == 'typingStopped' ) {
        hideUserIsTyping();
    }
};

All you'd need to do is send a message to the server when the user is typing, and maybe add a timeout, and send an event of typingStopped if the user hasn't typed anything in like 10 seconds or so.

Here is an example using the code you provided:

var msg = $('#messagebox');

function addMessage(msg) {
    chat.append("<p>" + msg + "</p>");
}

msg.keypress(function( event ) {
    event.preventDefault();

    if (msg.val() == "" || !open) {
        return;
    }

    //User pressed enter
    if ( event.which == 13 ) {
        socket.send(JSON.stringify({
            type: 'message'
            msg: msg.val()
        }));
        addMessage(msg.val());
        msg.val("");
    } else {
        //Keypress, but not enter
        socket.send(JSON.stringify({
            type: 'typing'
        }));
    }
});

socket.onmessage = function(evt) {
    var data = JSON.parse(evt.data);

    switch ( data.type )
    {
        case 'message':
            addMessage(data.msg);
            break;
        case 'typing':
            notifyUserTyping(); //Create this function, and have it show/hide a "Typing..." textbox or similar.
            break;
    }
};