手动触发 Web Socket 的 onmessage 事件

3

我有一个使用PHP和Ratchet编写的小型聊天室。

在JS中,我有以下事件,它触发一个常规的js函数,该函数会在按下回车键时发生:

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

可以这样做,但是我希望在用户输入并发送消息之前,能够显示“用户正在输入”的提示信息。因此,我猜测需要手动调用onmessage事件,这是否可行?

相关的JavaScript代码:

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);
};
1个回答

0

你有一个从服务器传递过来的evt.data。添加另一种类型的事件,当用户正在输入时会触发。

类似于:

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();
    }
};

你只需要在用户输入时向服务器发送一条消息(当用户正在输入时),并可能添加一个超时时间,在大约10秒钟左右如果用户没有输入任何内容,则发送一个typingStopped事件。
以下是使用您提供的代码的示例:
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;
    }
};

onmessage事件发生是因为在你的代码中某处调用了它(你提到当用户按下回车键时),这会将它传递给服务器。这并不意味着你不能在其他地方发送它(比如当有人在输入时)。因为你可以随意修改数据,所以只需将事件作为一个键传递(例如socket.sendMessage({event: 'message', msg: 'testing'});),这样你就可以在另一个客户端上解析出来。 - Blue
总结一下:当用户按下回车键时,向服务器发送多条消息:{type: 'message', msg: 'testing'}。当用户开始输入时,发送 {type: 'typing'}。在超时时间后发送 {type: 'typingStopped'} 以通知其他用户他们不再停止。在另一个客户端上解析 type 以确定发生了什么类型的事件(消息、打字或停止打字),并适当地触发处理程序。 - Blue
非常感谢,那解决了我的问题。还有一个问题,notifyUserTyping 函数在 socket.onmessage 中被调用,发生在另一端(接收方),有没有办法选择端?因为这样我看不到如何检查发送方是否停止输入,我正在检查消息框是否在几秒钟后为空,但是这会检查接收方的消息框。如果您愿意,我可以为此提出新问题。 - user6562256
没有“选择阵营”的问题。你有两个客户端。如果你想让某些东西出现在另一边,你必须使用 WebSocket 消息,并从 onmessage 事件中解析它。 - Blue
我是在比喻,现在我明白了,非常感谢你! - user6562256
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接