0

私は1年半の間、これに対する解決策を見つけようとしてきました.これは、解決策が見えないこの問題に関する私の別の投稿ですhttps://github.com/beyondcode/laravel-websockets/issues/322

その投稿以来、何も変更されていないため、関連するすべてのリソースの比較的最新バージョンがあります (先月半に更新されました)。

パッケージ.json

"laravel-echo": "^1.10.0",
"laravel-echo-server": "^1.6.2",

composer.json

"beyondcode/laravel-websockets": "^1.11.1",
"pusher/pusher-php-server": "^4.1.5"

そして、その問題は何も変わっていないことを報告したので、今の違いは、私の問題はチャットモジュールでより顕著であることです.

基本的に、websockets はほとんどの部分で機能しますが、何らかの奇妙な理由で、ある時点で購読しているユーザーに更新を配信しないことを決定するか、laravel echo がスリープ状態になり、配信された更新の処理を忘れるため、X がメッセージを送信します人 Y に、しかし人 Y はそのメッセージを受信しません。ある時点で、人 X が新しいメッセージを送信すると、システムが再び機能し始め、その後、人 Y は突然すべてのメッセージを受信しますが、最初のメッセージはもともと 30 分前に送信されたものです遅すぎるため、別の状況では、人々はチャットでメッセージの重複を見ることさえできます.予定の予約デスク、およびそれらのユーザーはメッセージが時間内に配信されなかったため、わかりません。

これは非常に散発的に発生するため、ローカル環境で再現できなかったので、問題を簡単に追跡できました。システムは 90% の時間で動作しますが、残りの 10% はユーザーに問題を引き起こすのに十分な影響を与えているようです。github リンクをたどった場合、そのコードはそれ以降何も変更されていませんが、chat モジュール サブスクリプションのコードを追加します (他のモジュールへの異なるサブスクリプションを持つ他の vue ファイルがあることに注意してください (5 つの異なるサブスクリプションがあると思います)ユーザーあたりのチャンネル登録総数):

会話.vue

/**
 * Starts listening to update conversation events.
 *
 */
updateChat() {
    Echo.channel(`update-conversation.${this.office_id}.${this.conversation.id}.${this.user_id}`)
        .listen('.list.new.messages', (event) => {
            this.listNewMessages();
        });
},

/**
 * Stops listening to update conversation events.
 *
 */
stopUpdatingChat() {
    Echo.leaveChannel(`update-conversation.${this.office_id}.${this.conversation.id}.${this.user_id}`);
    Event.$emit('stop-new-devsupport-conversation', this.conversation.id, this.user_id);
},

channels.php

Broadcast::channel('update-conversation.{officeId}.{conversationId}.{userId}', function ($user, $officeId, $conversationId, $userId) {
    return ($user->hasPermission('chat') && $user->office_id === $officeId && $user->id === $conversationId && User::find($userId)->office_id === $officeId);
});

そして、これはイベントConversationEvent.phpです

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class ConversationEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $officeId;
    public $conversationId;
    public $userId;

    /**
     * Create a new event instance.
     *
     * @param  int  $officeId
     * @param  int  $conversationId
     * @param  int  $userId
     * @return void
     */
    public function __construct($officeId, $conversationId, $userId)
    {
        $this->officeId = $officeId;
        $this->conversationId = $conversationId;
        $this->userId = $userId;
    }

    /**
     * The event's broadcast name.
     *
     * @return string
     */
    public function broadcastAs()
    {
        return 'list.new.messages';
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel('update-conversation.' . $this->officeId . '.' . $this->conversationId . '.' . $this->userId);
    }
}

これに加えて、これはBootstrap.jsファイルの Echo 構成です。

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: window.PUSHER_APP_KEY,
    wsHost: window.location.hostname,
    wsPort: window.APP_DEBUG ? 6001 : 6002,
    wssPort: window.APP_DEBUG ? 6001 : 6002,
    disableStats: true,
    encrypted: !window.APP_DEBUG,
    enabledTransports: ['ws', 'wss'],
    forceTLS: false,
});

そしてBroadcast.php

'connections' => [
    'pusher' => [
        'driver' => 'pusher',
        'key' => env('PUSHER_APP_KEY'),
        'secret' => env('PUSHER_APP_SECRET'),
        'app_id' => env('PUSHER_APP_ID'),
        'options' => [
            'cluster' => env('PUSHER_APP_CLUSTER'),
            'encrypted' => true,
            'host' => '127.0.0.1',
            'port' => 6001,
            'scheme' => 'http',
        ],
    ],
]

github の投稿で述べたように、このhttps://alex.bouma.dev/installing-laravel-websockets-on-forge/に基づいて websockets の構成を完全に作成し、Forge で動作するようにしました。

わかりませんが、ユーザーが一定時間更新を受け取らなかった場合、自動的にチャンネル登録を解除するタイムアウトがあるのでしょうか? たとえば、一部のクライアントが私に送信したスクリーンショットには、メッセージの間隔が8分ほどあるため、そうは思いません。

私は本当に、本当にこの問題の解決策を最終的に見つけたいと思っているので、誰かが手を貸してくれるなら、本当に感謝しています.

前もって感謝します。

4

0 に答える 0