#laravel #websocket #pusher #laravel-echo #laravel-websockets
Вопрос:
Я пытался найти решение этой проблемы в течение полутора лет, вот еще один из моих постов, касающихся этой проблемы, но решения не видно https://github.com/beyondcode/laravel-websockets/issues/322
После этого поста ничего не изменилось, у меня есть относительно последняя версия всех задействованных ресурсов (обновлена за последние полтора месяца).
пакет.json
"laravel-echo": "^1.10.0",
"laravel-echo-server": "^1.6.2",
композитор.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, с тех пор в этом коде ничего не изменилось, но я собираюсь добавить код для подписки на модуль чата (имейте в виду, что у меня есть другие файлы vue с разными подписками на другие модули (я думаю, что всего на одного пользователя приходится 5 разных подписок на каналы).:
Conversation.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') amp;amp; $user->office_id === $officeId amp;amp; $user->id === $conversationId amp;amp; User::find($userId)->office_id === $officeId);
});
And this is the event ConversationEvent.php
namespace AppEvents;
use IlluminateBroadcastingChannel;
use IlluminateBroadcastingInteractsWithSockets;
use IlluminateContractsBroadcastingShouldBroadcast;
use IlluminateFoundationEventsDispatchable;
use IlluminateQueueSerializesModels;
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 IlluminateBroadcastingChannel|array
*/
public function broadcastOn()
{
return new Channel('update-conversation.' . $this->officeId . '.' . $this->conversationId . '.' . $this->userId);
}
}
In addition to this, this is the Echo configuration in the Bootstrap.js file
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,
});
And broadcasting.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',
],
],
]
Like I said on my github post, I entirely based my websockets configuration on this https://alex.bouma.dev/installing-laravel-websockets-on-forge/ to make it work with Forge
I don’t know, but is there maybe a timeout to automatically unsubscribe users to channels if they haven’t received an update after certain amount of time? I really wouldn’t think so as screenshots some clients have sent me have like 8 minutes between messages for example.
Я действительно, ДЕЙСТВИТЕЛЬНО хочу, наконец, найти решение этой проблемы, поэтому, пожалуйста, если кто-нибудь может помочь, я буду очень благодарен.
Заранее спасибо.