通知用户仍在键入消息

时间:2018-03-24 01:13:58

标签: javascript laravel vue.js laravel-5.6

我使用的是Laravel 5.6.7,Socket.IO和vue.js. 我没有使用Pusher和redis 。下面是我向用户发送消息的代码,一对一与我聊天。

var url = "http://localhost:6001/apps/My_appId/events?auth_key=My_Key";

var socketId = Echo.socketId();
var request = {
    "channel": "private-Send-Message-Channel.2",
    "name": "MessengerEvent",
    "data": {
        "msg": message
    },
    "socket_id": socketId
};
axios.post(url, JSON.stringify(request)).then((response) => {
    //Message Sent
});

我正在尝试通知正在和我聊天的用户我还在打字。我应该使用相同的上面代码,在每个char类型上发出xhr吗?这是告知用户消息输入仍在进行中的唯一方法吗?

更新1

有没有更好的方法来发布xhr,如上所述每个按键?我的意思是如果用户键入200个字符。我会发布xhr 200次吗?

我们是否有一个名为whisper和listenForWhisper的活动,如https://laravel.com/docs/5.6/broadcasting#client-events所示?我正在使用vue.js和laravel 5.6.7 没有推送器没有redis

4 个答案:

答案 0 :(得分:1)

如果您查看broadcasting documentation,您会看到两个代码段摘要,您可以在Vue.js应用程序中使用这些代码段。

要广播客户端事件,您可以使用Echo的whisper方法:

Echo.private('chat')
    .whisper('typing', {
        name: this.user.name
    });

要收听客户端事件,您可以使用listenForWhisper方法:

Echo.private('chat')
    .listenForWhisper('typing', (e) => {
        console.log(e.name);
    });

在用户输入内容时,您可以debounce上面的私语方法。

如果你不想使用像lodash这样的其他库,你可以通过简单地将whisper包裹在超时中来实现去抖动。以下方法每300毫秒播放一次耳语:

isTyping() {
    let channel = Echo.private('chat');

    setTimeout(function() {
        channel.whisper('typing', {
            name: this.user.name,
            typing: true
        });
    }, 300);
}

当聊天应用程序的输入字段中出现isTyping()事件时,应用需要触发onkeydown

创建应用后,您还需要倾听耳语。在接收到事件后,以下方法将typing变量设置为真,持续600ms。

created() {
    let _this = this;

    Echo.private('chat')
        .listenForWhisper('typing', (e) => {
            this.user = e.name;
            this.typing = e.typing;

            // remove is typing indicator after 0.6s
            setTimeout(function() {
                _this.typing = false
            }, 600);
        });
},

答案 1 :(得分:0)

我不是Laravel专家,但我之前遇到过这个问题。

首先,让我们来定义"输入"手段。定义它的最简单方法是,当且仅当发送消息的输入字段不为空时,用户才键入。

这并不完美,因为用户可以在键入消息的过程中离开键盘,然后不返回完成和/或发送消息,但这已经足够了。

更重要的是,我们现在不需要关心击键来了解用户是否正在打字。事实上,"用户正在打字"现在变得像chat_input_box.length > 0一样容易在代码中表示。

此布尔值是需要在用户/服务器之间同步的内容,而不是用户在键盘上敲击键的行为。但是,为了使值保持最新,我们需要捕获chat_input_box上的输入事件,如果布尔值在此当前事件发生之前已发生更改,则socket.io应该能够发送表示用户是否为用户的信号已停止或开始输入。

在接收方,此信号切换适当的视图以显示或消失,以便以人的方式向用户显示应用的状态。

对于用户输入内容然后离开的缺点,可以设置超时,以便在完成时,布尔值"键入"重置为false,而输入内容的行为会重置超时,然后自动重新启动。

答案 2 :(得分:0)

  

您不必向您的应用发送xhr请求。你可以   直接向聊天用户广播事件,而无需点击您的应用。

来自Laravel docs

有时您可能希望将事件广播到其他连接的客户端,而根本不需要使用Laravel应用程序。这对于诸如"输入"之类的内容特别有用。通知,您希望提醒应用程序的用户另一个用户在给定屏幕上键入消息。要广播客户端事件,您可以使用Echo的whisper方法:

Echo.private('chat')
    .whisper('typing', {
        name: this.user.name
    });

要收听客户端事件,您可以使用listenForWhisper方法:

Echo.private('chat')
    .listenForWhisper('typing', (e) => {
        console.log(e.name);
    });

答案 3 :(得分:-1)

是的,你是对的,它不应该在每个角色变化上发出,而你可以使用去抖等待一小段时间,然后激活该功能。

我建议使用lodash库的debounce方法。它应该是这样的。

  

请查看文档:{​​{3}}

Laravel的Echo也听起来很不错,因为你在后端采取typing动作什么都不做,因此从客户端发送到客户端比使用服务器更好。