В моем приложении есть групповой чат веб-сокета, который передает сообщение пользователя всем остальным пользователям. Я также хочу создать чат один на один, который будет транслировать сообщения только двум сторонам. Как я могу сообщить веб-сокету о передаче сообщения конкретному пользователю?
Мой контроллер:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Message;
use App\Events\MessageSent;
use Auth;
class ChatsController extends Controller
{
public function index()
{
if (Auth::check() === false) {
return view('login');
}
else
{
return view('chats');
}
}
public function fetchMessages()
{
return Message::with('user')->get();
}
public function sendMessage(Request $request)
{
$message = auth()->user()->messages()->create([
'message' => $request->message
]);
broadcast(new MessageSent($message->load('user')))->toOthers();
return ['status' => 'success'];
}
}
Файл My Vue:
<template>
<div class="row">
<div class="col-8">
<div class="card card-default">
<div class="card-header">Messages</div>
<div class="card-body p-0">
<ul class="list-unstyled" style="height:300px; overflow-y:scroll" v-chat-scroll>
<li class="p-2" v-for="(message, index) in messages" :key="index" >
<div style="background: #009afb; padding: 8px; color: white; border-radius: 15px;">
<img v-if="message.user.image == 'img'" src="https://www.stickpng.com/assets/images/585e4bf3cb11b227491c339a.png" style="width: 35px; height: 35px;">
<img v-else v-bind:src="'../images/' + message.user.image"
style="width: 35px; height: 35px;border-radius: 50%;">
<strong>{{ message.user.name }} {{ message.user.surname }} :</strong>
{{ message.message }}
<p style="color:lightgray;">
{{ message.created_at }}
</p>
</div>
</li>
</ul>
</div>
<input
@keydown="sendTypingEvent"
@keyup.enter="sendMessage"
v-model="newMessage"
type="text"
name="message"
placeholder="Enter your message..."
class="form-control">
</div>
<span class="text-muted" v-if="activeUser" >{{ activeUser.name }} is typing...</span>
</div>
<div class="col-4">
<div class="card card-default">
<div class="card-header">Active Users</div>
<div class="card-body">
<ul>
<li class="py-2" v-for="(user, index) in users" :key="index">
{{ user.name }}
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props:['user'],
data() {
return {
messages: [],
newMessage: '',
users:[],
activeUser: false,
typingTimer: false,
}
},
created() {
this.fetchMessages();
Echo.join('chat')
.here(user => {
this.users = user;
})
.joining(user => {
this.users.push(user);
})
.leaving(user => {
this.users = this.users.filter(u => u.id != user.id);
})
.listen('MessageSent',(event) => {
this.messages.push(event.message);
})
.listenForWhisper('typing', user => {
this.activeUser = user;
if(this.typingTimer) {
clearTimeout(this.typingTimer);
}
this.typingTimer = setTimeout(() => {
this.activeUser = false;
}, 3000);
})
},
methods: {
fetchMessages() {
axios.get('messages').then(response => {
this.messages = response.data;
})
},
sendMessage() {
this.messages.push({
user: this.user,
message: this.newMessage
});
axios.post('messages', {message: this.newMessage});
this.newMessage = '';
},
sendTypingEvent() {
Echo.join('chat')
.whisper('typing', this.user);
}
}
}
</script>
В моей таблице есть поля id, user_id и message.