laravel-websockets
laravel-websockets copied to clipboard
Duplicate websocket messages.
My channel listen query is here. when i chat with more than one person. using websockets it shows duplicate messages on receiver side. these person are in different tab. One user is open in chrome ,second is in chrome incognito mode and third is in firefox. when i send message from second and third to first user duplication in message is shown. I am using laravel 7.x and vue 2.5.17
// join channel query
Echo.join('chat-' + this.user.id + '-' + this.authUser.id)
.listen('MessageSent',(event) => {
this.messages.push(event.message);
})
//send Message
sendMessage() {
this.messages.push({
sender_id: this.authUser.id,
receiver_id: this.user.id,
message: this.newMessage
});
axios.post('/messages/send', {
sender_id: this.authUser.id,
receiver_id: this.user.id,
message: this.newMessage,
});
}
//Controller
message = Message::create([
'sender_id' => $request->input('sender_id'),
'receiver_id' => $request->input('receiver_id'),
'message' => $request->input('message'),
'status' => $status,
]);
broadcast(new MessageSent($message))->toOthers();
@faizan-glowlogix By default Laravel Echo will bind a request interceptor to set the X-Socket-ID header, which is used in the toOthers
method to identify the sending socket. However if you create your own axios instance you have to pass the X-Socket-ID
header to laravel yourself. Which might be your issue.
Please check to see if the X-Socket-ID
header is sent with your POST
message.
// New axios instance, not intercepted by laravel Echo
const instance = axios.create();
// We need to bind the interceptors ourselves to use laravel's ->toOthers() feature
instance.interceptors.request.use((config) => {
const socketId = broadcasting.echo.socketId();
if (socketId) {
config.headers['X-Socket-Id'] = socketId;
}
return config;
});
Have anyone found a reason? I get duplicate messages issue in random order. SocketsId sends correctly.
May be late, but as I found several issues for this withour answers, here is how I solved in my project, which does note use Axios.
The laravel-websockets demo uses Axios. Axios automatically send the header X-Socket-ID in your requests to the API. With it, the API knows whom not to send the event.
The request you must include the header is the one you are sending the payload that will be broadcast. For example, in the demo you would have to include the header in the sendMessage() methods request. To the POST request to /messages would have the header included along with the message.
Done this, the "duplicated" event stopped.
Here is a solution to avoid redeclaring the headers on each API call.
In resources/js/bootstrap.js
import axios from 'axios';
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
axios.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
axios.defaults.withCredentials = true;
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
wsHost: window.location.hostname,
wsPort: 6001,
wssPort: 6001,
forceTLS: false,
disableStats: true,
});
In another file, before/after listening to your events
//Here is the line to add once Echo is joined to a channel
axios.defaults.headers.common['X-Socket-ID'] = Echo.socketId();