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.
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;
});
Trying to subscribe to a private channel with Pusher. But every time it tries to subscribe I get the error below. Which makes no sense since it's clearly returning the auth info.
Pusher : Error : {"type":"WebSocketError","error":{"type":"PusherError","data":{"code":null,"message":"Auth info required to subscribe to private-sadfsadf"}}}
Normally it's returning the auth json (below) with status 200.
"{\"auth\":\"0b1ce844906bd4d82cb4:21571e5667bf99f17bbf67ae0411594560748fde30b9edeca653653158f8a1f5\"}"
Pusher PHP (shortened)
$pusher = new Pusher($app_key, $app_secret, $app_id);
$auth = $pusher->socket_auth($postvars['channel_name'], $postvars['socked_id']);
if ($auth)
return $response->withJSON($auth);
else
return $response->withStatus(403);
Pusher JS
var pusher = new Pusher('0b1ce844906bd4d82cb4', {
cluster: 'us2',
encrypted: true,
authEndpoint: '{{site.uri.public}}/chat/auth/{{game.id}}',
authTransport: 'ajax',
auth: {
params: {
'csrf_name': '{{site.csrf.name}}',
'csrf_value': '{{site.csrf.value}}'
},
headers: {
'{{site.csrf.name}}': '{{site.csrf.value}}'
}
}
});
I had this error and it was caused by having the BROADCAST_DRIVER set to redis instead of pusher.
it was because my endpoint /pusher/auth returned the signature in JSON format.
So, I just changed this:
return $response
To this:
return json_decode($response)
NB: PUSHER signature use hash_hmac to generate hash:
you can compare you entryPoint return with
$sig = hash_hmac('sha256',$socket, $channelNam);
var_dump($sig);
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);
});
});
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