In my laravel application i am using laravel ECHO. In this I'm trying to listen a event "pusher:subscribe" through on method. But I its not happening. I can able to subscribe, add_memeber, remove_memeber as per laravel echo documentation. But i cannot able to listen specifically "pusher:subscribe" event. Actually I am trying to get data from this event and i will manipulate further
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'myKeyHere',
authEndpoint: 'pusher/auth',
auth: {
headers: {
},
params: {
username: this.username
}
}
});
window.Echo.join('openChat').here((users) => {
console.log(users);
}).listen('MessagePublished', (e) => {
console.log('Message Received');
}).on('pusher:subscribe', (users) => {
console.log('NOT WORKING');
}).joining((user) => {
console.log('User Joined');
}).leaving((user) => {
console.log('User gone');
});
After a deep lookup in documents and forums i understood pusher:subscribe is a internal event , so it cannot be captured through Laravel ECHO. But I used pusher:subscription_succeeded to capture the member info ..
Modified Code:
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'myKeyHere',
authEndpoint: 'pusher/auth',
auth: {
headers: {
},
params: {
username: this.username
}
}
});
window.Echo.join('openChat').here((users) => {
console.log(users);
}).listen('MessagePublished', (e) => {
console.log('Message Received');
}).on('pusher:subscription_succeeded', (member) => {
console.log(member);
}).joining((user) => {
console.log('User Joined');
}).leaving((user) => {
console.log('User gone');
});
Related
I created a web app for video using Laravel, pusher and react js but now problem is that I was following the tutorial I don't know about the react but I'm good in Laravel.
Now I want to add a function where I can send email to a user so he can join me in video chat, right now it is working on click functions where react take an id and send the request to the client channel.
here is my react code.
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import MediaHandler from '../MediaHandler';
import Pusher from 'pusher-js';
import Peer from 'simple-peer';
const APP_KEY = 'removed-app-key';
export default class App extends Component {
constructor() {
super();
this.state = {
hasMedia: false,
otherUserId: null
};
this.user = window.user;
this.user.stream = null;
this.peers = {};
this.mediaHandler = new MediaHandler();
this.setupPusher();
this.callTo = this.callTo.bind(this);
this.setupPusher = this.setupPusher.bind(this);
this.startPeer = this.startPeer.bind(this);
}
componentWillMount() {
this.mediaHandler.getPermissions()
.then((stream) => {
this.setState({hasMedia: true});
this.user.stream = stream;
try {
this.myVideo.srcObject = stream;
} catch (e) {
this.myVideo.src = URL.createObjectURL(stream);
}
this.myVideo.play();
})
}
setupPusher() {
Pusher.logToConsole=true;
this.pusher = new Pusher(APP_KEY, {
authEndpoint: '/pusher/auth',
cluster: 'ap2',
auth: {
params: this.user.id,
headers: {
'X-CSRF-Token': window.csrfToken
}
}
});
this.channel = this.pusher.subscribe('presence-video-channel');
this.channel.bind(`client-signal-${this.user.id}`, (signal) => {
let peer = this.peers[signal.userId];
// if peer is not already exists, we got an incoming call
if(peer === undefined) {
this.setState({otherUserId: signal.userId});
peer = this.startPeer(signal.userId, false);
}
peer.signal(signal.data);
});
}
startPeer(userId, initiator = true) {
const peer = new Peer({
initiator,
stream: this.user.stream,
trickle: false
});
peer.on('signal', (data) => {
this.channel.trigger(`client-signal-${userId}`, {
type: 'signal',
userId: this.user.id,
userName:this.user.name,
data: data
});
});
peer.on('stream', (stream) => {
try {
this.userVideo.srcObject = stream;
} catch (e) {
this.userVideo.src = URL.createObjectURL(stream);
}
this.userVideo.play();
});
peer.on('close', () => {
let peer = this.peers[userId];
if(peer !== undefined) {
peer.destroy();
}
this.peers[userId] = undefined;
});
return peer;
}
callTo(userId) {
this.peers[userId] = this.startPeer(userId);
}
render() {
return (
<div className="App">
{[1,2,3,4].map((userId) => {
return this.user.id !== userId ? <button key={userId} onClick={() => this.callTo(userId)}>Call {name}</button> : null;
})}
<div className="video-container">
<video className="my-video" ref={(ref) => {this.myVideo = ref;}}></video>
<video className="user-video" ref={(ref) => {this.userVideo = ref;}}></video>
</div>
</div>
);
}
}
if (document.getElementById('app')) {
ReactDOM.render(<App />, document.getElementById('app'));
}
Here is my pusher function.
public function authenticate(Request $request){
$socketId= $request->socket_id;
$channelName= $request->channel_name;
$pusher = new Pusher('APP_KEY', 'APP_SECRET','APP_ID',['cluster'=> 'ap2','forceTLS'=>true]);
$presence_data = ['name' => auth()->user()->name];
$key = $pusher->presence_auth($channelName, $socketId, auth()->id(), $presence_data);
return response($key);
}
My head script
!-- Scripts -->
#if(auth()->user())
<script>
window.user = {
id:{{auth()->id()}},
name:"{{auth()->user()->first_name}}"
};
window.csrfToken = "{{ csrf_token() }}";
</script>
#endif
The simple thing I want to create a room where I can send email to user to join me one-to-one video chat.
I'm searching this from last night but no good result till now
I trying to create CHAT in fresh Laravel 6.0 framework.
I following this tutorial https://pusher.com/tutorials/chat-laravel
Routes file, web.php
Route::get('messages', 'ChatsController#fetchMessages');
Route::post('messages', 'ChatsController#sendMessage');
JavaScript files
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
import Pusher from 'pusher-js';
Echo.private('chat').listen('MessageSent', (e) => {
this.messages.push({
message: e.message.message,
user: e.user
});
});
import Echo from "laravel-echo"
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'xxxxxx',
cluster: 'eu',
encrypted: false,
useTLS: false
});
const app = new Vue({
el: '#app',
data: {
messages: []
},
created() {
this.fetchMessages();
},
methods: {
fetchMessages() {
axios.get('messages').then(response => {
this.messages = response.data;
});
},
addMessage(message) {
this.messages.push(message);
axios.post('messages', message).then(response => {
console.log(response.data);
});
}
}
});
BroadcastServiceProvider.php
class BroadcastServiceProvider extends ServiceProvider
{
public function boot()
{
Broadcast::routes();
Broadcast::channel('chat', function ($user) {
return Auth::check();
});
}
}
MessageSent.php Event
public function broadcastOn()
{
return new PrivateChannel('chat');
}
MySQL input works but fetch on another browser NO!
There is Error 500 in Console Log
POST http://localhost:8000/messages 500 (Internal Server Error)<br>
Uncaught (in promise) Error: Request failed with status code 500<br>
at createError (createError.js?2d83:16)<br>
at settle (settle.js?467f:17)<br>
at XMLHttpRequest.handleLoad (xhr.js?b50d:59)<br>
There is fresh laravel log file: https://pastebin.com/vnjNUd2n
have a nice day !
I have a problem:
I set up Laravel Echo & Pusher but got this error, have no idea to resolve :(
I checked my app-key, app-cluster but all are correct.
Can someone help me?
app.js
const app = new Vue({
el: '#app',
data: {
messages: []
},
methods:{
addMessage(message){
this.messages.push(message);
axios.post('/messages', message).then(response => {
console.log(response);
});
}
},
created(){
axios.get('/messages').then(response => {
this.messages = response.data;
});
Echo.channel('chatroom')
.listen('MessageEvent', (e) => {
console.log(e);
});
}
})
bootstrap.js
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: '************',
cluster: 'ap1',
encrypted: false
});
MessageEvent
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message, $user;
public function __construct(Message $message, User $user)
{
$this->message = $message;
//query
$this->user = $user;
}
public function broadcastOn()
{
return new PresenceChannel('chatroom');
}
channels.php
Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Broadcast::channel('chatroom', function ($user, $id) {
return $user;
});
Error 403 or 500 /broadcasting/auth with Laravel version > 5.3 & Pusher, you need change your code in resources/assets/js/bootstrap.js with
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'your key',
cluster: 'your cluster',
encrypted: true,
auth: {
headers: {
Authorization: 'Bearer ' + YourTokenLogin
},
},
});
And in app/Providers/BroadcastServiceProvider.php change by
Broadcast::routes()
with
Broadcast::routes(['middleware' => ['auth:api']]);
or
Broadcast::routes(['middleware' => ['jwt.auth']]); //if you use JWT
it worked for me, and hope it help you.
Remove the $id as you are not passing from the event
Broadcast::channel('chatroom', function ($user) {
return true;
});
I think you need to give an authentic point if u have used laravel echo just goto
Resources/assets/js/bootstrap.js
Just add the following line inside the window
Echo = new Echo({
authEndpoint : 'http://localhost/projectName/public/broadcasting/auth',
});
if you're working on localhost make sure that your .env file is set up properly
try setting
APP_URL=http://localhost
DB_HOST=localhost
and run
php artisan config:cache
hope this will help you.
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);
});
});
Trying to integrate APIs built in Laravel 5.4 with ionic 2 and struggling handle the error
What I want to do:
Authenticate the login using Laravel Password service ( OAuth2 ).
Once authenticated, it would return the access token.
Access Token is passed in the header in a GET API call to receive the
user details.
I am able to #1 and #2 but got stuck at #3.
Here is my code of login.ts
public login() {
this.showLoading();
this.auth.login(this.loginCredentials).subscribe(allowed => {
if (allowed) {
setTimeout(() => {
this.loading.dismiss();
this.nav.setRoot(HelloIonicPage)
});
} else {
this.showError("Access Denied");
}
},
error => {
this.showError(error);
});
}
auth is a service provider, that has login method.
//Function to get access token
public login(credentials) {
if (credentials.email === null || credentials.password === null) {
return Observable.throw("Please insert credentials");
} else {
return Observable.create(observer => {
var link = 'http://localhost/XXX/public/oauth/token';
var vars = {
password: "XXX",
username: "XXXXXX",
grant_type: 'password',
client_id: "XXXXX",
client_secret: 'XXXXXX',
scope: ''
}
this.http.post(link, vars)
.map(res => res.json())
.subscribe(
data => { let user = this.getUserFromAccessToken(data);
console.log(user);
observer.next(user);
},
err => { observer.error(err.json()); }
() => {
console.log('Completed..');
}
);
});
}
}
//Function to get user from the accessToken
private getUserFromAccessToken(oAuthData) {
let headers = new Headers({ 'Content-Type': 'application/json','Accept': 'application/json','Authorization': 'Bearer ' + oAuthData.access_token });
let options = new RequestOptions({ headers: headers });
let link = 'http://localhost/XXXX/public/api/v1/user';
return this.http.get(link, options)
.map(res => res.json())
.subscribe(
data => this.currentUser = data.user,
err => this.error = err
);
}
currentUser and error are defined as properties of the AuthService class.
How should I ensure that an error is thrown either in case the access token is not returned or user is not returned from the access token.