Laravel Echo не получает уведомления Pusher в реальном времени - идеи?
Я пытаюсь реализовать подход обмена сообщениями пользователей, используя идеи с этого сайта:
https://www.sitepoint.com/add-real-time-notifications-laravel-pusher/
Ключевой идеей является использование возможности уведомлений laravel для обновления таблицы уведомлений (с целью пометки сообщений как прочитанных) и одновременной широковещательной передачи в виде частного канала и прослушивания в клиенте через Laravel Echo.
Я хочу отправлять уведомления при добавлении нового упражнения, поэтому я использую EventServiceProvider для прослушивания события создания базы данных, и именно здесь я запускаю уведомление:
Exercise::created(function ($exercise) {
foreach ($users as $user) {
$user->notify(new NewExercisePosted($user, $exercise));
}
Уведомление:
class NewExercisePosted extends Notification implements ShouldBroadcast
{
//use Queueable;
protected $exercise;
protected $user;
public function __construct(User $user, Exercise $exercise)
{
$this->user = $user;
$this->exercise = $exercise;
}
public function via($notifiable)
{
return ['database', 'broadcast'];
}
public function toArray($notifiable)
{
return [
'id' => $this->id,
'read_at' => null,
'data' => [
'user_id' => $this->user->id,
'ex_id' => $this->exercise->id,
],
];
}
}
Это просто заполнение таблицы уведомлений и широковещательная рассылка.
Вот мой основной вид файла:
<!DOCTYPE html>
<html>
<head>
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="stylesheet" href="/css/app.css")/>
<script src='https://www.google.com/recaptcha/api.js'></script>
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
<!-- This makes the current user's id available in javascript -->
@if(!auth()->guest())
<script>
window.Laravel.userId = <?php echo auth()->user()->id; ?>
</script>
@endif
</head>
<body>
@include('partials/header')
@if(Session::has('message'))
<div class="alert alert-info">
{{Session::get('message')}}
</div>
@endif
@yield('content')
@include('partials/footer')
@include('partials/analytics')
<script src="/js/app.js"></script>
</body>
</html>
Вот соответствующая часть представления заголовка, где у меня появляются сообщения:
<li class="dropdown">
<a class="dropdown-toggle" id="notifications" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<span class="glyphicon glyphicon-user"></span>
</a>
<ul class="dropdown-menu" aria-labelledby="notificationsMenu" id="notificationsMenu">
<li class="dropdown-header">No notifications</li>
</ul>
</li>
Вот мой app.js:
require('./bootstrap');
var app = 0;
window._ = require('lodash');
window.$ = window.jQuery = require('jquery');
require('bootstrap-sass');
$(document).ready(function () {
$(function () {
$('[data-toggle="tooltip"]').tooltip()
})
});
window.Pusher = require('pusher-js');
import Echo from "laravel-echo";
const PUSHER_KEY = 'blah';
const NOTIFICATION_TYPES = {
follow: 'App\\Notifications\\UserFollowed',
newEx: 'App\\Notifications\\NewExercisePosted'
};
window.Echo = new Echo({
broadcaster: 'pusher',
key: PUSHER_KEY,
cluster: 'mt1',
encrypted: true
});
var notifications = [];
$(document).ready(function() {
// check if there's a logged in user
if(Laravel.userId) {
// load notifications from database
$.get(`/notifications`, function (data) {
addNotifications(data, "#notifications");
});
// listen to notifications from pusher
window.Echo.private(`App.User.${Laravel.userId}`)
.notification((notification) => {
addNotifications([notification], '#notifications');
});
}
});
function addNotifications(newNotifications, target) {
console.log(notifications.length);
notifications = _.concat(notifications, newNotifications);
// show only last 5 notifications
notifications.slice(0, 5);
showNotifications(notifications, target);
}
function showNotifications(notifications, target) {
if(notifications.length) {
var htmlElements = notifications.map(function (notification) {
return makeNotification(notification);
});
$(target + 'Menu').html(htmlElements.join(''));
$(target).addClass('has-notifications')
} else {
$(target + 'Menu').html('<li class="dropdown-header">No notifications</li>');
$(target).removeClass('has-notifications');
}
}
// Make a single notification string
function makeNotification(notification) {
var to = routeNotification(notification);
//console.log(to);
var notificationText = makeNotificationText(notification);
return '<li><a href="' + to + '">' + notificationText + '</a></li>';
}
function routeNotification(notification) {
//console.log(notification.data.data.ex_id);
var to = `?read=${notification.id}`;
if(notification.type === NOTIFICATION_TYPES.follow) {
to = 'users' + to;
} else if(notification.type === NOTIFICATION_TYPES.newEx) {
const exId = notification.data.data.ex_id;
to = `guitar-lesson-ex/${exId}` + to;
}
return '/' + to;
}
function makeNotificationText(notification) {
var text = '';
if(notification.type === NOTIFICATION_TYPES.follow) {
const name = notification.data.follower_name;
text += `<strong>${name}</strong> followed you`;
} else if(notification.type === NOTIFICATION_TYPES.newEx) {
text += `New exercise posted`;
}
return text;
}
Вещи работают несколько, но не совсем. Сообщения появляются в базе данных и в Pusher сразу после того, как я создаю новое упражнение, и когда вы щелкаете уведомление MarkAsRead, уведомление помечается как прочитанное. Вот проблема:
Когда я создаю новое упражнение, клиент не обновляется в реальном времени. Кажется, что это производит изменения только при обновлении страницы.
Исходя из того, что я имею выше, какие-либо советы о том, как исправить вещи? Я не разбираюсь в javascript, особенно в области переменных, порядке выполнения и т. Д., И т. Д. Поэтому я подозреваю, что упустил некоторые тонкости. Я гитарист, прежде чем я разработчик!
Спасибо!
Брайан
1 ответ
Я провел весь день вчера, пытаясь выяснить это, и в конце концов, все сводилось к * vs {id}...
Проблема была в файле channel.php, где выполняется авторизация канала. Я использовал App.User. {Id}, не понимая, что было в соответствии с инструкциями 5.4, когда на самом деле для 5.3 должен быть App.User. *
Я просто даже не думал об этом думать! Сейчас все работает как положено.
спасибо Брайан