I recently upgraded to 5.3 from 5.2.
Last week I installed Laravel Echo, and am using it with Pusher, Vue and Vue-resource.
Everytime I post to my database I get this error
Cannot set property 'X-Socket-ID' of undefined
The doc says if you use Vue and Vue-resource X-Socket-ID is attached to the header automatically, but obviously no in this case
Does anyone got any ideas how to solve this?
Error comes from this code
Vue.http.interceptors.push(function (request, next) {
if (_this.socketId()) {
request.headers['X-Socket-ID'] = _this.socketId();
}
next();
});
main.js
var Vue = require('vue');
window.moment = require('moment');
require("moment/locale/ja.js");
window.Vue = Vue;
Vue.use(require('vue-resource'));
window.Pusher = require('pusher-js');
import Echo from "laravel-echo"
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'my key'
});
Thanks for you help
solved after installing Vue-resource#^0.9.3
Related
I'm trying to keep only one connection active per user who open multiple tabs on my application that uses Pusher with Laravel Echo, I was able to get it working on a test project by following the article and the example project below.
https://blog.pusher.com/reduce-websocket-connections-with-shared-workers/
https://github.com/pusher-community/pusher-with-shared-workers
But I'm having a hard time trying to adapt it to work with my Laravel project, how should I do that?
Here is the configuration I have added to my bootstrap.js file
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
encrypted: true
});
$.getJSON( "/heartbeat", function( json ) {
window.Echo.channel('user.' + json.user_id).listen('NotifyUser', e => {
displayModal(e.msg);
console.log('User with an id of ' + e.id + ' has been notified.');
console.log(e);
// Relay the message on to each client
clients.forEach(function(client){
client.postMessage(data);
});
});
});
self.addEventListener("connect", function(evt){
// Add the port to the list of connected clients
var port = evt.ports[0];
clients.push(port);
// Start the worker.
port.start();
});
It's working but not the way I want, it's creating a new connection for each opened tab.
As specified in the link you provided yourself: https://blog.pusher.com/reduce-websocket-connections-with-shared-workers/ , you need to import a specific version of pusher to use worker: pusher.worker.js.
So, go here: https://github.com/pusher/pusher-js/tree/master/dist/worker
and download the pusher.worker.min.js . Put it in the same directory as your boostrap.js and require it. Instead of:
window.Pusher = require('pusher-js');
use
importScripts("pusher.worker.min.js");
I can't manage to get echo and pusher working when using private channels, googled for two days and found nada.
What seems to be happening is some sort of problem with the authentication (I'm using Laravel basic Auth) cause I can subscribe to public channels
routes/channels.php
Broadcast::channel('private-ci-received-{userId}', function ($user, $userId) {
return (int) $user->id === (int) $userId;
});
Broadcast::channel('private-ci-received-{toUserId}', function ($currentUser, $toUserId) {
return true;
});
bootstrap.js
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
logToConsole: true,
encrypted: true,
});
default.blade.php(main layout)
Pusher.logToConsole = true;
Echo.logToConsole = true;
Echo.private('ci-received-{{ Auth::user()->id}}')
.listen('.CIReceived', (e) => {
console.log(e);
});
What get printed on the console is :
Pusher : No callbacks on private-ci-received-1 for pusher:subscription_error
It's a pretty generic error, then for debug purposes I tried to bind the error using Pusher (not laravel echo)
var pusher = new Pusher('MYSECRETAPPKEYHERE', {
cluster: 'us2',
forceTLS: true
});
var channel = pusher.subscribe('private-ci-received-1');
channel.bind('pusher:subscription_error', function(data) {
console.log(data);
});
console.log(data) output
JSON returned from webapp was invalid, yet status code was 200
The default authEndPoint is /broadcasting/auth IIRC I think it expects to return a JSON but instead it returns the HTML CODE from my page.
Those routes are created by the framework itself and from what I've read Laravel echo and Laravel Auth should work great together without much fiddling.
My .env file is correct i'm using pusher as broadcast driver and BroadcastServiceProvider is properly uncommented.
Can anyone shed a light in the matter? Thanks
This worked for me
Default value of .env is
BROADCAST_DRIVER=log
Pls change it to
BROADCAST_DRIVER=pusher
I was also getting ["No callbacks on private-user.1 for pusher:subscription_error"]
After making the above changes, it works fine for me
Set APP_DEBUG=true in your .env file and check the HTTP response of your auth route in the network section of your browser's developer tools. If authentication is successful, your laravel app should respond with JSON like this:
{"auth": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
If there's an error it will show you in the response since you set debug mode to true.
You do not need to add private- onto your channel in broadcasting.php this is done automagically
Try this
Broadcast::channel('ci-received-{userId}', function ($user, $userId) {
return (int) $user->id === (int) $userId;
});
I'm using pusher in my project.in console debug show the event when I want to connect to the channel in the dashboard show the Disconnection status and I don't get the event on javascript App.
js Code:
Echo.private(`order.${orderId}`)
.listen('NewChat', (e) => {
console.log(e.message);
}
);
Broadcast config:
PUSHER_APP_ID=625***
PUSHER_APP_KEY=bcd15f3d3c6*******
PUSHER_APP_SECRET=c8e7e09d21********
PUSHER_APP_CLUSTER=ap2
bootstrap.js:
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'bcd15f3d3***********',
cluster: 'ap2',
encrypted: false
});
event:
public function broadcastOn()
{
return new PrivateChannel('order.'.$this->order_id);
}
channel:
Broadcast::channel('order.{orderId}', function () {
return true;
});
console debug status
I have no real experience iwth Laravel in combination with pusher, but i see the following:
Broadcast::channel('order.{orderId}',
{orderId} wont be translated to an variable value. You need {$orderId}. Also, doing this in a single quoted string wont work because it will just print {$orderId}, so you need double quotes.
Try the following:
Broadcast::channel("order.{$orderId}",
Maybe this will solve your problem, maybe not.
If not, are you sure private(order.${orderId}) is using the right Id?
Check if return new PrivateChannel('order.'.$this->order_id); is using the right $this->order_id.
I recently check out my project from SVN. I ran into "Uncaught ReferenceError: $ is not defined" where ever I have used "$" ie; Jquery. I am using laravel mixer to combine the JS and CSS Files.
This is my bootstrap.js
window._ = require('lodash');
window.Popper = require('popper.js').default;
window.tooltip = require('tooltip.js');
try {
window.$ = window.jQuery = require('jquery');
require('jquery-ui-dist/jquery-ui.min.js');
require('bootstrap');
} catch (e) {}
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
//Moment JS
window.moment = require('moment');
//Collect JS
window.collect = require('collect.js');
//Clipboard JS
window.ClipboardJS = require('clipboard');
//Import Toster
window.toastr = require('toastr');
//Swaet Alert
import Swal from 'sweetalert2';
window.swal = Swal;
//Owl Carousel
window.owlCarousel = require('owl.carousel');
//JS Cookie
window.Cookies = require('js-cookie');
//Image Zoom
require('ez-plus');
This is my webpack.mix.js
let mix = require('laravel-mix');
mix.js('resources/assets/js/app.js', 'public/js').sourceMaps()
.sass('resources/assets/sass/app.scss', 'public/css');
My Laravel Version: 5.5.40
laravel-mix Version: 1.7.2
This worked for me:
Remove the defer from the app.js script tag and change window.$ = window.jquery = to global.$ = global.jquery =
Weather or not this is the correct way to do it, this has worked for me.
laravel 5.7
I'm looking into Laravel Echo (With socket.io as connector)
But I can't find out how to bind a callback when user/visitor succeed or not connecting to the socket (Not channel), but generally if connected.
import Echo from "laravel-echo"; //import Laravel-echo
if(typeof(io) != 'undefined'){ //check if io loaded
//init Echo
window.Echo = new Echo({
broadcaster: 'socket.io',
host: { path: '/socket.io' }
});
}
So here I do check if io exist, then most probably socket is up.
But can we bind a callback like we can do with socket.io:
Example from socket.io docs
const socket = io('http://localhost');
console.log(socket.id); // undefined
socket.on('connect', () => {
console.log(socket.id); // 'here we can get socket id'
});
The reason why I need a callback is to get the socket id and initiate other scripts.
Looking deeper into the laravel echo source code, I've found that there is on event binder, that we can't call straight away echo.on('connect', ...). But we have access to connector and the actual socket so here is the solution:
if(typeof(io) != 'undefined'){ //check if io loaded
//init Echo
echo = new Echo({
broadcaster: 'socket.io',
host: { path: '/socket.io' }
});
//bind our events
echo.connector.socket.on('connect', function(){
console.log('connected', echo.socketId());
});
echo.connector.socket.on('disconnect', function(){
console.log('disconnected');
});
echo.connector.socket.on('reconnecting', function(attemptNumber){
console.log('reconnecting', attemptNumber);
});
}
For anyone trying to figure out how to return a promise from a Presence channel here connection, the following worked for me:
// return a promise and resolve when the subscription has succeeded
return new Promise((resolve, reject) => {
echo.connector.channels['presence-' + channel].subscription.bind('pusher:subscription_succeeded', () => {
return resolve(true);
});
});