【问题标题】:Inform user that message is still being typed通知用户仍在输入消息
【发布时间】:2018-09-02 18:08:54
【问题描述】:

我正在使用 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 without pusherwithout redis

【问题讨论】:

  • 你可能想要限制它。

标签: javascript laravel vue.js laravel-5.6


【解决方案1】:

如果您查看 broadcasting documentation,您会看到两个代码 sn-ps,您可以在 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);
}

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

创建应用后,您还需要倾听耳语。以下方法将在收到事件后将typing 变量设置为true 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);
        });
},

【讨论】:

  • 我没有使用推送器。对不起,我在问题中提到了。
【解决方案2】:

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

首先,让我们定义“打字”的含义。定义它的最简单方法是说当且仅当发送消息的输入字段不为空时,用户正在键入。

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

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

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

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

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

【讨论】:

    【解决方案3】:

    您不必向您的应用发送 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);
        });
    

    【讨论】:

    • 不,这是 Laravel Echo 的功能。 Echo 是一个同时支持 Pusher 和 Socket.io 的封装库。
    • 带有 vue.js 和 laravel 的 socket.io 不支持这两种方法 Whisper 和 listenForWhisper
    • 它适用于 socket.io 中的私人频道。你在哪里读到它不受支持。我不相信是这样的
    【解决方案4】:

    是的,您是对的,它不应该在每个字符更改时都发出,而是您可以使用 debounce 等待一小段时间然后触发该函数。

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

    请查看文档:https://lodash.com/docs/4.17.5#debounce

    Laravel 的 Echo 听起来也不错,因为您无需在后端使用 typing 操作,因此仅从客户端发送到客户端比涉及服务器要好。

    【讨论】:

    • 您是否有任何建议来检查用户是否在没有我的问题中提到的情况下输入他们的消息?很抱歉,这不是答案。
    猜你喜欢
    • 1970-01-01
    • 2016-05-12
    • 2017-12-04
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多